├── APEX 18.1 _hidden_ features.pdf ├── README.md ├── app_export └── f114_demo_app_export.sql ├── css └── custom.css ├── examples ├── 01_apex_session.sql ├── 02_apex_app_settings.sql ├── 03_apex_acl.sql ├── 04_apex_export.sql ├── 05_apex_mail.sql ├── Untitled.sql ├── apex_json.sql ├── apex_pkg_app_install.sql ├── apex_string.sql ├── apex_url.sql └── session_cloning.sql ├── img ├── bg1.png ├── bilogweb.png ├── favicon.ico ├── qrcode copy.png ├── qrcode.png └── slika.jpg ├── index.html ├── lib ├── css │ ├── font-awesome.min.css │ └── foundation.min.css ├── foundation.min.js ├── jquery-3.2.1.min.js └── remark-latest.min.js └── presentation.md /APEX 18.1 _hidden_ features.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/APEX 18.1 _hidden_ features.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # APEX 18.1 "hidden" features 2 | 3 | **Marko Gorički** 4 | 5 | [@mgoricki](https://twitter.com/mgoricki) 6 | 7 | mgoricki8@gmail.com 8 | 9 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 10 | 11 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 12 | 13 | --- 14 | 15 | # Where to start? 16 | 17 | - APEX documentation 18 | - [apex.oracle.com/doc182](https://apex.oracle.com/doc182) 19 | - [Release Notes](https://docs.oracle.com/database/apex-18.1/HTMRN/toc.htm#HTMRN-GUID-540B73CB-08A7-4422-B6BF-CC785EC47694) / New Features 20 | - [Changes in this release](https://docs.oracle.com/database/apex-18.2/AEAPI/changes-in-this-release.htm#AEAPI29121) 21 | - Sample Applications 22 | - [#orclapex](https://twitter.com/hashtag/orclapex?src=tren) 23 | - Blogs 24 | - [https://github.com/Dani3lSun/awesome-orclapex](https://github.com/Dani3lSun/awesome-orclapex) 25 | - [apex.oracle.com/shortcuts](https://apex.oracle.com/shortcuts) 26 | 27 | 28 | 29 | --- 30 | 31 | # APEX_SESSION package 32 | 33 | - **set_debug** and **set_trace** available from 5.1 34 | - New in 18.1: 35 | - **create_session** 36 | - **attach** 37 | - **delete_session** 38 | - **detach** 39 | 40 | ## SET_DEBUG 41 | 42 | - sets debug level for all future requests in a session. 43 | - 7 levels ([constants](https://docs.oracle.com/database/apex-18.1/AEAPI/Constants-2.htm#AEAPI29184)): 44 | - 1 - error 45 | - 2 - warning 46 | - 4 - info (default) - same as YES 47 | - 5 - app_enter 48 | - 6 - app_trace 49 | - 8 - engine_enter 50 | - 9 - engine_trace 51 | 52 | ```sql 53 | begin 54 | apex_session.set_debug ( 55 | p_session_id => :APP_SESSION, 56 | p_level => apex_debug.c_log_level_info); 57 | commit; -- DON'T FORGET TO COMMIT!!!! 58 | end; 59 | / 60 | ``` 61 | 62 | ## SET_TRACE 63 | 64 | - sets trace mode in all future requests of a session 65 | 66 | ```sql 67 | begin 68 | apex_session.set_trace ( 69 | p_session_id => :APP_SESSION, 70 | p_level => 'SQL'); 71 | commit; -- DON'T FORGET TO COMMIT!!!! 72 | end; 73 | / 74 | ``` 75 | 76 | ```sql 77 | -- active sessions view 78 | select * 79 | from apex_workspace_sessions 80 | where workspace_name = :WORKSPACE 81 | and user_name = nvl(:USER, user_name); 82 | 83 | -- activity log view 84 | select * 85 | from apex_activity_log 86 | where session_id = :APP_SESSION 87 | order by time_stamp desc; 88 | 89 | -- debug messages view 90 | select * 91 | from apex_debug_messages 92 | where application_id = 114 93 | and session_id = :APP_SESSION; 94 | ``` 95 | 96 | ## Create Session 97 | 98 | - creates a new session for the given application, sets environment and runs **the Initialization PL/SQL Code**. 99 | 100 | ```sql 101 | begin 102 | apex_util.set_workspace(:WORKSPACE_NAME); 103 | apex_session.create_session (p_app_id => 114 104 | , p_page_id => 1 105 | , p_username => 'DEMO'); 106 | end; 107 | / 108 | 109 | -- test variables 110 | select v('APP_ID') as app_id 111 | , v('APP_SESSION') as app_session 112 | , v('APP_USER') as app_user 113 | , apex_page.get_url as get_url 114 | from dual; 115 | ``` 116 | 117 | ## Attach Session 118 | 119 | - sets environment and runs the **Initialization PL/SQL Code** 120 | 121 | ```sql 122 | begin 123 | apex_session.attach(p_app_id => 114 124 | , p_page_id => 3 125 | , p_session_id => :APP_SESSION); 126 | end; 127 | / 128 | ``` 129 | 130 | ## Delete/Detach Session 131 | - calls application's **Cleanup PL/SQL Code** and reset the environment 132 | - apex_session.detach - same as delete session but no parameter 133 | 134 | ```sql 135 | begin 136 | -- p_session_id is optional paarmeter - with null same as detach 137 | apex_session.delete_session (p_session_id => :APP_SESSION); 138 | end; 139 | / 140 | ``` 141 | 142 | ## Links 143 | - [Documentation 18.2](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_SESSION.htm) 144 | - before APEX 18.1 you could use OraOpenSource's [OOS Utils](https://oos-utils.readthedocs.io/en/latest/oos_util_apex/) 145 | 146 | --- 147 | 148 | # Application Settings 149 | 150 | - No more need for simple key-value configuration tables 151 | - Key feature: **On Upgrade Keep Value** 152 | - **API package**: apex_app_settings (get_value/set_value) 153 | - **dictionary view**: apex_application_settings 154 | 155 | ## GET_VALUE 156 | 157 | - gets the application setting value 158 | 159 | ```sql 160 | -- before use, not enough to just set workspace (security_group_id) 161 | exec apex_util.set_workspace(:WORKSPACE); 162 | 163 | -- you need to create or attach to session if used outside APEX session 164 | begin 165 | apex_session.create_session (p_app_id => 114 166 | , p_page_id => 1 167 | , p_username => :USER); 168 | end; 169 | / 170 | 171 | -- get_value example 172 | select name 173 | , apex_app_setting.get_value(p_name => name) as val 174 | , on_upgrade_keep_value 175 | from apex_application_settings 176 | where application_id = 114; 177 | ``` 178 | 179 | ## SET_VALUE 180 | 181 | - changes the application setting value 182 | - also needs APEX session 183 | 184 | ```sql 185 | begin 186 | apex_app_setting.set_value ( 187 | p_name => 'REPORT_SERVER' 188 | ,p_value => '10.11.12.13:9080/jasperserver/'); 189 | commit; -- DON'T FORGET TO COMMIT 190 | end; 191 | / 192 | ``` 193 | 194 | ## Links 195 | - [Documentation 18.2](https://docs.oracle.com/database/apex-18.1/AEAPI/APEX_APP_SETTING.htm) 196 | 197 | --- 198 | 199 | # Application Access Control (ACL) 200 | 201 | - Developers define roles and assign users to roles 202 | - Control access to pages and components with Authorization Schemes 203 | - **dictionary views**: 204 | - apex_appl_acl_roles 205 | - apex_appl_acl_users 206 | - apex_appl_acl_user_roles 207 | - **API package**: apex_acl 208 | - add_user_role 209 | - add_user_roles 210 | - remove_user_role 211 | - remove_all_user_roles 212 | - replace_user_roles 213 | - has_user_role 214 | - has_user_any_roles 215 | - can create administration page through features (also new feature) 216 | - procedures are overloaded - you can use role_id or role_static_id 217 | 218 | ## ADD_USER_ROLE 219 | 220 | - adds role to the user 221 | 222 | ```sql 223 | begin 224 | apex_util.set_workspace(:WORKSPACE); 225 | apex_acl.add_user_role ( 226 | -- assigns a role to a user 227 | p_application_id => 114 -- default wwv_flow_security.g_flow_id 228 | ,p_user_name => :USER 229 | ,p_role_static_id => 'READER' -- other proc with p_role_id 230 | ); 231 | commit; 232 | end; 233 | / 234 | ``` 235 | 236 | ## REMOVE_USER_ROLE 237 | 238 | - removes an assigned role from a user 239 | 240 | ```sql 241 | begin 242 | apex_util.set_workspace(:WORKSPACE); 243 | apex_acl.remove_user_role ( 244 | p_application_id => 114, -- default wwv_flow_security.g_flow_id, 245 | p_user_name => :USER, 246 | p_role_static_id => 'READER' 247 | ); 248 | commit; 249 | end; 250 | / 251 | ``` 252 | 253 | ## ADD_USER_ROLES 254 | 255 | - adds multiple roles to the user 256 | 257 | ```sql 258 | begin 259 | apex_util.set_workspace(:WORKSPACE); 260 | apex_acl.add_user_roles( 261 | -- assigns an array of roles to a user 262 | p_application_id => 114, 263 | p_user_name => :USER, 264 | p_role_static_ids => apex_t_varchar2('READER', 'ADMINISTRATOR') 265 | ); 266 | commit; 267 | end; 268 | / 269 | ``` 270 | 271 | 272 | ## REPLACE_USER_ROLES 273 | 274 | - replaces any existing assigned roles to new array of roles 275 | 276 | ```sql 277 | begin 278 | apex_util.set_workspace(:WORKSPACE); 279 | apex_acl.replace_user_roles ( 280 | p_application_id => 114, -- default wwv_flow_security.g_flow_id, 281 | p_user_name => :USER, 282 | p_role_static_ids => apex_string.split('ADMINISTRATOR:CONTRIBUTOR', ':')); 283 | end; 284 | / 285 | ``` 286 | 287 | ## REMOVE_ALL_USER_ROLES 288 | 289 | - removes all assigned roles from a user 290 | 291 | ```sql 292 | begin 293 | apex_util.set_workspace(:WORKSPACE); 294 | apex_acl.remove_all_user_roles( 295 | p_application_id => '114', --default wwv_flow_security.g_flow_id, 296 | p_user_name => :USER); 297 | commit; 298 | end; 299 | / 300 | ``` 301 | 302 | ## USER_HAS_ROLE 303 | 304 | - checks if user has specific role 305 | 306 | ```sql 307 | begin 308 | apex_util.set_workspace(:WORKSPACE); 309 | if apex_acl.has_user_role(p_application_id => :APP_ID 310 | , p_user_name => :USER 311 | , p_role_static_id => 'READER') then 312 | dbms_output.put_line('OK'); 313 | else 314 | dbms_output.put_line('NOT OK'); 315 | end if; 316 | end; 317 | / 318 | ``` 319 | 320 | ## HAS_USER_ANY_ROLES 321 | 322 | - checks if user has any role 323 | 324 | ```sql 325 | begin 326 | apex_util.set_workspace('SIOUG2018'); 327 | if apex_acl.has_user_any_roles (p_application_id => :APP_ID 328 | , p_user_name => :USER) then 329 | dbms_output.put_line('OK'); 330 | else 331 | dbms_output.put_line('NOT OK'); 332 | end if; 333 | end; 334 | / 335 | ``` 336 | 337 | ## Links 338 | - [Documentation 18.2](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_ACL.htm) 339 | 340 | --- 341 | 342 | # APEX Export 343 | 344 | - can be done in APEX Builder, with Java Utility or SQLcl 345 | - can export the app definitions, files, feedback, and workspaces to text files as CLOBs 346 | - available from APEX 5.1 (but not documented) 347 | - uses utility types APEX_T_EXPORT_FILE and APEX_T_EXPORT_FILES 348 | 349 | ```sql 350 | -- APEX_T_EXPORT_FILE 351 | create or replace type wwv_flow_t_export_file force is object ( 352 | name varchar2(255), 353 | contents clob 354 | ) 355 | 356 | -- APEX_T_EXPORT_FILES 357 | create or replace type wwv_flow_t_export_files is table of wwv_flow_t_export_file 358 | ``` 359 | 360 | ## GET_APPLICATION 361 | 362 | - Definition: 363 | 364 | ```sql 365 | function get_application ( 366 | p_application_id in number, 367 | p_split in boolean default false, 368 | p_with_date in boolean default false, 369 | p_with_ir_public_reports in boolean default false, 370 | p_with_ir_private_reports in boolean default false, 371 | p_with_ir_notifications in boolean default false, 372 | p_with_translations in boolean default false, 373 | p_with_pkg_app_mapping in boolean default false, 374 | p_with_original_ids in boolean default false, 375 | p_with_no_subscriptions in boolean default false, 376 | p_with_comments in boolean default false, 377 | p_with_supporting_objects in varchar2 default null, 378 | p_with_acl_assignments in boolean default false -- you can export ACL assignments 379 | ) 380 | return wwv_flow_t_export_files; 381 | ``` 382 | 383 | - Example: 384 | 385 | ```sql 386 | -- get application 387 | declare 388 | v_apex_export_files apex_t_export_files; 389 | begin 390 | v_apex_export_files := apex_export.get_application(:APP_ID 391 | -- , p_with_acl_assignments => true 392 | ); 393 | dbms_output.put_line(v_apex_export_files(1).name); 394 | dbms_output.put_line(length(v_apex_export_files(1).contents)); 395 | end; 396 | / 397 | ``` 398 | 399 | 400 | ## Split Application 401 | ```sql 402 | declare 403 | v_apex_export_files apex_t_export_files; -- table of apex_t_export_file 404 | v_app_exp_file blob; 405 | begin 406 | v_apex_export_files := apex_export.get_application(:APP_ID 407 | , p_split => true 408 | ); 409 | for i in v_apex_export_files.first..v_apex_export_files.last 410 | loop 411 | dbms_output.put_line(v_apex_export_files(i).name); 412 | end loop; 413 | end; 414 | / 415 | ``` 416 | 417 | ## Other Functions 418 | - **get_feedback** - exports user feedback 419 | 420 | ```sql 421 | function get_feedback ( 422 | p_workspace_id in number, 423 | p_with_date in boolean default false, 424 | p_since in date default null, 425 | p_deployment_system in varchar2 default null ) 426 | return wwv_flow_t_export_files; 427 | ``` 428 | 429 | - **get_workspace** - exports the given workspace's definition and users 430 | 431 | ```sql 432 | function get_workspace ( 433 | p_workspace_id in number, 434 | p_with_date in boolean default false, 435 | p_with_team_development in boolean default false, 436 | p_with_misc in boolean default false -- include data from SQL Workshop, mail logs, etc. in the export. 437 | ) 438 | return wwv_flow_t_export_files; 439 | ``` 440 | 441 | - **get_workspace_files** - exports the given workspace's static files 442 | 443 | ```sql 444 | function get_workspace_files ( 445 | p_workspace_id in number, 446 | p_with_date in boolean default false ) 447 | return wwv_flow_t_export_files; 448 | ``` 449 | 450 | ## Links 451 | 452 | - [Demo](http://localhost:8080/ords/f?p=114:16) 453 | - [Documentation](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_EXPORT.htm) 454 | 455 | 456 | 457 | 458 | --- 459 | 460 | # APEX Mail Templates 461 | 462 | - new feature in APEX 18.1 (Shared Components > Email Templates) 463 | - API package: apex_mail - (2 new procedures and one function): 464 | - send (procedure and function) 465 | - prepare_template procedure 466 | 467 | - **dictionary views** 468 | - apex_mail_log 469 | - apex_mail_queue 470 | - apex_mail_attachments 471 | 472 | ## SEND procedure 473 | 474 | - new template_static_id parameter 475 | 476 | ```sql 477 | declare 478 | v_placeholders clob; 479 | begin 480 | apex_util.set_workspace('SIOUG2018'); 481 | apex_json.initialize_clob_output; 482 | apex_json.open_object; 483 | 484 | apex_json.write('EVENT_NAME' , 'MakeIT 2018'); 485 | apex_json.write('EVENT_DATE' , '15.10.2018.'); 486 | apex_json.write('EVENT_LINK' , 'www.makeIT.si'); 487 | apex_json.write('DURATION' , '2 days'); 488 | apex_json.write('INVITEE' , 'Marko Gorički'); 489 | apex_json.write('ORGANIZER' , 'SIOUG'); 490 | apex_json.write('LOCATION' , 'Portorož'); 491 | apex_json.write('MY_APPLICATION_LINK', 'www.makeIT.si'); 492 | apex_json.write('NOTES' , 'n/a'); 493 | apex_json.write('URL_LINK' , 'n/a'); 494 | apex_json.write('URL_NAME' , 'n/a'); 495 | apex_json.write('START_TIME' , '15.10.2018.'); 496 | 497 | apex_json.close_object; 498 | v_placeholders := apex_json.get_clob_output; 499 | apex_json.free_output; 500 | 501 | apex_mail.send ( 502 | p_template_static_id => 'EVENT' 503 | , p_placeholders => v_placeholders 504 | , p_to => 'marko.goricki@bilog.hr' 505 | ); 506 | apex_mail.push_queue; 507 | end; 508 | / 509 | ``` 510 | 511 | - [Demo on apex.oracle.com](https://apex.oracle.com/pls/apex/f?p=93889:2) 512 | 513 | 514 | ## SEND function 515 | 516 | - same as send functions but returns mail_id (used for adding atachements) 517 | 518 | ## PREPARE_TEMPLATE procedure 519 | 520 | - returns a formatted mail based on an e-mail template where the placeholders specified as json string are substituted 521 | 522 | ```sql 523 | procedure prepare_template ( 524 | p_static_id in varchar2, 525 | p_placeholders in clob, 526 | p_application_id in number default wwv_flow_security.g_flow_id, 527 | p_subject out varchar2, 528 | p_html out clob, 529 | p_text out clob); 530 | ``` 531 | 532 | ## Links 533 | 534 | - [Documentation](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_MAIL.htm) 535 | 536 | 537 | --- 538 | 539 | 540 | # Dynamically Set Parsing Schema 541 | - change the parsing user for the current page view to another workspace schema 542 | - can only call it from Initialization PL/SQL Code 543 | 544 | ```sql 545 | begin 546 | apex_util.set_parsing_schema_for_request ( 547 | p_schema => :SCHEMA 548 | ); 549 | end; 550 | / 551 | ``` 552 | 553 | ## Example 554 | 555 | ```sql 556 | if :APP_PAGE_ID between 1 and 100 then 557 | apex_util.set_parsing_schema_for_request ( 558 | p_schema => :G_PARSING_SCHEMA ); 559 | end if; 560 | ``` 561 | 562 | ## Links 563 | 564 | - [Demo](http://localhost:8080/ords/f?p=114:14) 565 | - [Documentation](https://docs.oracle.com/database/apex-18.1/AEAPI/SET_PARSING_SCHEMA_FOR_REQUEST-Procedure.htm) 566 | 567 | ??? 568 | 569 | Multi-tenancy is an architecture in which a single instance of a software application serves multiple customers. Each customer is called a tenant. Tenants may be given the ability to customize some parts of the application, such as color of the user interface (UI) or business rules, but they cannot customize the application's code. 570 | 571 | --- 572 | 573 | # Session Cloning 574 | 575 | - before using it, you have to enable it with **sys** user or **apex_administrator_role** user: 576 | 577 | ```sql 578 | grant apex_administrator_role to sioug2018; 579 | ``` 580 | 581 | ```sql 582 | begin 583 | apex_instance_admin.set_parameter( 584 | p_parameter => 'CLONE_SESSION_ENABLED', 585 | p_value => 'Y'); 586 | end; 587 | / 588 | ``` 589 | - to use it add request to the link APEX_CLONE_SESSION: 590 | - .../f?p=114:10:15609087012832:**APEX_CLONE_SESSION**::: 591 | 592 | ## Links 593 | 594 | - [Demo](http://localhost:8080/ords/f?p=114:14:0) 595 | 596 | --- 597 | 598 | # APEX URL 599 | 600 | - bad way - DB needs to hard parse query for each SQL statement 601 | 602 | ```sql 603 | select 'f?p=&APP_ID.:17:&APP_SESSION.:::P17_ITEM:1' as my_url 604 | , apex_util.prepare_url('f?p=&APP_ID.:17:&APP_SESSION.:::P17_ITEM:1') as my_url_with_cs 605 | from some_table; 606 | ``` 607 | 608 | - better - not so readable and developer can easily make errors 609 | ```sql 610 | select 'f?p=&APP_ID.:17:'||:APP_SESSION||':::P17_ITEM:1' as my_url 611 | , apex_util.prepare_url('f?p=&APP_ID.:17:'||:APP_SESSION||':::P17_ITEM:1') as my_url_with_cs 612 | from some_table; 613 | ``` 614 | 615 | - good way - readable, creates checksum if needed 616 | 617 | ```sql 618 | select apex_page.get_url(p_page => '17' 619 | , p_items => 'P17_ITEM' 620 | , p_values => '1') as my_url 621 | from some_table; 622 | ``` 623 | 624 | - other parameters 625 | 626 | ```sql 627 | -- PARAMETERS 628 | -- * p_application application id or alias. defaults to the current application. 629 | -- * p_page page id or alias. defaults to the current page. 630 | -- * p_session session id. defaults to the current session id. 631 | -- * p_request URL request parameter. 632 | -- * p_debug URL debug parameter. defaults to the current debug mode. 633 | -- * p_clear_cache URL clear cache parameter. 634 | -- * p_items comma delimited list of item names to set session state. 635 | -- * p_values comma separated list of item values to set session state. 636 | -- * p_printer_friendly URL printer friendly parameter. defaults tot he current request's printer friendly mode. 637 | -- * p_trace SQL trace parameter. 638 | ``` 639 | 640 | --- 641 | 642 | # Strings (APEX_STRING) 643 | 644 | - new in 5.1 645 | - utilities for varchar2, clob, apex_t_varchar2, and apex_t_number types 646 | 647 | ## JOIN and SPLIT 648 | - apex_util.string_to_table and apex_util.table_to_string are [DEPRECATED](https://docs.oracle.com/database/apex-18.2/AEAPI/STRING_TO_TABLE-Function.htm) 649 | - **SPLIT**: 650 | 651 | ```sql 652 | -- apex_util.string_to_table DEPRECATED 653 | declare 654 | v_arr apex_application_global.vc_arr2; 655 | begin 656 | v_arr := apex_util.string_to_table('One:Two:Three'); 657 | for i in 1..v_arr.count 658 | loop 659 | dbms_output.put_line(v_arr(i)); 660 | end loop; 661 | end; 662 | / 663 | ``` 664 | 665 | ```sql 666 | -- apex_string 667 | select * from apex_string.split('One:Two:Three', ':'); 668 | -- doesn't work: select * from APEX_UTIL.STRING_TO_TABLE('One:Two:Three'); 669 | ``` 670 | 671 | - **JOIN**: 672 | 673 | ```sql 674 | -- apex_util.table_to_string DEPRECATED 675 | declare 676 | v_arr apex_application_global.vc_arr2; 677 | begin 678 | select ename 679 | bulk collect into v_arr 680 | from emp; 681 | 682 | dbms_output.put_line(apex_util.table_to_string(v_arr)); 683 | end; 684 | / 685 | ``` 686 | 687 | ```sql 688 | declare 689 | v_arr apex_t_varchar2; 690 | begin 691 | select ename 692 | bulk collect into v_arr 693 | from emp; 694 | 695 | dbms_output.put_line(apex_string.join(v_arr, ':')); 696 | end; 697 | / 698 | ``` 699 | ## Key value tables - PUT/GET/DELETE 700 | 701 | ```sql 702 | declare 703 | v_table apex_t_varchar2; 704 | begin 705 | -- populate table 706 | for i in (select ename, sal from emp) 707 | loop 708 | -- put element into table 709 | apex_string.plist_put(v_table, i.ename, i.sal); 710 | end loop; 711 | 712 | 713 | -- get element from table 714 | dbms_output.put_line( 715 | apex_string.plist_get(v_table, 'JONES') 716 | ); 717 | end; 718 | / 719 | ``` 720 | 721 | ## FORMAT 722 | - returns a formatted string, with substitutions applied. 723 | 724 | ```sql 725 | select apex_string.format('Hi %s! Hope to see you at the party. It starts at %s.' 726 | , 'Marko' 727 | , '18:30') m 728 | from dual; 729 | ``` 730 | 731 | ```sql 732 | -- with %0 %1 - starts with zero 733 | select apex_string.format('Hi %1! Hope to see you at the party. It starts at %0.' 734 | , '18:30' 735 | , 'Marko' 736 | , p_max_length => 10) m 737 | from dual; 738 | ``` 739 | ## SHUFFLE 740 | - Returns the input table values, re-ordered.. 741 | 742 | ```sql 743 | select * 744 | from apex_string.shuffle(apex_t_varchar2('One','Two','Three')); 745 | ``` 746 | 747 | ## Parsing CSV data 748 | - output CSV from a table (in SQL Developer or SQLcl): 749 | 750 | ```sql 751 | select /*csv*/ * from emp; 752 | ``` 753 | - parse CSV: 754 | 755 | ```sql 756 | with 757 | function get_column (p_row varchar2 758 | , p_col_num number) 759 | return varchar2 760 | is 761 | v_row apex_t_varchar2; 762 | begin 763 | v_row := apex_string.split(p_row, ','); 764 | if v_row.exists(p_col_num) then 765 | return v_row(p_col_num); 766 | end if; 767 | return null; 768 | end; 769 | select get_column(column_value, 1) as col1 770 | , get_column(column_value, 2) as col2 771 | , get_column(column_value, 3) as col3 772 | , get_column(column_value, 4) as col4 773 | , get_column(column_value, 5) as col5 774 | , get_column(column_value, 6) as col6 775 | , get_column(column_value, 7) as col7 776 | , get_column(column_value, 8) as col8 777 | from apex_string.split(:CSVDATA, chr(10)); -- chr(10) or chr(10)||chr(13) 778 | ``` 779 | 780 | ## APEX_UTIL.GET_HASH 781 | - computes a hash value for all given values 782 | - can be used to implement lost update detection for data records 783 | - p_salted - if true (the default), salt hash with internal session info 784 | 785 | ```sql 786 | select apex_util.get_hash( 787 | p_values => apex_t_varchar2 (empno, sal, comm), 788 | p_salted => true 789 | ) x 790 | from emp; 791 | ``` 792 | 793 | ## Links 794 | 795 | - [Documentation](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_STRING.htm) 796 | 797 | 798 | --- 799 | 800 | # Other APIs 801 | - New in 18.1 802 | - **APEX_PKG_APP_INSTALL** - utilities you can use to manage Packaged Applications. 803 | - **APEX_JWT** - utilities for JSON Web Tokens (JWT) 804 | - **APEX_EXEC** - contains procedures and functions to execute queries or procedural calls on local and remote data sources as well as web source modules 805 | - **APEX_CREDENTIAL** (new in 18.2) - package to change stored credentials either persistently or for the current APEX session only 806 | 807 | - Useful from previous versions: 808 | - **APEX_ZIP** - compress and to uncompress files and store them in a ZIP file 809 | - **APEX_JSON** - utilities to parse and generate JSON 810 | - **APEX_WEB_SERVICE** - utilities to invoke WS 811 | 812 | - Non APEX APIs 813 | - https://github.com/mortenbra/alexandria-plsql-utils 814 | - OraOpenSource https://oos-utils.readthedocs.io/en/latest/README/ 815 | -------------------------------------------------------------------------------- /css/custom.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); 2 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); 3 | @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic); 4 | @import url('http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700,900&subset=latin,latin-ext'); 5 | 6 | .red{color:red} 7 | .green{color:green} 8 | 9 | html,body{ 10 | font:normal 15px 'Open Sans', sans-serif; 11 | font-weight:300; 12 | } 13 | body{ 14 | background-color:#efefef; 15 | } 16 | 17 | .remark-container{ 18 | background-color:#f3f3f3; 19 | } 20 | 21 | .remark-slide-scaler{ 22 | box-shadow:none !important; 23 | } 24 | 25 | h1{ 26 | background-color:#8ddc62; 27 | color: white; 28 | padding: 20px 30px; 29 | border-bottom: 4px solid #efefef; 30 | background-image: url("../img/bg1.png"); 31 | background-color: rgb(141, 220, 98); 32 | background-position: 50% 270px; 33 | font-weight: 300; 34 | } 35 | 36 | h4{ 37 | margin:40px 0 0; 38 | } 39 | .remark-slide-content{ 40 | padding-top:90px !important; 41 | } 42 | .remark-slide-content h1{ 43 | margin-top:0 !important; 44 | position: fixed; 45 | top: 0; 46 | left:0; 47 | display:block; 48 | width: 100%; 49 | } 50 | .remark-slide-content.center h1{ 51 | padding: 40px; 52 | position: initial; 53 | border-top: 4px solid #efefef; 54 | } 55 | .remark-slide-content h2{ 56 | font-size: 25px; 57 | } 58 | .remark-slide-content ul, .remark-slide-content ol{ 59 | padding:0 55px; 60 | } 61 | .remark-slide-content h4, .remark-slide-content h2{ 62 | padding:10px 33px; 63 | background-color: #8ddc62; 64 | color: #fff; 65 | } 66 | 67 | .remark-slide-content li{ 68 | padding: 8px 0px; 69 | } 70 | 71 | .remark-slide-content pre{ 72 | padding:0 55px; 73 | } 74 | .remark-slide-content{ 75 | padding:0; 76 | font-size:30px; 77 | } 78 | 79 | .remark-slide-scaler{ 80 | overflow:auto; 81 | top: 0px !important; 82 | left: 0px !important; 83 | } 84 | .remark-slide-number{ 85 | font-size:18px; 86 | } 87 | 88 | .myPhoto img{ 89 | position: absolute; 90 | left:auto; 91 | right: 20px; 92 | top: 150px; 93 | width:220px; 94 | border:2px solid #ccc; 95 | padding:2px; 96 | } 97 | .bilogWeb { 98 | display:block; 99 | text-align: center; 100 | } 101 | .bilogWeb img{ 102 | width:80%; 103 | margin: 0 auto; 104 | } 105 | -------------------------------------------------------------------------------- /examples/01_apex_session.sql: -------------------------------------------------------------------------------- 1 | select * From apex_debug_messages; 2 | 3 | -- view active sessions 4 | select * 5 | from apex_workspace_sessions 6 | where workspace_name = 'SIOUG2018' 7 | and trunc(session_created) = trunc(Sysdate) 8 | and user_name = 'DEMO' 9 | order by session_created desc; 10 | 11 | ------------------------------------------------------------------------------------------------ 12 | -- 1) SET_DEBUG 13 | begin 14 | apex_session.set_debug ( 15 | p_session_id => :APP_SESSION, 16 | p_level => apex_debug.c_log_level_info); 17 | commit; -- DON'T FORGET TO COMMIT!!!! 18 | end; 19 | / 20 | 21 | select * from apex_debug_messages where session_id = 4668249412165 order by id desc; 22 | 23 | ------------------------------------------------------------------------------------------------ 24 | -- 2) CREATE_SESSION 25 | begin 26 | apex_util.set_workspace(:WORKSPACE_NAME); 27 | apex_session.create_session (p_app_id => 114 28 | , p_page_id => 1 29 | , p_username => :USER); 30 | commit; 31 | end; 32 | / 33 | 34 | -- Example 1: view variables 35 | select v('APP_ID') as app_id 36 | , v('APP_SESSION') as app_session 37 | , v('APP_USER') as app_user 38 | , apex_mail.get_instance_url||apex_page.get_url as get_url 39 | from dual; 40 | 41 | -- Example 2: create collections 42 | select * From apex_collections; 43 | exec apex_collection.create_collection_from_query ('EMP', 'select * from emp', p_truncate_if_exists => 'YES'); 44 | select * From apex_collections; 45 | 46 | begin 47 | apex_collection.update_member_attribute('EMP' 48 | , p_seq => 1 49 | , p_attr_number => 2 50 | , p_attr_VALUE => 'KING THE GREATEST'); 51 | commit; 52 | end; 53 | / 54 | 55 | -- Example 3: use v function 56 | select v('P1_DEPTNO') from dual; 57 | 58 | create or replace view v_emp as 59 | select * 60 | from emp 61 | where deptno = (select v('P1_DEPTNO') from dual); 62 | 63 | select * from v_emp; 64 | call apex_util.set_session_state('P1_DEPTNO', '20'); -- you don't even need to create item 65 | 66 | -- Example 4: Create protected URL outside APEX session 67 | select apex_page.get_url(p_items => 'P1_DEPTNO', p_values => '10') url from dual; 68 | 69 | 70 | ------------------------------------------------------------------------------------------------ 71 | -- 3) ATTACH 72 | begin 73 | -- no need to set workspace id 74 | apex_session.attach(p_app_id => 114 75 | , p_page_id => 3 76 | , p_session_id => :APP_SESSION); 77 | commit; 78 | end; 79 | / 80 | 81 | -- you need to reattach to view values after change because it's cached 82 | select item_name 83 | , apex_util.get_session_state(item_name) as val 84 | , v(item_name) as val2 85 | from apex_application_page_items 86 | where application_id = 114 and page_id = 3; 87 | 88 | -- you can set APEX item 89 | exec apex_util.set_session_state('P3_ITEM', 'Marko'); 90 | 91 | -- you can alse see collections 92 | select * From apex_collections; 93 | 94 | begin 95 | apex_collection.update_member_attribute('EMP', p_seq => 1, p_attr_number => 2, p_attr_VALUE => 'KING THE GREATEST'); 96 | commit; 97 | end; 98 | / 99 | 100 | 101 | 102 | ------------------------------------------------------------------------------------------------ 103 | -- 4) DELETE 104 | begin 105 | apex_util.set_workspace(:WORKSPACE_NAME); 106 | apex_session.create_session (p_app_id => 114 107 | , p_page_id => 1 108 | , p_username => :USER); 109 | commit; 110 | end; 111 | / 112 | select * from apex_workspace_sessions where workspace_name = 'SIOUG2018' and apex_session_id = v('APP_SESSION'); 113 | select v('APP_SESSION') sess_id from dual; 114 | begin 115 | -- p_session_id is optional parameter - with null same as detach 116 | apex_util.set_workspace('SIOUG2018'); 117 | apex_session.delete_session (p_session_id => v('APP_SESSION')); 118 | commit; 119 | end; 120 | / 121 | 122 | select v('APP_ID') as app_id 123 | , v('APP_SESSION') as app_session 124 | , v('APP_USER') as app_user 125 | -- , apex_mail.get_instance_url||apex_page.get_url as get_url 126 | from dual; 127 | 128 | select * from apex_workspace_sessions where workspace_name = 'SIOUG2018' and apex_session_id = :APP_SESSION; 129 | 130 | ------------------------------------------------------------------------------------------------ 131 | -- 5) DETACH 132 | exec apex_session.detach; 133 | 134 | -------------------------------------------------------------------------------- /examples/02_apex_app_settings.sql: -------------------------------------------------------------------------------- 1 | -- set workspace - not enough 2 | exec apex_util.set_workspace('SIOUG2018'); 3 | 4 | -- create session - needed if used outside APEX session 5 | begin 6 | apex_util.set_workspace('SIOUG2018'); 7 | apex_session.create_session(114,1,'DEMO'); 8 | commit; 9 | end; 10 | / 11 | 12 | 13 | ---------------------------- 14 | -- GET_VALUE 15 | -- %usage: gets the application setting value in the current application 16 | select name, apex_app_setting.get_value(p_name => name) as val 17 | from apex_application_settings 18 | where application_id = 114; 19 | 20 | 21 | 22 | ---------------------------- 23 | -- SET_VALUE 24 | -- %usage: changes the application setting value in the current application 25 | begin 26 | apex_util.set_workspace('SIOUG2018'); 27 | apex_session.create_session (114, 1, 'DEMO'); 28 | apex_app_setting.set_value ( 29 | p_name => 'PARAM' 30 | ,p_value => 'localhost/jasperserver'); 31 | commit; 32 | end; 33 | / 34 | -------------------------------------------------------------------------------- /examples/03_apex_acl.sql: -------------------------------------------------------------------------------- 1 | --dictionary views: 2 | -- all roles 3 | select role_name, role_static_id, role_desc 4 | from apex_appl_acl_roles 5 | where workspace = 'SIOUG2018' 6 | and application_id = 114; 7 | 8 | -- users 9 | select user_name, role_ids, role_names 10 | from apex_appl_acl_users x 11 | where workspace = 'SIOUG2018' 12 | and application_id = 114; 13 | 14 | -- users and roles 15 | select user_name, role_id, role_name, role_static_id, role_desc 16 | from apex_appl_acl_user_roles 17 | where workspace = 'SIOUG2018' 18 | and application_id = 114 19 | order by 1; 20 | 21 | ----------------------------- 22 | -- ADD_USER_ROLE 23 | -- adds user role to the user 24 | begin 25 | apex_util.set_workspace('SIOUG2018'); 26 | apex_acl.add_user_role ( 27 | p_application_id => 114 -- default wwv_flow_security.g_flow_id 28 | ,p_user_name => 'DEMO' 29 | ,p_role_static_id => 'CONTRIBUTOR' 30 | ); 31 | commit; 32 | end; 33 | / 34 | 35 | ----------------------------- 36 | -- REMOVE_USER_ROLE 37 | -- removes user role from the user 38 | begin 39 | apex_util.set_workspace('SIOUG2018'); 40 | apex_acl.remove_user_role ( 41 | -- removes an assigned role from a user 42 | p_application_id => 114, -- default wwv_flow_security.g_flow_id, 43 | p_user_name => 'DEMO', 44 | p_role_static_id => 'CONTRIBUTOR'); 45 | commit; 46 | end; 47 | / 48 | 49 | ----------------------------- 50 | -- ADD_USER_ROLES 51 | -- assigns an array of roles to a user 52 | begin 53 | apex_util.set_workspace('SIOUG2018'); 54 | apex_acl.add_user_roles( 55 | p_application_id => 114, 56 | p_user_name => 'DEMO', 57 | p_role_static_ids => apex_t_varchar2('READER', 'ADMINISTRATOR') 58 | ); 59 | commit; 60 | end; 61 | / 62 | 63 | ----------------------------- 64 | -- REPLACE_USER_ROLES 65 | -- replaces any existing assigned roles to new array of roles 66 | begin 67 | apex_util.set_workspace('SIOUG2018'); 68 | apex_acl.replace_user_roles ( 69 | p_application_id => 114, -- default wwv_flow_security.g_flow_id, 70 | p_user_name => 'DEMO', 71 | p_role_static_ids => apex_string.split('ADMINISTRATOR:CONTRIBUTOR', ':') 72 | ); 73 | end; 74 | / 75 | 76 | 77 | ----------------------------- 78 | -- REMOVE_ALL_USER_ROLES 79 | -- add_user_roles (array of roles), replace_user_roles (remove and add array of roles) 80 | begin 81 | -- NOTE: no error if workspace is not set 82 | apex_util.set_workspace('SIOUG2018'); 83 | apex_acl.remove_all_user_roles( 84 | -- removes all assigned roles from a user 85 | p_application_id => '114', --default wwv_flow_security.g_flow_id, 86 | p_user_name => 'DEMO'); 87 | commit; 88 | end; 89 | / 90 | 91 | 92 | ----------------------------- 93 | -- USER_HAS_ROLE 94 | -- %usage: checks if user has role 95 | begin 96 | apex_util.set_workspace('SIOUG2018'); 97 | if apex_acl.has_user_role(p_application_id => 114 98 | , p_user_name => 'DEMO' 99 | , p_role_static_id => 'READER') then 100 | dbms_output.put_line('OK'); 101 | else 102 | dbms_output.put_line('NOT OK'); 103 | end if; 104 | end; 105 | / 106 | 107 | ----------------------------- 108 | -- HAS_USER_ANY_ROLES 109 | -- %usage: checks if user has any role 110 | begin 111 | apex_util.set_workspace('SIOUG2018'); 112 | if apex_acl.has_user_any_roles (p_application_id => 114 113 | , p_user_name => 'TEST2') then 114 | dbms_output.put_line('OK'); 115 | else 116 | dbms_output.put_line('NOT OK'); 117 | end if; 118 | end; 119 | / -------------------------------------------------------------------------------- /examples/04_apex_export.sql: -------------------------------------------------------------------------------- 1 | set serveroutput on; 2 | 3 | /* 4 | drop table my_clob; 5 | create table my_clob ( 6 | id number generated by default on null as identity, 7 | name varchar2(1000), 8 | clob_content clob 9 | ); 10 | 11 | create or replace procedure p_log_clob(p_name varchar2, p_clob clob) 12 | is 13 | pragma autonomous_transaction; 14 | begin 15 | delete from my_clob; 16 | insert into my_clob (name, clob_content) values (p_name, p_clob); 17 | commit; 18 | end; 19 | / 20 | truncate table my_clob; 21 | */ 22 | 23 | -- APEX_T_EXPORT_FILE 24 | /* 25 | create or replace type wwv_flow_t_export_file force is object ( 26 | name varchar2(255), 27 | contents clob 28 | ) 29 | 30 | -- APEX_T_EXPORT_FILES 31 | create or replace type wwv_flow_t_export_files is table of wwv_flow_t_export_file 32 | */ 33 | 34 | ----------------------------- 35 | -- GET_APPLICATION 36 | -- gets application as CLOB 37 | declare 38 | v_apex_export_files apex_t_export_files; -- table of apex_t_export_file 39 | begin 40 | v_apex_export_files := apex_export.get_application(p_application_id => 114 41 | , p_with_acl_assignments => true 42 | ); 43 | dbms_output.put_line(v_apex_export_files(1).name); 44 | dbms_output.put_line(length(v_apex_export_files(1).contents)); 45 | 46 | p_log_clob(v_apex_export_files(1).name, v_apex_export_files(1).contents); 47 | end; 48 | / 49 | 50 | select * from my_clob; 51 | 52 | ----------------------------- 53 | -- GET_APPLICATION with split 54 | -- splits application in CLOBs 55 | declare 56 | v_apex_export_files apex_t_export_files; 57 | begin 58 | v_apex_export_files := apex_export.get_application(114, p_split => true); 59 | for i in v_apex_export_files.first..v_apex_export_files.last 60 | loop 61 | dbms_output.put_line(v_apex_export_files(i).name||' - '||length(v_apex_export_files(i).contents)); 62 | end loop; 63 | end; 64 | / 65 | -- get feedback 66 | /* 67 | function get_feedback ( 68 | p_workspace_id in number, 69 | p_with_date in boolean default false, 70 | p_since in date default null, 71 | p_deployment_system in varchar2 default null ) 72 | return wwv_flow_t_export_files; 73 | */ 74 | declare 75 | v_apex_export_files apex_t_export_files; 76 | begin 77 | v_apex_export_files := apex_export.get_feedback( 78 | p_workspace_id => apex_util.find_security_group_id ('SIOUG2018'), 79 | p_since => date '2018-01-01' 80 | ); 81 | 82 | for i in v_apex_export_files.first..v_apex_export_files.last 83 | loop 84 | dbms_output.put_line(v_apex_export_files(i).name||' - '||length(v_apex_export_files(i).contents)); 85 | end loop; 86 | end; 87 | / 88 | 89 | -- get_workspace 90 | /* 91 | function get_workspace ( 92 | p_workspace_id in number, 93 | p_with_date in boolean default false, 94 | p_with_team_development in boolean default false, 95 | p_with_misc in boolean default false ) 96 | return wwv_flow_t_export_files; 97 | */ 98 | declare 99 | v_apex_export_files apex_t_export_files; 100 | begin 101 | v_apex_export_files := apex_export.get_workspace( 102 | p_workspace_id => apex_util.find_security_group_id ('SIOUG2018') 103 | ); 104 | 105 | for i in v_apex_export_files.first..v_apex_export_files.last 106 | loop 107 | dbms_output.put_line(v_apex_export_files(i).name||' - '||length(v_apex_export_files(i).contents)); 108 | end loop; 109 | end; 110 | / 111 | 112 | -- get_workspace_files 113 | /* 114 | function get_workspace_files ( 115 | p_workspace_id in number, 116 | p_with_date in boolean default false ) 117 | return wwv_flow_t_export_files; 118 | */ 119 | declare 120 | v_apex_export_files apex_t_export_files; 121 | begin 122 | v_apex_export_files := apex_export.get_workspace_files( 123 | p_workspace_id => apex_util.find_security_group_id ('SIOUG2018') 124 | ); 125 | 126 | for i in v_apex_export_files.first..v_apex_export_files.last 127 | loop 128 | dbms_output.put_line(v_apex_export_files(i).name||' - '||length(v_apex_export_files(i).contents)); 129 | end loop; 130 | end; 131 | / 132 | -------------------------------------------------------------------------------- /examples/05_apex_mail.sql: -------------------------------------------------------------------------------- 1 | -- dictionary 2 | select * from apex_mail_log order by mail_id desc; 3 | select * from apex_mail_queue; 4 | select * from apex_mail_attachments; 5 | 6 | apex_mail 7 | 8 | -- send procedure 9 | declare 10 | v_placeholders clob; 11 | begin 12 | 13 | apex_json.initialize_clob_output; 14 | apex_json.open_object; 15 | apex_json.write('EVENT_DATE', '15.10.2018'); 16 | apex_json.write('EVENT_NAME', 'MakeIT 2018 New'); 17 | apex_json.write('INVITEE', 'Marko Gorički'); 18 | apex_json.write('ORGANIZER', 'SIOUG'); 19 | apex_json.write('LOCATION', 'Portorož'); 20 | apex_json.close_object; 21 | 22 | v_placeholders := apex_json.get_clob_output; 23 | apex_json.free_output; 24 | 25 | apex_mail.send ( 26 | p_template_static_id => 'TEST' 27 | , p_placeholders => v_placeholders 28 | , p_to => 'marko.goricki@bilog.hr' 29 | , p_cc => null 30 | , p_bcc => null 31 | , p_from => 'mgoricki8@gmail.com' 32 | , p_replyto => null 33 | , p_application_id => 114-- default wwv_flow_security.g_flow_id 34 | ); 35 | apex_mail.push_queue; 36 | end; 37 | / 38 | 39 | -- prepare_template 40 | declare 41 | v_subject varchar2(200); 42 | v_html clob; 43 | v_text clob; 44 | v_placeholders clob; 45 | begin 46 | 47 | apex_json.initialize_clob_output; 48 | apex_json.open_object; 49 | apex_json.write('EVENT_DATE', '15.10.2018'); 50 | apex_json.write('EVENT_NAME', 'MakeIT 2018'); 51 | apex_json.write('INVITEE', 'Marko Gorički'); 52 | apex_json.write('ORGANIZER', 'SIOUG'); 53 | apex_json.write('LOCATION', 'Portorož'); 54 | apex_json.close_object; 55 | 56 | v_placeholders := apex_json.get_clob_output; 57 | apex_json.free_output; 58 | 59 | apex_mail.prepare_template ( 60 | p_static_id => 'TEST' 61 | , p_placeholders => v_placeholders--'{"DATUM":"","IME":"Marko", "PREZIME":"Gorički"}' 62 | , p_application_id => 114 63 | , p_subject => v_subject 64 | , p_html => v_html 65 | , p_text => v_text); 66 | 67 | dbms_output.put_line('Subject: '||v_subject); 68 | dbms_output.put_line('HTML: '||v_html); 69 | dbms_output.put_line('Text: '||v_text); 70 | end; 71 | / -------------------------------------------------------------------------------- /examples/Untitled.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/examples/Untitled.sql -------------------------------------------------------------------------------- /examples/apex_json.sql: -------------------------------------------------------------------------------- 1 | declare 2 | v_json apex_json.t_values; 3 | v_tab apex_t_varchar2; 4 | begin 5 | apex_json.parse(v_json, '{ "foo": ["one", "two"], "bar": "three" }'); 6 | v_tab := apex_json.get_t_varchar2(p_values => v_json 7 | , p_path => 'foo'); 8 | for i in (select * 9 | from table(v_tab) 10 | ) 11 | loop 12 | dbms_output.put_line(i.column_value); 13 | end loop; 14 | end; 15 | / -------------------------------------------------------------------------------- /examples/apex_pkg_app_install.sql: -------------------------------------------------------------------------------- 1 | -- install: 2 | declare 3 | v_new_app_id number; 4 | begin 5 | apex_util.set_workspace('SIOUG2018'); 6 | 7 | v_new_app_id := apex_pkg_app_install.install( 8 | p_app_name => 'Sample Database Application', 9 | p_authentication_type => apex_authentication.c_type_apex_accounts, 10 | p_schema => 'SIOUG2018'); 11 | dbms_output.put_line(v_new_app_id); 12 | end; 13 | / 14 | 15 | -- deinstall: 16 | begin 17 | apex_util.set_workspace('SIOUG2018'); 18 | apex_pkg_app_install.deinstall(p_app_id => 8950); 19 | end; 20 | / 21 | 22 | -- upgrade -------------------------------------------------------------------------------- /examples/apex_string.sql: -------------------------------------------------------------------------------- 1 | set serveroutput on ; 2 | -------------------------------------- 3 | -- apex_util.string_to_table DEPRECATED 4 | declare 5 | v_arr apex_application_global.vc_arr2; 6 | begin 7 | v_arr := apex_util.string_to_table('One:Two:Three'); 8 | for i in 1..v_arr.count 9 | loop 10 | dbms_output.put_line(v_arr(i)); 11 | end loop; 12 | end; 13 | / 14 | 15 | -- apex_string 16 | select * from apex_string.split('One:Two:Three', ':'); 17 | -- select * from APEX_UTIL.STRING_TO_TABLE('One:Two:Three'); 18 | 19 | -------------------------------------- 20 | -- apex_util.table_to_string DEPRECATED 21 | declare 22 | v_arr apex_application_global.vc_arr2; 23 | begin 24 | select ename 25 | bulk collect into v_arr 26 | from emp; 27 | 28 | dbms_output.put_line(apex_util.table_to_string(v_arr)); 29 | end; 30 | / 31 | 32 | -- apex_string.join 33 | declare 34 | v_arr apex_t_varchar2; 35 | begin 36 | select ename 37 | bulk collect into v_arr 38 | from emp; 39 | 40 | dbms_output.put_line(apex_string.join(v_arr, ':')); 41 | end; 42 | / 43 | 44 | 45 | select apex_string.join(apex_t_varchar2('One','Two','Three'),':') x 46 | from dual; 47 | 48 | 49 | -------------------------------------- 50 | -- PUT/GET table 51 | declare 52 | v_table apex_t_varchar2; 53 | begin 54 | -- populate table 55 | for i in (select ename, sal from emp) 56 | loop 57 | -- put element into table 58 | apex_string.plist_put(v_table, i.ename, i.sal); 59 | end loop; 60 | 61 | 62 | -- get element from table 63 | dbms_output.put_line( 64 | apex_string.plist_get(v_table, 'JONES') 65 | ); 66 | end; 67 | / 68 | 69 | -------------------------------------- 70 | -- APEX_STRING.MESSAGE 71 | -- %usage Returns a formatted string, with substitutions applied. 72 | 73 | select apex_string.format('Hi %s! Hope to see you at the party. It starts at %s.', 'Marko', '18:30') m 74 | from dual; 75 | 76 | -- with %0 %1 - starts with zero 77 | select apex_string.format('Hi %1! Hope to see you at the party. It starts at %0.', '18:30', 'Marko', p_max_length => 10) m 78 | from dual; 79 | 80 | -------------------------------------- 81 | -- APEX_STRING.SHUFFLE 82 | -- %usage Returns the input table values, re-ordered.. 83 | select * 84 | from apex_string.shuffle(apex_t_varchar2('One','Two','Three')); 85 | 86 | -------------------------------------- 87 | -- PARSING CSV 88 | select /*csv*/ * from emp; -- get CSV 89 | 90 | -- parse CSV with apex_string 91 | with 92 | function get_column (p_row varchar2 93 | , p_col_num number) 94 | return varchar2 95 | is 96 | v_row apex_t_varchar2; 97 | begin 98 | v_row := apex_string.split(p_row, ','); 99 | if v_row.exists(p_col_num) then 100 | return v_row(p_col_num); 101 | end if; 102 | return null; 103 | end; 104 | select get_column(column_value, 1) as col1 105 | , get_column(column_value, 2) as col2 106 | , get_column(column_value, 3) as col3 107 | , get_column(column_value, 4) as col4 108 | , get_column(column_value, 5) as col5 109 | , get_column(column_value, 6) as col6 110 | , get_column(column_value, 7) as col7 111 | , get_column(column_value, 8) as col8 112 | from apex_string.split(:CSVDATA, chr(10)); 113 | / 114 | 115 | -------------------------------------- 116 | -- APEX_UTIL.GET_HASH 117 | -- computes a hash value for all given values 118 | -- can be used to implement lost update detection for data records 119 | -- p_salted - if true (the default), salt hash with internal session info 120 | 121 | select ename, apex_util.get_hash(apex_t_varchar2 (empno, sal, comm)) x 122 | from emp; 123 | -------------------------------------------------------------------------------- /examples/apex_url.sql: -------------------------------------------------------------------------------- 1 | --alter system flush shared_pool; 2 | select fetches, executions, sql_text From v$sqlarea where sql_Text like '%apex_url%' and sql_text not like '%v$sqlarea%'; 3 | select count(1) From v$sqlarea where sql_Text like '%apex_url_good%' and sql_text not like '%v$sqlarea%'; 4 | select count(1) From v$sqlarea where sql_Text like '%apex_url_bad%' and sql_text not like '%v$sqlarea%'; 5 | 6 | -------------------------------------------------------------------------------- /examples/session_cloning.sql: -------------------------------------------------------------------------------- 1 | -- before using it, you have to enable it with sys user or apex_administrator_roe user 2 | 3 | -- grant apex_administrator_role to sioug2018; 4 | begin 5 | apex_instance_admin.set_parameter( 6 | p_parameter => 'CLONE_SESSION_ENABLED', 7 | p_value => 'Y'); 8 | end; 9 | / 10 | 11 | -- add request to the link APEX_CLONE_SESSION -------------------------------------------------------------------------------- /img/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/img/bg1.png -------------------------------------------------------------------------------- /img/bilogweb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/img/bilogweb.png -------------------------------------------------------------------------------- /img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/img/favicon.ico -------------------------------------------------------------------------------- /img/qrcode copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/img/qrcode copy.png -------------------------------------------------------------------------------- /img/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/img/qrcode.png -------------------------------------------------------------------------------- /img/slika.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgoricki/presentation-apex-18-hidden-features/554e50cfc89092753b0b961a55ca31a77a86cd09/img/slika.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | APEX 18.1 "hidden" features 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | 66 | 67 | -------------------------------------------------------------------------------- /lib/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} 5 | -------------------------------------------------------------------------------- /lib/css/foundation.min.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /*! normalize-scss | MIT/GPLv2 License | bit.ly/normalize-scss */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}main{display:block}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}input{overflow:visible}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;display:table;max-width:100%;padding:0;color:inherit;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}details{display:block}summary{display:list-item}menu{display:block}canvas{display:inline-block}[hidden],template{display:none}.foundation-mq{font-family:"small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}html{box-sizing:border-box;font-size:100%}*,:after,:before{box-sizing:inherit}body{margin:0;padding:0;background:#fefefe;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;color:#0a0a0a;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle;max-width:100%;height:auto;-ms-interpolation-mode:bicubic}textarea{height:auto;min-height:50px;border-radius:0}select{box-sizing:border-box;width:100%;border-radius:0}.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;border-radius:0;background:transparent;line-height:1}[data-whatinput=mouse] button{outline:0}pre{overflow:auto}.is-visible{display:block!important}.is-hidden{display:none!important}.row{max-width:75rem;margin-right:auto;margin-left:auto}.row:after,.row:before{display:table;content:" "}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-right:0;padding-left:0}.row .row{margin-right:-.625rem;margin-left:-.625rem}@media print,screen and (min-width:40em){.row .row{margin-right:-.9375rem;margin-left:-.9375rem}}@media print,screen and (min-width:64em){.row .row{margin-right:-.9375rem;margin-left:-.9375rem}}.row .row.collapse{margin-right:0;margin-left:0}.row.expanded{max-width:none}.row.expanded .row{margin-right:auto;margin-left:auto}.row:not(.expanded) .row{max-width:none}.row.gutter-small>.column,.row.gutter-small>.columns{padding-right:.625rem;padding-left:.625rem}.row.gutter-medium>.column,.row.gutter-medium>.columns{padding-right:.9375rem;padding-left:.9375rem}.column,.columns{width:100%;float:left;padding-right:.625rem;padding-left:.625rem}@media print,screen and (min-width:40em){.column,.columns{padding-right:.9375rem;padding-left:.9375rem}}.column:last-child:not(:first-child),.columns:last-child:not(:first-child){float:right}.column.end:last-child:last-child,.end.columns:last-child:last-child{float:left}.column.row.row,.row.row.columns{float:none}.row .column.row.row,.row .row.row.columns{margin-right:0;margin-left:0;padding-right:0;padding-left:0}.small-1{width:8.33333%}.small-push-1{position:relative;left:8.33333%}.small-pull-1{position:relative;left:-8.33333%}.small-offset-0{margin-left:0}.small-2{width:16.66667%}.small-push-2{position:relative;left:16.66667%}.small-pull-2{position:relative;left:-16.66667%}.small-offset-1{margin-left:8.33333%}.small-3{width:25%}.small-push-3{position:relative;left:25%}.small-pull-3{position:relative;left:-25%}.small-offset-2{margin-left:16.66667%}.small-4{width:33.33333%}.small-push-4{position:relative;left:33.33333%}.small-pull-4{position:relative;left:-33.33333%}.small-offset-3{margin-left:25%}.small-5{width:41.66667%}.small-push-5{position:relative;left:41.66667%}.small-pull-5{position:relative;left:-41.66667%}.small-offset-4{margin-left:33.33333%}.small-6{width:50%}.small-push-6{position:relative;left:50%}.small-pull-6{position:relative;left:-50%}.small-offset-5{margin-left:41.66667%}.small-7{width:58.33333%}.small-push-7{position:relative;left:58.33333%}.small-pull-7{position:relative;left:-58.33333%}.small-offset-6{margin-left:50%}.small-8{width:66.66667%}.small-push-8{position:relative;left:66.66667%}.small-pull-8{position:relative;left:-66.66667%}.small-offset-7{margin-left:58.33333%}.small-9{width:75%}.small-push-9{position:relative;left:75%}.small-pull-9{position:relative;left:-75%}.small-offset-8{margin-left:66.66667%}.small-10{width:83.33333%}.small-push-10{position:relative;left:83.33333%}.small-pull-10{position:relative;left:-83.33333%}.small-offset-9{margin-left:75%}.small-11{width:91.66667%}.small-push-11{position:relative;left:91.66667%}.small-pull-11{position:relative;left:-91.66667%}.small-offset-10{margin-left:83.33333%}.small-12{width:100%}.small-offset-11{margin-left:91.66667%}.small-up-1>.column,.small-up-1>.columns{float:left;width:100%}.small-up-1>.column:nth-of-type(1n),.small-up-1>.columns:nth-of-type(1n){clear:none}.small-up-1>.column:nth-of-type(1n+1),.small-up-1>.columns:nth-of-type(1n+1){clear:both}.small-up-1>.column:last-child,.small-up-1>.columns:last-child{float:left}.small-up-2>.column,.small-up-2>.columns{float:left;width:50%}.small-up-2>.column:nth-of-type(1n),.small-up-2>.columns:nth-of-type(1n){clear:none}.small-up-2>.column:nth-of-type(2n+1),.small-up-2>.columns:nth-of-type(2n+1){clear:both}.small-up-2>.column:last-child,.small-up-2>.columns:last-child{float:left}.small-up-3>.column,.small-up-3>.columns{float:left;width:33.33333%}.small-up-3>.column:nth-of-type(1n),.small-up-3>.columns:nth-of-type(1n){clear:none}.small-up-3>.column:nth-of-type(3n+1),.small-up-3>.columns:nth-of-type(3n+1){clear:both}.small-up-3>.column:last-child,.small-up-3>.columns:last-child{float:left}.small-up-4>.column,.small-up-4>.columns{float:left;width:25%}.small-up-4>.column:nth-of-type(1n),.small-up-4>.columns:nth-of-type(1n){clear:none}.small-up-4>.column:nth-of-type(4n+1),.small-up-4>.columns:nth-of-type(4n+1){clear:both}.small-up-4>.column:last-child,.small-up-4>.columns:last-child{float:left}.small-up-5>.column,.small-up-5>.columns{float:left;width:20%}.small-up-5>.column:nth-of-type(1n),.small-up-5>.columns:nth-of-type(1n){clear:none}.small-up-5>.column:nth-of-type(5n+1),.small-up-5>.columns:nth-of-type(5n+1){clear:both}.small-up-5>.column:last-child,.small-up-5>.columns:last-child{float:left}.small-up-6>.column,.small-up-6>.columns{float:left;width:16.66667%}.small-up-6>.column:nth-of-type(1n),.small-up-6>.columns:nth-of-type(1n){clear:none}.small-up-6>.column:nth-of-type(6n+1),.small-up-6>.columns:nth-of-type(6n+1){clear:both}.small-up-6>.column:last-child,.small-up-6>.columns:last-child{float:left}.small-up-7>.column,.small-up-7>.columns{float:left;width:14.28571%}.small-up-7>.column:nth-of-type(1n),.small-up-7>.columns:nth-of-type(1n){clear:none}.small-up-7>.column:nth-of-type(7n+1),.small-up-7>.columns:nth-of-type(7n+1){clear:both}.small-up-7>.column:last-child,.small-up-7>.columns:last-child{float:left}.small-up-8>.column,.small-up-8>.columns{float:left;width:12.5%}.small-up-8>.column:nth-of-type(1n),.small-up-8>.columns:nth-of-type(1n){clear:none}.small-up-8>.column:nth-of-type(8n+1),.small-up-8>.columns:nth-of-type(8n+1){clear:both}.small-up-8>.column:last-child,.small-up-8>.columns:last-child{float:left}.small-collapse>.column,.small-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .small-collapse.row,.small-collapse .row{margin-right:0;margin-left:0}.small-uncollapse>.column,.small-uncollapse>.columns{padding-right:.625rem;padding-left:.625rem}.small-centered{margin-right:auto;margin-left:auto}.small-centered,.small-centered:last-child:not(:first-child){float:none;clear:both}.small-pull-0,.small-push-0,.small-uncentered{position:static;float:left;margin-right:0;margin-left:0}@media print,screen and (min-width:40em){.medium-1{width:8.33333%}.medium-push-1{position:relative;left:8.33333%}.medium-pull-1{position:relative;left:-8.33333%}.medium-offset-0{margin-left:0}.medium-2{width:16.66667%}.medium-push-2{position:relative;left:16.66667%}.medium-pull-2{position:relative;left:-16.66667%}.medium-offset-1{margin-left:8.33333%}.medium-3{width:25%}.medium-push-3{position:relative;left:25%}.medium-pull-3{position:relative;left:-25%}.medium-offset-2{margin-left:16.66667%}.medium-4{width:33.33333%}.medium-push-4{position:relative;left:33.33333%}.medium-pull-4{position:relative;left:-33.33333%}.medium-offset-3{margin-left:25%}.medium-5{width:41.66667%}.medium-push-5{position:relative;left:41.66667%}.medium-pull-5{position:relative;left:-41.66667%}.medium-offset-4{margin-left:33.33333%}.medium-6{width:50%}.medium-push-6{position:relative;left:50%}.medium-pull-6{position:relative;left:-50%}.medium-offset-5{margin-left:41.66667%}.medium-7{width:58.33333%}.medium-push-7{position:relative;left:58.33333%}.medium-pull-7{position:relative;left:-58.33333%}.medium-offset-6{margin-left:50%}.medium-8{width:66.66667%}.medium-push-8{position:relative;left:66.66667%}.medium-pull-8{position:relative;left:-66.66667%}.medium-offset-7{margin-left:58.33333%}.medium-9{width:75%}.medium-push-9{position:relative;left:75%}.medium-pull-9{position:relative;left:-75%}.medium-offset-8{margin-left:66.66667%}.medium-10{width:83.33333%}.medium-push-10{position:relative;left:83.33333%}.medium-pull-10{position:relative;left:-83.33333%}.medium-offset-9{margin-left:75%}.medium-11{width:91.66667%}.medium-push-11{position:relative;left:91.66667%}.medium-pull-11{position:relative;left:-91.66667%}.medium-offset-10{margin-left:83.33333%}.medium-12{width:100%}.medium-offset-11{margin-left:91.66667%}.medium-up-1>.column,.medium-up-1>.columns{float:left;width:100%}.medium-up-1>.column:nth-of-type(1n),.medium-up-1>.columns:nth-of-type(1n){clear:none}.medium-up-1>.column:nth-of-type(1n+1),.medium-up-1>.columns:nth-of-type(1n+1){clear:both}.medium-up-1>.column:last-child,.medium-up-1>.columns:last-child{float:left}.medium-up-2>.column,.medium-up-2>.columns{float:left;width:50%}.medium-up-2>.column:nth-of-type(1n),.medium-up-2>.columns:nth-of-type(1n){clear:none}.medium-up-2>.column:nth-of-type(2n+1),.medium-up-2>.columns:nth-of-type(2n+1){clear:both}.medium-up-2>.column:last-child,.medium-up-2>.columns:last-child{float:left}.medium-up-3>.column,.medium-up-3>.columns{float:left;width:33.33333%}.medium-up-3>.column:nth-of-type(1n),.medium-up-3>.columns:nth-of-type(1n){clear:none}.medium-up-3>.column:nth-of-type(3n+1),.medium-up-3>.columns:nth-of-type(3n+1){clear:both}.medium-up-3>.column:last-child,.medium-up-3>.columns:last-child{float:left}.medium-up-4>.column,.medium-up-4>.columns{float:left;width:25%}.medium-up-4>.column:nth-of-type(1n),.medium-up-4>.columns:nth-of-type(1n){clear:none}.medium-up-4>.column:nth-of-type(4n+1),.medium-up-4>.columns:nth-of-type(4n+1){clear:both}.medium-up-4>.column:last-child,.medium-up-4>.columns:last-child{float:left}.medium-up-5>.column,.medium-up-5>.columns{float:left;width:20%}.medium-up-5>.column:nth-of-type(1n),.medium-up-5>.columns:nth-of-type(1n){clear:none}.medium-up-5>.column:nth-of-type(5n+1),.medium-up-5>.columns:nth-of-type(5n+1){clear:both}.medium-up-5>.column:last-child,.medium-up-5>.columns:last-child{float:left}.medium-up-6>.column,.medium-up-6>.columns{float:left;width:16.66667%}.medium-up-6>.column:nth-of-type(1n),.medium-up-6>.columns:nth-of-type(1n){clear:none}.medium-up-6>.column:nth-of-type(6n+1),.medium-up-6>.columns:nth-of-type(6n+1){clear:both}.medium-up-6>.column:last-child,.medium-up-6>.columns:last-child{float:left}.medium-up-7>.column,.medium-up-7>.columns{float:left;width:14.28571%}.medium-up-7>.column:nth-of-type(1n),.medium-up-7>.columns:nth-of-type(1n){clear:none}.medium-up-7>.column:nth-of-type(7n+1),.medium-up-7>.columns:nth-of-type(7n+1){clear:both}.medium-up-7>.column:last-child,.medium-up-7>.columns:last-child{float:left}.medium-up-8>.column,.medium-up-8>.columns{float:left;width:12.5%}.medium-up-8>.column:nth-of-type(1n),.medium-up-8>.columns:nth-of-type(1n){clear:none}.medium-up-8>.column:nth-of-type(8n+1),.medium-up-8>.columns:nth-of-type(8n+1){clear:both}.medium-up-8>.column:last-child,.medium-up-8>.columns:last-child{float:left}.medium-collapse>.column,.medium-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .medium-collapse.row,.medium-collapse .row{margin-right:0;margin-left:0}.medium-uncollapse>.column,.medium-uncollapse>.columns{padding-right:.9375rem;padding-left:.9375rem}.medium-centered{margin-right:auto;margin-left:auto}.medium-centered,.medium-centered:last-child:not(:first-child){float:none;clear:both}.medium-pull-0,.medium-push-0,.medium-uncentered{position:static;float:left;margin-right:0;margin-left:0}}@media print,screen and (min-width:64em){.large-1{width:8.33333%}.large-push-1{position:relative;left:8.33333%}.large-pull-1{position:relative;left:-8.33333%}.large-offset-0{margin-left:0}.large-2{width:16.66667%}.large-push-2{position:relative;left:16.66667%}.large-pull-2{position:relative;left:-16.66667%}.large-offset-1{margin-left:8.33333%}.large-3{width:25%}.large-push-3{position:relative;left:25%}.large-pull-3{position:relative;left:-25%}.large-offset-2{margin-left:16.66667%}.large-4{width:33.33333%}.large-push-4{position:relative;left:33.33333%}.large-pull-4{position:relative;left:-33.33333%}.large-offset-3{margin-left:25%}.large-5{width:41.66667%}.large-push-5{position:relative;left:41.66667%}.large-pull-5{position:relative;left:-41.66667%}.large-offset-4{margin-left:33.33333%}.large-6{width:50%}.large-push-6{position:relative;left:50%}.large-pull-6{position:relative;left:-50%}.large-offset-5{margin-left:41.66667%}.large-7{width:58.33333%}.large-push-7{position:relative;left:58.33333%}.large-pull-7{position:relative;left:-58.33333%}.large-offset-6{margin-left:50%}.large-8{width:66.66667%}.large-push-8{position:relative;left:66.66667%}.large-pull-8{position:relative;left:-66.66667%}.large-offset-7{margin-left:58.33333%}.large-9{width:75%}.large-push-9{position:relative;left:75%}.large-pull-9{position:relative;left:-75%}.large-offset-8{margin-left:66.66667%}.large-10{width:83.33333%}.large-push-10{position:relative;left:83.33333%}.large-pull-10{position:relative;left:-83.33333%}.large-offset-9{margin-left:75%}.large-11{width:91.66667%}.large-push-11{position:relative;left:91.66667%}.large-pull-11{position:relative;left:-91.66667%}.large-offset-10{margin-left:83.33333%}.large-12{width:100%}.large-offset-11{margin-left:91.66667%}.large-up-1>.column,.large-up-1>.columns{float:left;width:100%}.large-up-1>.column:nth-of-type(1n),.large-up-1>.columns:nth-of-type(1n){clear:none}.large-up-1>.column:nth-of-type(1n+1),.large-up-1>.columns:nth-of-type(1n+1){clear:both}.large-up-1>.column:last-child,.large-up-1>.columns:last-child{float:left}.large-up-2>.column,.large-up-2>.columns{float:left;width:50%}.large-up-2>.column:nth-of-type(1n),.large-up-2>.columns:nth-of-type(1n){clear:none}.large-up-2>.column:nth-of-type(2n+1),.large-up-2>.columns:nth-of-type(2n+1){clear:both}.large-up-2>.column:last-child,.large-up-2>.columns:last-child{float:left}.large-up-3>.column,.large-up-3>.columns{float:left;width:33.33333%}.large-up-3>.column:nth-of-type(1n),.large-up-3>.columns:nth-of-type(1n){clear:none}.large-up-3>.column:nth-of-type(3n+1),.large-up-3>.columns:nth-of-type(3n+1){clear:both}.large-up-3>.column:last-child,.large-up-3>.columns:last-child{float:left}.large-up-4>.column,.large-up-4>.columns{float:left;width:25%}.large-up-4>.column:nth-of-type(1n),.large-up-4>.columns:nth-of-type(1n){clear:none}.large-up-4>.column:nth-of-type(4n+1),.large-up-4>.columns:nth-of-type(4n+1){clear:both}.large-up-4>.column:last-child,.large-up-4>.columns:last-child{float:left}.large-up-5>.column,.large-up-5>.columns{float:left;width:20%}.large-up-5>.column:nth-of-type(1n),.large-up-5>.columns:nth-of-type(1n){clear:none}.large-up-5>.column:nth-of-type(5n+1),.large-up-5>.columns:nth-of-type(5n+1){clear:both}.large-up-5>.column:last-child,.large-up-5>.columns:last-child{float:left}.large-up-6>.column,.large-up-6>.columns{float:left;width:16.66667%}.large-up-6>.column:nth-of-type(1n),.large-up-6>.columns:nth-of-type(1n){clear:none}.large-up-6>.column:nth-of-type(6n+1),.large-up-6>.columns:nth-of-type(6n+1){clear:both}.large-up-6>.column:last-child,.large-up-6>.columns:last-child{float:left}.large-up-7>.column,.large-up-7>.columns{float:left;width:14.28571%}.large-up-7>.column:nth-of-type(1n),.large-up-7>.columns:nth-of-type(1n){clear:none}.large-up-7>.column:nth-of-type(7n+1),.large-up-7>.columns:nth-of-type(7n+1){clear:both}.large-up-7>.column:last-child,.large-up-7>.columns:last-child{float:left}.large-up-8>.column,.large-up-8>.columns{float:left;width:12.5%}.large-up-8>.column:nth-of-type(1n),.large-up-8>.columns:nth-of-type(1n){clear:none}.large-up-8>.column:nth-of-type(8n+1),.large-up-8>.columns:nth-of-type(8n+1){clear:both}.large-up-8>.column:last-child,.large-up-8>.columns:last-child{float:left}.large-collapse>.column,.large-collapse>.columns{padding-right:0;padding-left:0}.expanded.row .large-collapse.row,.large-collapse .row{margin-right:0;margin-left:0}.large-uncollapse>.column,.large-uncollapse>.columns{padding-right:.9375rem;padding-left:.9375rem}.large-centered{margin-right:auto;margin-left:auto}.large-centered,.large-centered:last-child:not(:first-child){float:none;clear:both}.large-pull-0,.large-push-0,.large-uncentered{position:static;float:left;margin-right:0;margin-left:0}}.column-block{margin-bottom:1.25rem}.column-block>:last-child{margin-bottom:0}@media print,screen and (min-width:40em){.column-block{margin-bottom:1.875rem}.column-block>:last-child{margin-bottom:0}}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}p{margin-bottom:1rem;font-size:inherit;line-height:1.6;text-rendering:optimizeLegibility}em,i{font-style:italic}b,em,i,strong{line-height:inherit}b,strong{font-weight:700}small{font-size:80%;line-height:inherit}h1,h2,h3,h4,h5,h6{font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-style:normal;font-weight:400;color:inherit;text-rendering:optimizeLegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{line-height:0;color:#cacaca}h1{font-size:1.5rem}h1,h2{line-height:1.4;margin-top:0;margin-bottom:.5rem}h2{font-size:1.25rem}h3{font-size:1.1875rem}h3,h4{line-height:1.4;margin-top:0;margin-bottom:.5rem}h4{font-size:1.125rem}h5{font-size:1.0625rem}h5,h6{line-height:1.4;margin-top:0;margin-bottom:.5rem}h6{font-size:1rem}@media print,screen and (min-width:40em){h1{font-size:3rem}h2{font-size:2.5rem}h3{font-size:1.9375rem}h4{font-size:1.5625rem}h5{font-size:1.25rem}h6{font-size:1rem}}a{line-height:inherit;color:#1779ba;text-decoration:none;cursor:pointer}a:focus,a:hover{color:#1468a0}a img{border:0}hr{clear:both;max-width:75rem;height:0;margin:1.25rem auto;border-top:0;border-right:0;border-bottom:1px solid #cacaca;border-left:0}dl,ol,ul{margin-bottom:1rem;list-style-position:outside;line-height:1.6}li{font-size:inherit}ul{list-style-type:disc}ol,ul{margin-left:1.25rem}ol ol,ol ul,ul ol,ul ul{margin-left:1.25rem;margin-bottom:0}dl{margin-bottom:1rem}dl dt{margin-bottom:.3rem;font-weight:700}blockquote{margin:0 0 1rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #cacaca}blockquote,blockquote p{line-height:1.6;color:#8a8a8a}cite{display:block;font-size:.8125rem;color:#8a8a8a}cite:before{content:"— "}abbr{border-bottom:1px dotted #0a0a0a;color:#0a0a0a;cursor:help}figure{margin:0}code{padding:.125rem .3125rem .0625rem;border:1px solid #cacaca;font-weight:400}code,kbd{background-color:#e6e6e6;font-family:Consolas,Liberation Mono,Courier,monospace;color:#0a0a0a}kbd{margin:0;padding:.125rem .25rem 0}.subheader{margin-top:.2rem;margin-bottom:.5rem;font-weight:400;line-height:1.4;color:#8a8a8a}.lead{font-size:125%;line-height:1.6}.stat{font-size:2.5rem;line-height:1}p+.stat{margin-top:-1rem}.no-bullet{margin-left:0;list-style:none}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media print,screen and (min-width:40em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media print,screen and (min-width:64em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none!important}@media print{*{background:transparent!important;box-shadow:none!important;color:#000!important;text-shadow:none!important}.show-for-print{display:block!important}.hide-for-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}abbr[title]:after{content:" (" attr(title) ")"}blockquote,pre{border:1px solid #8a8a8a;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.button{display:inline-block;vertical-align:middle;margin:0 0 1rem;padding:.85em 1em;-webkit-appearance:none;border:1px solid transparent;border-radius:0;transition:background-color .25s ease-out,color .25s ease-out;font-size:.9rem;line-height:1;text-align:center;cursor:pointer;background-color:#1779ba;color:#fefefe}[data-whatinput=mouse] .button{outline:0}.button:focus,.button:hover{background-color:#14679e;color:#fefefe}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;width:100%;margin-right:0;margin-left:0}.button.primary{background-color:#1779ba;color:#fefefe}.button.primary:focus,.button.primary:hover{background-color:#126195;color:#fefefe}.button.secondary{background-color:#767676;color:#fefefe}.button.secondary:focus,.button.secondary:hover{background-color:#5e5e5e;color:#fefefe}.button.success{background-color:#3adb76;color:#0a0a0a}.button.success:focus,.button.success:hover{background-color:#22bb5b;color:#0a0a0a}.button.warning{background-color:#ffae00;color:#0a0a0a}.button.warning:focus,.button.warning:hover{background-color:#cc8b00;color:#0a0a0a}.button.alert{background-color:#cc4b37;color:#fefefe}.button.alert:focus,.button.alert:hover{background-color:#a53b2a;color:#fefefe}.button.hollow{border:1px solid #1779ba;color:#1779ba}.button.hollow,.button.hollow:focus,.button.hollow:hover{background-color:transparent}.button.hollow:focus,.button.hollow:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.primary{border:1px solid #1779ba;color:#1779ba}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.secondary{border:1px solid #767676;color:#767676}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3b3b3b;color:#3b3b3b}.button.hollow.success{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.warning{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.hollow.alert{border:1px solid #cc4b37;color:#cc4b37}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#67251a;color:#67251a}.button.disabled,.button[disabled]{opacity:.25;cursor:not-allowed}.button.disabled,.button.disabled:focus,.button.disabled:hover,.button[disabled],.button[disabled]:focus,.button[disabled]:hover{background-color:#1779ba;color:#fefefe}.button.disabled.primary,.button[disabled].primary{opacity:.25;cursor:not-allowed}.button.disabled.primary,.button.disabled.primary:focus,.button.disabled.primary:hover,.button[disabled].primary,.button[disabled].primary:focus,.button[disabled].primary:hover{background-color:#1779ba;color:#fefefe}.button.disabled.secondary,.button[disabled].secondary{opacity:.25;cursor:not-allowed}.button.disabled.secondary,.button.disabled.secondary:focus,.button.disabled.secondary:hover,.button[disabled].secondary,.button[disabled].secondary:focus,.button[disabled].secondary:hover{background-color:#767676;color:#fefefe}.button.disabled.success,.button[disabled].success{opacity:.25;cursor:not-allowed}.button.disabled.success,.button.disabled.success:focus,.button.disabled.success:hover,.button[disabled].success,.button[disabled].success:focus,.button[disabled].success:hover{background-color:#3adb76;color:#0a0a0a}.button.disabled.warning,.button[disabled].warning{opacity:.25;cursor:not-allowed}.button.disabled.warning,.button.disabled.warning:focus,.button.disabled.warning:hover,.button[disabled].warning,.button[disabled].warning:focus,.button[disabled].warning:hover{background-color:#ffae00;color:#0a0a0a}.button.disabled.alert,.button[disabled].alert{opacity:.25;cursor:not-allowed}.button.disabled.alert,.button.disabled.alert:focus,.button.disabled.alert:hover,.button[disabled].alert,.button[disabled].alert:focus,.button[disabled].alert:hover{background-color:#cc4b37;color:#fefefe}.button.dropdown:after{display:block;width:0;height:0;border:.4em inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#fefefe transparent transparent;position:relative;top:.4em;display:inline-block;float:right;margin-left:1em}.button.arrow-only:after{top:-.1em;float:none;margin-left:0}[type=color],[type=date],[type=datetime-local],[type=datetime],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],textarea{display:block;box-sizing:border-box;width:100%;height:2.4375rem;margin:0 0 1rem;padding:.5rem;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);font-family:inherit;font-size:1rem;font-weight:400;color:#0a0a0a;transition:box-shadow .5s,border-color .25s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}[type=color]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=datetime]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,textarea:focus{outline:none;border:1px solid #8a8a8a;background-color:#fefefe;box-shadow:0 0 5px #cacaca;transition:box-shadow .5s,border-color .25s ease-in-out}textarea{max-width:100%}textarea[rows]{height:auto}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#cacaca}input::-moz-placeholder,textarea::-moz-placeholder{color:#cacaca}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#cacaca}input::placeholder,textarea::placeholder{color:#cacaca}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:not-allowed}[type=button],[type=submit]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}input[type=search]{box-sizing:border-box}[type=checkbox],[type=file],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;vertical-align:baseline;margin-left:.5rem;margin-right:1rem;margin-bottom:0}[type=checkbox]+label[for],[type=radio]+label[for]{cursor:pointer}label>[type=checkbox],label>[type=radio]{margin-right:.5rem}[type=file]{width:100%}label{display:block;margin:0;font-size:.875rem;font-weight:400;line-height:1.8;color:#0a0a0a}label.middle{margin:0 0 1rem;padding:.5625rem 0}.help-text{margin-top:-.5rem;font-size:.8125rem;font-style:italic;color:#0a0a0a}.input-group{display:table;width:100%;margin-bottom:1rem}.input-group>:first-child,.input-group>:last-child>*{border-radius:0 0 0 0}.input-group-button,.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label,.input-group-field,.input-group-label{margin:0;white-space:nowrap;display:table-cell;vertical-align:middle}.input-group-label{padding:0 1rem;border:1px solid #cacaca;background:#e6e6e6;color:#0a0a0a;text-align:center;white-space:nowrap;width:1%;height:100%}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{border-radius:0;height:2.5rem}.input-group-button{padding-top:0;padding-bottom:0;text-align:center;width:1%;height:100%}.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label{height:2.5rem;padding-top:0;padding-bottom:0;font-size:1rem}.input-group .input-group-button{display:table-cell}fieldset{margin:0;padding:0;border:0}legend{max-width:100%;margin-bottom:.5rem}.fieldset{margin:1.125rem 0;padding:1.25rem;border:1px solid #cacaca}.fieldset legend{margin:0;margin-left:-.1875rem;padding:0 .1875rem;background:#fefefe}select{height:2.4375rem;margin:0 0 1rem;padding:.5rem;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;font-family:inherit;font-size:1rem;line-height:normal;color:#0a0a0a;background-image:url("data:image/svg+xml;utf8,");background-origin:content-box;background-position:right -1rem center;background-repeat:no-repeat;background-size:9px 6px;padding-right:1.5rem;transition:box-shadow .5s,border-color .25s ease-in-out}@media screen and (min-width:0\0){select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==")}}select:focus{outline:none;border:1px solid #8a8a8a;background-color:#fefefe;box-shadow:0 0 5px #cacaca;transition:box-shadow .5s,border-color .25s ease-in-out}select:disabled{background-color:#e6e6e6;cursor:not-allowed}select::-ms-expand{display:none}select[multiple]{height:auto;background-image:none}.is-invalid-input:not(:focus){border-color:#cc4b37;background-color:#f9ecea}.is-invalid-input:not(:focus)::-webkit-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::-moz-placeholder{color:#cc4b37}.is-invalid-input:not(:focus):-ms-input-placeholder{color:#cc4b37}.form-error,.is-invalid-input:not(:focus)::placeholder,.is-invalid-label{color:#cc4b37}.form-error{display:none;margin-top:-.5rem;margin-bottom:1rem;font-size:.75rem;font-weight:700}.form-error.is-visible{display:block}.accordion{margin-left:0;background:#fefefe;list-style-type:none}.accordion-item:first-child>:first-child,.accordion-item:last-child>:last-child{border-radius:0 0 0 0}.accordion-title{position:relative;display:block;padding:1.25rem 1rem;border:1px solid #e6e6e6;border-bottom:0;font-size:.75rem;line-height:1;color:#1779ba}:last-child:not(.is-active)>.accordion-title{border-bottom:1px solid #e6e6e6;border-radius:0 0 0 0}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}.accordion-title:before{position:absolute;top:50%;right:1rem;margin-top:-.5rem;content:"+"}.is-active>.accordion-title:before{content:"\2013"}.accordion-content{display:none;padding:1rem;border:1px solid #e6e6e6;border-bottom:0;background-color:#fefefe;color:#0a0a0a}:last-child>.accordion-content:last-child{border-bottom:1px solid #e6e6e6}.is-accordion-submenu-parent>a{position:relative}.is-accordion-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;position:absolute;top:50%;margin-top:-3px;right:1rem}.is-accordion-submenu-parent[aria-expanded=true]>a:after{transform:rotate(180deg);transform-origin:50% 50%}.badge{display:inline-block;min-width:2.1em;padding:.3em;border-radius:50%;font-size:.6rem;text-align:center}.badge,.badge.primary{background:#1779ba;color:#fefefe}.badge.secondary{background:#767676;color:#fefefe}.badge.success{background:#3adb76;color:#0a0a0a}.badge.warning{background:#ffae00;color:#0a0a0a}.badge.alert{background:#cc4b37;color:#fefefe}.breadcrumbs{margin:0 0 1rem;list-style:none}.breadcrumbs:after,.breadcrumbs:before{display:table;content:" "}.breadcrumbs:after{clear:both}.breadcrumbs li{float:left;font-size:.6875rem;color:#0a0a0a;cursor:default;text-transform:uppercase}.breadcrumbs li:not(:last-child):after{position:relative;top:1px;margin:0 .75rem;opacity:1;content:"/";color:#cacaca}.breadcrumbs a{color:#1779ba}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#cacaca;cursor:not-allowed}.button-group{margin-bottom:1rem;font-size:0}.button-group:after,.button-group:before{display:table;content:" "}.button-group:after{clear:both}.button-group .button{margin:0;margin-right:1px;margin-bottom:1px;font-size:.9rem}.button-group .button:last-child{margin-right:0}.button-group.tiny .button{font-size:.6rem}.button-group.small .button{font-size:.75rem}.button-group.large .button{font-size:1.25rem}.button-group.expanded{margin-right:-1px}.button-group.expanded:after,.button-group.expanded:before{display:none}.button-group.expanded .button:first-child:last-child{width:100%}.button-group.expanded .button:first-child:nth-last-child(2),.button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2)~.button{display:inline-block;width:calc(50% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(2):first-child:nth-last-child(2)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(2):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(3),.button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3)~.button{display:inline-block;width:calc(33.33333% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(3):first-child:nth-last-child(3)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(3):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(4),.button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4)~.button{display:inline-block;width:calc(25% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(4):first-child:nth-last-child(4)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(4):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(5),.button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5)~.button{display:inline-block;width:calc(20% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(5):first-child:nth-last-child(5)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(5):last-child{margin-right:-6px}.button-group.expanded .button:first-child:nth-last-child(6),.button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6)~.button{display:inline-block;width:calc(16.66667% - 1px);margin-right:1px}.button-group.expanded .button:first-child:nth-last-child(6):first-child:nth-last-child(6)~.button:last-child,.button-group.expanded .button:first-child:nth-last-child(6):last-child{margin-right:-6px}.button-group.primary .button{background-color:#1779ba;color:#fefefe}.button-group.primary .button:focus,.button-group.primary .button:hover{background-color:#126195;color:#fefefe}.button-group.secondary .button{background-color:#767676;color:#fefefe}.button-group.secondary .button:focus,.button-group.secondary .button:hover{background-color:#5e5e5e;color:#fefefe}.button-group.success .button{background-color:#3adb76;color:#0a0a0a}.button-group.success .button:focus,.button-group.success .button:hover{background-color:#22bb5b;color:#0a0a0a}.button-group.warning .button{background-color:#ffae00;color:#0a0a0a}.button-group.warning .button:focus,.button-group.warning .button:hover{background-color:#cc8b00;color:#0a0a0a}.button-group.alert .button{background-color:#cc4b37;color:#fefefe}.button-group.alert .button:focus,.button-group.alert .button:hover{background-color:#a53b2a;color:#fefefe}.button-group.stacked-for-medium .button,.button-group.stacked-for-small .button,.button-group.stacked .button{width:100%}.button-group.stacked-for-medium .button:last-child,.button-group.stacked-for-small .button:last-child,.button-group.stacked .button:last-child{margin-bottom:0}@media print,screen and (min-width:40em){.button-group.stacked-for-small .button{width:auto;margin-bottom:0}}@media print,screen and (min-width:64em){.button-group.stacked-for-medium .button{width:auto;margin-bottom:0}}@media screen and (max-width:39.9375em){.button-group.stacked-for-small.expanded{display:block}.button-group.stacked-for-small.expanded .button{display:block;margin-right:0}}.card{margin-bottom:1rem;border:1px solid #e6e6e6;border-radius:0;background:#fefefe;box-shadow:none;overflow:hidden;color:#0a0a0a}.card>:last-child{margin-bottom:0}.card-divider{padding:1rem;background:#e6e6e6}.card-divider>:last-child{margin-bottom:0}.card-section{padding:1rem}.card-section>:last-child{margin-bottom:0}.callout{position:relative;margin:0 0 1rem;padding:1rem;border:1px solid hsla(0,0%,4%,.25);border-radius:0;background-color:#fff;color:#0a0a0a}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#d7ecfa;color:#0a0a0a}.callout.secondary{background-color:#eaeaea;color:#0a0a0a}.callout.success{background-color:#e1faea;color:#0a0a0a}.callout.warning{background-color:#fff3d9;color:#0a0a0a}.callout.alert{background-color:#f7e4e1;color:#0a0a0a}.callout.small{padding:.5rem}.callout.large{padding:3rem}.close-button{position:absolute;color:#8a8a8a;cursor:pointer}[data-whatinput=mouse] .close-button{outline:0}.close-button:focus,.close-button:hover{color:#0a0a0a}.close-button.small{right:.66rem;top:.33em;font-size:1.5em;line-height:1}.close-button,.close-button.medium{right:1rem;top:.5rem;font-size:2em;line-height:1}.menu{margin:0;list-style-type:none}.menu>li{display:table-cell;vertical-align:middle}[data-whatinput=mouse] .menu>li{outline:0}.menu>li>a{display:block;padding:.7rem 1rem;line-height:1}.menu a,.menu button,.menu input,.menu select{margin-bottom:0}.menu>li>a i,.menu>li>a i+span,.menu>li>a img,.menu>li>a img+span,.menu>li>a svg,.menu>li>a svg+span{vertical-align:middle}.menu>li>a i,.menu>li>a img,.menu>li>a svg{margin-right:.25rem;display:inline-block}.menu.horizontal>li,.menu>li{display:table-cell}.menu.expanded{display:table;width:100%;table-layout:fixed}.menu.expanded>li:first-child:last-child{width:100%}.menu.vertical>li{display:block}@media print,screen and (min-width:40em){.menu.medium-horizontal>li{display:table-cell}.menu.medium-expanded{display:table;width:100%;table-layout:fixed}.menu.medium-expanded>li:first-child:last-child{width:100%}.menu.medium-vertical>li{display:block}}@media print,screen and (min-width:64em){.menu.large-horizontal>li{display:table-cell}.menu.large-expanded{display:table;width:100%;table-layout:fixed}.menu.large-expanded>li:first-child:last-child{width:100%}.menu.large-vertical>li{display:block}}.menu.simple li{display:inline-block;vertical-align:top;line-height:1}.menu.simple a{padding:0}.menu.simple li{margin-left:0;margin-right:1rem}.menu.simple.align-right li{margin-right:0;margin-left:1rem}.menu.align-right:after,.menu.align-right:before{display:table;content:" "}.menu.align-right:after{clear:both}.menu.align-right>li{float:right}.menu.icon-top>li>a{text-align:center}.menu.icon-top>li>a i,.menu.icon-top>li>a img,.menu.icon-top>li>a svg{display:block;margin:0 auto .25rem}.menu.icon-top.vertical a>span{margin:auto}.menu.nested{margin-left:1rem}.menu .active>a{background:#1779ba;color:#fefefe}.menu.menu-bordered li{border:1px solid #e6e6e6}.menu.menu-bordered li:not(:first-child){border-top:0}.menu.menu-hover li:hover{background-color:#e6e6e6}.menu-text{padding-top:0;padding-bottom:0;padding:.7rem 1rem;font-weight:700;line-height:1;color:inherit}.menu-centered{text-align:center}.menu-centered>.menu{display:inline-block;vertical-align:top}.no-js [data-responsive-menu] ul{display:none}.menu-icon{position:relative;display:inline-block;vertical-align:middle;width:20px;height:16px;cursor:pointer}.menu-icon:after{position:absolute;top:0;left:0;display:block;width:100%;height:2px;background:#fefefe;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;content:""}.menu-icon:hover:after{background:#cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.menu-icon.dark{position:relative;display:inline-block;vertical-align:middle;width:20px;height:16px;cursor:pointer}.menu-icon.dark:after{position:absolute;top:0;left:0;display:block;width:100%;height:2px;background:#0a0a0a;box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;content:""}.menu-icon.dark:hover:after{background:#8a8a8a;box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a}.is-drilldown{position:relative;overflow:hidden}.is-drilldown li{display:block}.is-drilldown.animate-height{transition:height .5s}.is-drilldown-submenu{position:absolute;top:0;left:100%;z-index:-1;width:100%;background:#fefefe;transition:transform .15s linear}.is-drilldown-submenu.is-active{z-index:1;display:block;transform:translateX(-100%)}.is-drilldown-submenu.is-closing{transform:translateX(100%)}.drilldown-submenu-cover-previous{min-height:100%}.is-drilldown-submenu-parent>a{position:relative}.is-drilldown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba;position:absolute;top:50%;margin-top:-6px;right:1rem}.js-drilldown-back>a:before{display:block;width:0;height:0;border:6px inset;content:"";border-right-style:solid;border-color:transparent #1779ba transparent transparent;display:inline-block;vertical-align:middle;margin-right:.75rem;border-left-width:0}.dropdown-pane{position:absolute;z-index:10;display:block;width:300px;padding:1rem;visibility:hidden;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;font-size:1rem}.dropdown-pane.is-open{visibility:visible}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}.dropdown.menu>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;margin-top:-3px}[data-whatinput=mouse] .dropdown.menu a{outline:0}.no-js .dropdown.menu ul{display:none}.dropdown.menu.vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto}.dropdown.menu.vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.vertical>li>a:after{right:14px}.dropdown.menu.vertical>li.opens-left>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}@media print,screen and (min-width:40em){.dropdown.menu.medium-horizontal>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu.medium-horizontal>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;margin-top:-3px}.dropdown.menu.medium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.medium-vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto}.dropdown.menu.medium-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.medium-vertical>li>a:after{right:14px}.dropdown.menu.medium-vertical>li.opens-left>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.medium-vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}}@media print,screen and (min-width:64em){.dropdown.menu.large-horizontal>li.opens-left>.is-dropdown-submenu{top:100%;right:0;left:auto}.dropdown.menu.large-horizontal>li.opens-right>.is-dropdown-submenu{top:100%;right:auto;left:0}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a{position:relative;padding-right:1.5rem}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-bottom-width:0;border-top-style:solid;border-color:#1779ba transparent transparent;right:5px;margin-top:-3px}.dropdown.menu.large-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.large-vertical>li.opens-left>.is-dropdown-submenu{right:100%;left:auto}.dropdown.menu.large-vertical>li.opens-right>.is-dropdown-submenu{right:auto;left:100%}.dropdown.menu.large-vertical>li>a:after{right:14px}.dropdown.menu.large-vertical>li.opens-left>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.dropdown.menu.large-vertical>li.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}}.dropdown.menu.align-right .is-dropdown-submenu.first-sub{top:100%;right:0;left:auto}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical.align-right{float:right}.is-dropdown-submenu-parent{position:relative}.is-dropdown-submenu-parent a:after{position:absolute;top:50%;right:5px;margin-top:-6px}.is-dropdown-submenu-parent.opens-inner>.is-dropdown-submenu{top:100%;left:auto}.is-dropdown-submenu-parent.opens-left>.is-dropdown-submenu{right:100%;left:auto}.is-dropdown-submenu-parent.opens-right>.is-dropdown-submenu{right:auto;left:100%}.is-dropdown-submenu{position:absolute;top:0;left:100%;z-index:1;display:none;min-width:200px;border:1px solid #cacaca;background:#fefefe}.is-dropdown-submenu .is-dropdown-submenu-parent>a:after{right:14px}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-left>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-left-width:0;border-right-style:solid;border-color:transparent #1779ba transparent transparent}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after{display:block;width:0;height:0;border:6px inset;content:"";border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #1779ba}.is-dropdown-submenu .is-dropdown-submenu{margin-top:-1px}.is-dropdown-submenu>li{width:100%}.is-dropdown-submenu.js-dropdown-active{display:block}.flex-video,.responsive-embed{position:relative;height:0;margin-bottom:1rem;padding-bottom:75%;overflow:hidden}.flex-video embed,.flex-video iframe,.flex-video object,.flex-video video,.responsive-embed embed,.responsive-embed iframe,.responsive-embed object,.responsive-embed video{position:absolute;top:0;left:0;width:100%;height:100%}.flex-video.widescreen,.responsive-embed.widescreen{padding-bottom:56.25%}.label{display:inline-block;padding:.33333rem .5rem;border-radius:0;font-size:.8rem;line-height:1;white-space:nowrap;cursor:default}.label,.label.primary{background:#1779ba;color:#fefefe}.label.secondary{background:#767676;color:#fefefe}.label.success{background:#3adb76;color:#0a0a0a}.label.warning{background:#ffae00;color:#0a0a0a}.label.alert{background:#cc4b37;color:#fefefe}.media-object{display:block;margin-bottom:1rem}.media-object img{max-width:none}@media screen and (max-width:39.9375em){.media-object.stack-for-small .media-object-section{padding:0;padding-bottom:1rem;display:block}.media-object.stack-for-small .media-object-section img{width:100%}}.media-object-section{display:table-cell;vertical-align:top}.media-object-section:first-child{padding-right:1rem}.media-object-section:last-child:not(:nth-child(2)){padding-left:1rem}.media-object-section>:last-child{margin-bottom:0}.media-object-section.middle{vertical-align:middle}.media-object-section.bottom{vertical-align:bottom}.is-off-canvas-open{overflow:hidden}.js-off-canvas-overlay{position:absolute;top:0;left:0;width:100%;height:100%;transition:opacity .5s ease,visibility .5s ease;background:hsla(0,0%,100%,.25);opacity:0;visibility:hidden;overflow:hidden}.js-off-canvas-overlay.is-visible{opacity:1;visibility:visible}.js-off-canvas-overlay.is-closable{cursor:pointer}.js-off-canvas-overlay.is-overlay-absolute{position:absolute}.js-off-canvas-overlay.is-overlay-fixed{position:fixed}.off-canvas-wrapper{position:relative;overflow:hidden}.off-canvas{position:fixed;z-index:1;transition:transform .5s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;background:#e6e6e6}[data-whatinput=mouse] .off-canvas{outline:0}.off-canvas.is-transition-overlap{z-index:10}.off-canvas.is-transition-overlap.is-open{box-shadow:0 0 10px hsla(0,0%,4%,.7)}.off-canvas.is-open{transform:translate(0)}.off-canvas-absolute{position:absolute;z-index:1;transition:transform .5s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;background:#e6e6e6}[data-whatinput=mouse] .off-canvas-absolute{outline:0}.off-canvas-absolute.is-transition-overlap{z-index:10}.off-canvas-absolute.is-transition-overlap.is-open{box-shadow:0 0 10px hsla(0,0%,4%,.7)}.off-canvas-absolute.is-open{transform:translate(0)}.position-left{top:0;left:0;width:250px;height:100%;transform:translateX(-250px);overflow-y:auto}.position-left.is-open~.off-canvas-content{transform:translateX(250px)}.position-left.is-transition-push:after{position:absolute;top:0;right:0;height:100%;width:1px;box-shadow:0 0 10px hsla(0,0%,4%,.7);content:" "}.position-left.is-transition-overlap.is-open~.off-canvas-content{transform:none}.position-right{top:0;right:0;width:250px;height:100%;transform:translateX(250px);overflow-y:auto}.position-right.is-open~.off-canvas-content{transform:translateX(-250px)}.position-right.is-transition-push:after{position:absolute;top:0;left:0;height:100%;width:1px;box-shadow:0 0 10px hsla(0,0%,4%,.7);content:" "}.position-right.is-transition-overlap.is-open~.off-canvas-content{transform:none}.position-top{top:0;left:0;width:100%;height:250px;transform:translateY(-250px);overflow-x:auto}.position-top.is-open~.off-canvas-content{transform:translateY(250px)}.position-top.is-transition-push:after{position:absolute;bottom:0;left:0;height:1px;width:100%;box-shadow:0 0 10px hsla(0,0%,4%,.7);content:" "}.position-top.is-transition-overlap.is-open~.off-canvas-content{transform:none}.position-bottom{bottom:0;left:0;width:100%;height:250px;transform:translateY(250px);overflow-x:auto}.position-bottom.is-open~.off-canvas-content{transform:translateY(-250px)}.position-bottom.is-transition-push:after{position:absolute;top:0;left:0;height:1px;width:100%;box-shadow:0 0 10px hsla(0,0%,4%,.7);content:" "}.position-bottom.is-transition-overlap.is-open~.off-canvas-content{transform:none}.off-canvas-content{transition:transform .5s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden}@media print,screen and (min-width:40em){.position-left.reveal-for-medium{transform:none;z-index:1}.position-left.reveal-for-medium~.off-canvas-content{margin-left:250px}.position-right.reveal-for-medium{transform:none;z-index:1}.position-right.reveal-for-medium~.off-canvas-content{margin-right:250px}.position-top.reveal-for-medium{transform:none;z-index:1}.position-top.reveal-for-medium~.off-canvas-content{margin-top:250px}.position-bottom.reveal-for-medium{transform:none;z-index:1}.position-bottom.reveal-for-medium~.off-canvas-content{margin-bottom:250px}}@media print,screen and (min-width:64em){.position-left.reveal-for-large{transform:none;z-index:1}.position-left.reveal-for-large~.off-canvas-content{margin-left:250px}.position-right.reveal-for-large{transform:none;z-index:1}.position-right.reveal-for-large~.off-canvas-content{margin-right:250px}.position-top.reveal-for-large{transform:none;z-index:1}.position-top.reveal-for-large~.off-canvas-content{margin-top:250px}.position-bottom.reveal-for-large{transform:none;z-index:1}.position-bottom.reveal-for-large~.off-canvas-content{margin-bottom:250px}}.orbit,.orbit-container{position:relative}.orbit-container{height:0;margin:0;list-style:none;overflow:hidden}.orbit-slide{width:100%}.orbit-slide.no-motionui.is-active{top:0;left:0}.orbit-figure{margin:0}.orbit-image{width:100%;max-width:100%;margin:0}.orbit-caption{bottom:0;width:100%;margin-bottom:0;background-color:hsla(0,0%,4%,.5)}.orbit-caption,.orbit-next,.orbit-previous{position:absolute;padding:1rem;color:#fefefe}.orbit-next,.orbit-previous{top:50%;transform:translateY(-50%);z-index:10}[data-whatinput=mouse] .orbit-next,[data-whatinput=mouse] .orbit-previous{outline:0}.orbit-next:active,.orbit-next:focus,.orbit-next:hover,.orbit-previous:active,.orbit-previous:focus,.orbit-previous:hover{background-color:hsla(0,0%,4%,.5)}.orbit-previous{left:0}.orbit-next{left:auto;right:0}.orbit-bullets{position:relative;margin-top:.8rem;margin-bottom:.8rem;text-align:center}[data-whatinput=mouse] .orbit-bullets{outline:0}.orbit-bullets button{width:1.2rem;height:1.2rem;margin:.1rem;border-radius:50%;background-color:#cacaca}.orbit-bullets button.is-active,.orbit-bullets button:hover{background-color:#8a8a8a}.pagination{margin-left:0;margin-bottom:1rem}.pagination:after,.pagination:before{display:table;content:" "}.pagination:after{clear:both}.pagination li{margin-right:.0625rem;border-radius:0;font-size:.875rem;display:none}.pagination li:first-child,.pagination li:last-child{display:inline-block}@media print,screen and (min-width:40em){.pagination li{display:inline-block}}.pagination a,.pagination button{display:block;padding:.1875rem .625rem;border-radius:0;color:#0a0a0a}.pagination a:hover,.pagination button:hover{background:#e6e6e6}.pagination .current{padding:.1875rem .625rem;background:#1779ba;color:#fefefe;cursor:default}.pagination .disabled{padding:.1875rem .625rem;color:#cacaca;cursor:not-allowed}.pagination .disabled:hover{background:transparent}.pagination .ellipsis:after{padding:.1875rem .625rem;content:"\2026";color:#0a0a0a}.pagination-previous.disabled:before,.pagination-previous a:before{display:inline-block;margin-right:.5rem;content:"\00ab"}.pagination-next.disabled:after,.pagination-next a:after{display:inline-block;margin-left:.5rem;content:"\00bb"}.progress{height:1rem;margin-bottom:1rem;border-radius:0;background-color:#cacaca}.progress.primary .progress-meter{background-color:#1779ba}.progress.secondary .progress-meter{background-color:#767676}.progress.success .progress-meter{background-color:#3adb76}.progress.warning .progress-meter{background-color:#ffae00}.progress.alert .progress-meter{background-color:#cc4b37}.progress-meter{position:relative;display:block;width:0;height:100%;background-color:#1779ba}.progress-meter-text{top:50%;left:50%;transform:translate(-50%,-50%);position:absolute;margin:0;font-size:.75rem;font-weight:700;color:#fefefe;white-space:nowrap}body.is-reveal-open{overflow:hidden}html.is-reveal-open,html.is-reveal-open body{min-height:100%;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.reveal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1005;display:none;background-color:hsla(0,0%,4%,.45);overflow-y:scroll}.reveal{z-index:1006;-webkit-backface-visibility:hidden;backface-visibility:hidden;display:none;padding:1rem;border:1px solid #cacaca;border-radius:0;background-color:#fefefe;position:relative;top:100px;margin-right:auto;margin-left:auto;overflow-y:auto}[data-whatinput=mouse] .reveal{outline:0}@media print,screen and (min-width:40em){.reveal{min-height:0}}.reveal .column,.reveal .columns{min-width:0}.reveal>:last-child{margin-bottom:0}@media print,screen and (min-width:40em){.reveal{width:600px;max-width:75rem}}@media print,screen and (min-width:40em){.reveal .reveal{right:auto;left:auto;margin:0 auto}}.reveal.collapse{padding:0}@media print,screen and (min-width:40em){.reveal.tiny{width:30%;max-width:75rem}}@media print,screen and (min-width:40em){.reveal.small{width:50%;max-width:75rem}}@media print,screen and (min-width:40em){.reveal.large{width:90%;max-width:75rem}}.reveal.full{top:0;left:0;width:100%;max-width:none;height:100%;height:100vh;min-height:100vh;margin-left:0;border:0;border-radius:0}@media screen and (max-width:39.9375em){.reveal{top:0;left:0;width:100%;max-width:none;height:100%;height:100vh;min-height:100vh;margin-left:0;border:0;border-radius:0}}.reveal.without-overlay{position:fixed}.slider{position:relative;height:.5rem;margin-top:1.25rem;margin-bottom:2.25rem;background-color:#e6e6e6;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:none;touch-action:none}.slider-fill{position:absolute;top:0;left:0;display:inline-block;max-width:100%;height:.5rem;background-color:#cacaca;transition:all .2s ease-in-out}.slider-fill.is-dragging{transition:all 0s linear}.slider-handle{top:50%;transform:translateY(-50%);position:absolute;left:0;z-index:1;display:inline-block;width:1.4rem;height:1.4rem;border-radius:0;background-color:#1779ba;transition:all .2s ease-in-out;-ms-touch-action:manipulation;touch-action:manipulation}[data-whatinput=mouse] .slider-handle{outline:0}.slider-handle:hover{background-color:#14679e}.slider-handle.is-dragging{transition:all 0s linear}.slider.disabled,.slider[disabled]{opacity:.25;cursor:not-allowed}.slider.vertical{display:inline-block;width:.5rem;height:12.5rem;margin:0 1.25rem;transform:scaleY(-1)}.slider.vertical .slider-fill{top:0;width:.5rem;max-height:100%}.slider.vertical .slider-handle{position:absolute;top:0;left:50%;width:1.4rem;height:1.4rem;transform:translateX(-50%)}.sticky,.sticky-container{position:relative}.sticky{z-index:0;transform:translateZ(0)}.sticky.is-stuck{position:fixed;z-index:5}.sticky.is-stuck.is-at-top{top:0}.sticky.is-stuck.is-at-bottom{bottom:0}.sticky.is-anchored{position:relative;right:auto;left:auto}.sticky.is-anchored.is-at-bottom{bottom:0}.switch{height:2rem;position:relative;margin-bottom:1rem;outline:0;font-size:.875rem;font-weight:700;color:#fefefe;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch-input{position:absolute;margin-bottom:0;opacity:0}.switch-paddle{position:relative;display:block;width:4rem;height:2rem;border-radius:0;background:#cacaca;transition:all .25s ease-out;font-weight:inherit;color:inherit;cursor:pointer}input+.switch-paddle{margin:0}.switch-paddle:after{position:absolute;top:.25rem;left:.25rem;display:block;width:1.5rem;height:1.5rem;transform:translateZ(0);border-radius:0;background:#fefefe;transition:all .25s ease-out;content:""}input:checked~.switch-paddle{background:#1779ba}input:checked~.switch-paddle:after{left:2.25rem}[data-whatinput=mouse] input:focus~.switch-paddle{outline:0}.switch-active,.switch-inactive{position:absolute;top:50%;transform:translateY(-50%)}.switch-active{left:8%;display:none}input:checked+label>.switch-active{display:block}.switch-inactive{right:15%}input:checked+label>.switch-inactive{display:none}.switch.tiny{height:1.5rem}.switch.tiny .switch-paddle{width:3rem;height:1.5rem;font-size:.625rem}.switch.tiny .switch-paddle:after{top:.25rem;left:.25rem;width:1rem;height:1rem}.switch.tiny input:checked~.switch-paddle:after{left:1.75rem}.switch.small{height:1.75rem}.switch.small .switch-paddle{width:3.5rem;height:1.75rem;font-size:.75rem}.switch.small .switch-paddle:after{top:.25rem;left:.25rem;width:1.25rem;height:1.25rem}.switch.small input:checked~.switch-paddle:after{left:2rem}.switch.large{height:2.5rem}.switch.large .switch-paddle{width:5rem;height:2.5rem;font-size:1rem}.switch.large .switch-paddle:after{top:.25rem;left:.25rem;width:2rem;height:2rem}.switch.large input:checked~.switch-paddle:after{left:2.75rem}table{width:100%;margin-bottom:1rem;border-radius:0}table tbody,table tfoot,table thead{border:1px solid #f1f1f1;background-color:#fefefe}table caption{padding:.5rem .625rem .625rem;font-weight:700}table thead{background:#f8f8f8;color:#0a0a0a}table tfoot{background:#f1f1f1;color:#0a0a0a}table tfoot tr,table thead tr{background:transparent}table tfoot td,table tfoot th,table thead td,table thead th{padding:.5rem .625rem .625rem;font-weight:700;text-align:left}table tbody td,table tbody th{padding:.5rem .625rem .625rem}table tbody tr:nth-child(even){border-bottom:0;background-color:#f1f1f1}table.unstriped tbody{background-color:#fefefe}table.unstriped tbody tr{border-bottom:0;border-bottom:1px solid #f1f1f1;background-color:#fefefe}@media screen and (max-width:63.9375em){table.stack tfoot,table.stack thead{display:none}table.stack td,table.stack th,table.stack tr{display:block}table.stack td{border-top:0}}table.scroll{display:block;width:100%;overflow-x:auto}table.hover thead tr:hover{background-color:#f3f3f3}table.hover tfoot tr:hover{background-color:#ececec}table.hover tbody tr:hover{background-color:#f9f9f9}table.hover:not(.unstriped) tr:nth-of-type(even):hover{background-color:#ececec}.table-scroll{overflow-x:auto}.table-scroll table{width:auto}.tabs{margin:0;border:1px solid #e6e6e6;background:#fefefe;list-style-type:none}.tabs:after,.tabs:before{display:table;content:" "}.tabs:after{clear:both}.tabs.vertical>li{display:block;float:none;width:auto}.tabs.simple>li>a{padding:0}.tabs.simple>li>a:hover{background:transparent}.tabs.primary{background:#1779ba}.tabs.primary>li>a{color:#fefefe}.tabs.primary>li>a:focus,.tabs.primary>li>a:hover{background:#1673b1}.tabs-title{float:left}.tabs-title>a{display:block;padding:1.25rem 1.5rem;font-size:.75rem;line-height:1;color:#1779ba}.tabs-title>a:hover{background:#fefefe;color:#1468a0}.tabs-title>a:focus,.tabs-title>a[aria-selected=true]{background:#e6e6e6;color:#1779ba}.tabs-content{border:1px solid #e6e6e6;border-top:0;background:#fefefe;color:#0a0a0a;transition:all .5s ease}.tabs-content.vertical{border:1px solid #e6e6e6;border-left:0}.tabs-panel{display:none;padding:1rem}.tabs-panel[aria-hidden=false]{display:block}.thumbnail{display:inline-block;max-width:100%;margin-bottom:1rem;border:4px solid #fefefe;border-radius:0;box-shadow:0 0 0 1px hsla(0,0%,4%,.2);line-height:0}a.thumbnail{transition:box-shadow .2s ease-out}a.thumbnail:focus,a.thumbnail:hover{box-shadow:0 0 6px 1px rgba(23,121,186,.5)}a.thumbnail image{box-shadow:none}.title-bar{padding:.5rem;background:#0a0a0a;color:#fefefe}.title-bar:after,.title-bar:before{display:table;content:" "}.title-bar:after{clear:both}.title-bar .menu-icon{margin-left:.25rem;margin-right:.25rem}.title-bar-left{float:left}.title-bar-right{float:right;text-align:right}.title-bar-title{vertical-align:middle}.has-tip,.title-bar-title{display:inline-block;font-weight:700}.has-tip{position:relative;border-bottom:1px dotted #8a8a8a;cursor:help}.tooltip{position:absolute;top:calc(100% + .6495rem);z-index:1200;max-width:10rem;padding:.75rem;border-radius:0;background-color:#0a0a0a;font-size:80%;color:#fefefe}.tooltip:before{border:.75rem inset;border-top-width:0;border-bottom-style:solid;border-color:transparent transparent #0a0a0a;position:absolute;bottom:100%;left:50%;transform:translateX(-50%)}.tooltip.top:before,.tooltip:before{display:block;width:0;height:0;content:""}.tooltip.top:before{border:.75rem inset;border-bottom-width:0;border-top-style:solid;border-color:#0a0a0a transparent transparent;top:100%;bottom:auto}.tooltip.left:before{border:.75rem inset;border-right-width:0;border-left-style:solid;border-color:transparent transparent transparent #0a0a0a;left:100%}.tooltip.left:before,.tooltip.right:before{display:block;width:0;height:0;content:"";top:50%;bottom:auto;transform:translateY(-50%)}.tooltip.right:before{border:.75rem inset;border-left-width:0;border-right-style:solid;border-color:transparent #0a0a0a transparent transparent;right:100%;left:auto}.top-bar{padding:.5rem}.top-bar:after,.top-bar:before{display:table;content:" "}.top-bar:after{clear:both}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar input{max-width:200px;margin-right:1rem}.top-bar .input-group-field{width:100%;margin-right:0}.top-bar input.button{width:auto}.top-bar .top-bar-left,.top-bar .top-bar-right{width:100%}@media print,screen and (min-width:40em){.top-bar .top-bar-left,.top-bar .top-bar-right{width:auto}}@media screen and (max-width:63.9375em){.top-bar.stacked-for-medium .top-bar-left,.top-bar.stacked-for-medium .top-bar-right{width:100%}}@media screen and (max-width:74.9375em){.top-bar.stacked-for-large .top-bar-left,.top-bar.stacked-for-large .top-bar-right{width:100%}}.top-bar-title{display:inline-block;float:left;padding:.5rem 1rem .5rem 0}.top-bar-title .menu-icon{bottom:2px}.top-bar-left{float:left}.top-bar-right{float:right}.hide{display:none!important}.invisible{visibility:hidden}@media screen and (max-width:39.9375em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:40em){.show-for-small-only{display:none!important}}@media print,screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.9375em){.show-for-medium{display:none!important}}@media screen and (min-width:40em) and (max-width:63.9375em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.9375em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media print,screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.9375em){.show-for-large{display:none!important}}@media screen and (min-width:64em) and (max-width:74.9375em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.9375em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.show-on-focus:active,.show-on-focus:focus{position:static!important;width:auto;height:auto;overflow:visible;clip:auto}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:landscape){.hide-for-landscape,.show-for-portrait{display:none!important}}@media screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:block!important}}.float-left{float:left!important}.float-right{float:right!important}.float-center{display:block;margin-right:auto;margin-left:auto}.clearfix:after,.clearfix:before{display:table;content:" "}.clearfix:after{clear:both}.slide-in-down.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:translateY(-100%);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-down.mui-enter.mui-enter-active{transform:translateY(0)}.slide-in-left.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:translateX(-100%);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-left.mui-enter.mui-enter-active{transform:translateX(0)}.slide-in-up.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:translateY(100%);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-up.mui-enter.mui-enter-active{transform:translateY(0)}.slide-in-right.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:translateX(100%);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-in-right.mui-enter.mui-enter-active{transform:translateX(0)}.slide-out-down.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:translateY(0);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-down.mui-leave.mui-leave-active{transform:translateY(100%)}.slide-out-right.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:translateX(0);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-right.mui-leave.mui-leave-active{transform:translateX(100%)}.slide-out-up.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:translateY(0);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-up.mui-leave.mui-leave-active{transform:translateY(-100%)}.slide-out-left.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:translateX(0);transition-property:transform,opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}.slide-out-left.mui-leave.mui-leave-active{transform:translateX(-100%)}.fade-in.mui-enter{transition-duration:.5s;transition-timing-function:linear;opacity:0;transition-property:opacity}.fade-in.mui-enter.mui-enter-active{opacity:1}.fade-out.mui-leave{transition-duration:.5s;transition-timing-function:linear;opacity:1;transition-property:opacity}.fade-out.mui-leave.mui-leave-active{opacity:0}.hinge-in-from-top.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotateX(-90deg);transform-origin:top;transition-property:transform,opacity;opacity:0}.hinge-in-from-top.mui-enter.mui-enter-active{transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-right.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotateY(-90deg);transform-origin:right;transition-property:transform,opacity;opacity:0}.hinge-in-from-right.mui-enter.mui-enter-active{transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-bottom.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotateX(90deg);transform-origin:bottom;transition-property:transform,opacity;opacity:0}.hinge-in-from-bottom.mui-enter.mui-enter-active{transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-left.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotateY(90deg);transform-origin:left;transition-property:transform,opacity;opacity:0}.hinge-in-from-left.mui-enter.mui-enter-active{transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-middle-x.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotateX(-90deg);transform-origin:center;transition-property:transform,opacity;opacity:0}.hinge-in-from-middle-x.mui-enter.mui-enter-active{transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-in-from-middle-y.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotateY(-90deg);transform-origin:center;transition-property:transform,opacity;opacity:0}.hinge-in-from-middle-y.mui-enter.mui-enter-active,.hinge-out-from-top.mui-leave{transform:perspective(2000px) rotate(0deg);opacity:1}.hinge-out-from-top.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform-origin:top;transition-property:transform,opacity}.hinge-out-from-top.mui-leave.mui-leave-active{transform:perspective(2000px) rotateX(-90deg);opacity:0}.hinge-out-from-right.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotate(0deg);transform-origin:right;transition-property:transform,opacity;opacity:1}.hinge-out-from-right.mui-leave.mui-leave-active{transform:perspective(2000px) rotateY(-90deg);opacity:0}.hinge-out-from-bottom.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotate(0deg);transform-origin:bottom;transition-property:transform,opacity;opacity:1}.hinge-out-from-bottom.mui-leave.mui-leave-active{transform:perspective(2000px) rotateX(90deg);opacity:0}.hinge-out-from-left.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotate(0deg);transform-origin:left;transition-property:transform,opacity;opacity:1}.hinge-out-from-left.mui-leave.mui-leave-active{transform:perspective(2000px) rotateY(90deg);opacity:0}.hinge-out-from-middle-x.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotate(0deg);transform-origin:center;transition-property:transform,opacity;opacity:1}.hinge-out-from-middle-x.mui-leave.mui-leave-active{transform:perspective(2000px) rotateX(-90deg);opacity:0}.hinge-out-from-middle-y.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:perspective(2000px) rotate(0deg);transform-origin:center;transition-property:transform,opacity;opacity:1}.hinge-out-from-middle-y.mui-leave.mui-leave-active{transform:perspective(2000px) rotateY(-90deg);opacity:0}.scale-in-up.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:scale(.5);transition-property:transform,opacity;opacity:0}.scale-in-up.mui-enter.mui-enter-active{transform:scale(1);opacity:1}.scale-in-down.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:scale(1.5);transition-property:transform,opacity;opacity:0}.scale-in-down.mui-enter.mui-enter-active,.scale-out-up.mui-leave{transform:scale(1);opacity:1}.scale-out-up.mui-leave{transition-duration:.5s;transition-timing-function:linear;transition-property:transform,opacity}.scale-out-up.mui-leave.mui-leave-active{transform:scale(1.5);opacity:0}.scale-out-down.mui-leave{transition-duration:.5s;transition-timing-function:linear;transform:scale(1);transition-property:transform,opacity;opacity:1}.scale-out-down.mui-leave.mui-leave-active{transform:scale(.5);opacity:0}.spin-in.mui-enter{transition-duration:.5s;transition-timing-function:linear;transform:rotate(-270deg);transition-property:transform,opacity;opacity:0}.spin-in.mui-enter.mui-enter-active,.spin-out.mui-leave{transform:rotate(0);opacity:1}.spin-out.mui-leave{transition-duration:.5s;transition-timing-function:linear;transition-property:transform,opacity}.spin-in-ccw.mui-enter,.spin-out.mui-leave.mui-leave-active{transform:rotate(270deg);opacity:0}.spin-in-ccw.mui-enter{transition-duration:.5s;transition-timing-function:linear;transition-property:transform,opacity}.spin-in-ccw.mui-enter.mui-enter-active,.spin-out-ccw.mui-leave{transform:rotate(0);opacity:1}.spin-out-ccw.mui-leave{transition-duration:.5s;transition-timing-function:linear;transition-property:transform,opacity}.spin-out-ccw.mui-leave.mui-leave-active{transform:rotate(-270deg);opacity:0}.slow{transition-duration:.75s!important}.fast{transition-duration:.25s!important}.linear{transition-timing-function:linear!important}.ease{transition-timing-function:ease!important}.ease-in{transition-timing-function:ease-in!important}.ease-out{transition-timing-function:ease-out!important}.ease-in-out{transition-timing-function:ease-in-out!important}.bounce-in{transition-timing-function:cubic-bezier(.485,.155,.24,1.245)!important}.bounce-out{transition-timing-function:cubic-bezier(.485,.155,.515,.845)!important}.bounce-in-out{transition-timing-function:cubic-bezier(.76,-.245,.24,1.245)!important}.short-delay{transition-delay:.3s!important}.long-delay{transition-delay:.7s!important}.shake{animation-name:a}@keyframes a{0%,10%,20%,30%,40%,50%,60%,70%,80%,90%{transform:translateX(7%)}5%,15%,25%,35%,45%,55%,65%,75%,85%,95%{transform:translateX(-7%)}}.spin-ccw,.spin-cw{animation-name:b}@keyframes b{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.wiggle{animation-name:c}@keyframes c{40%,50%,60%{transform:rotate(7deg)}35%,45%,55%,65%{transform:rotate(-7deg)}0%,30%,70%,to{transform:rotate(0)}}.shake,.spin-ccw,.spin-cw,.wiggle{animation-duration:.5s}.infinite{animation-iteration-count:infinite}.slow{animation-duration:.75s!important}.fast{animation-duration:.25s!important}.linear{animation-timing-function:linear!important}.ease{animation-timing-function:ease!important}.ease-in{animation-timing-function:ease-in!important}.ease-out{animation-timing-function:ease-out!important}.ease-in-out{animation-timing-function:ease-in-out!important}.bounce-in{animation-timing-function:cubic-bezier(.485,.155,.24,1.245)!important}.bounce-out{animation-timing-function:cubic-bezier(.485,.155,.515,.845)!important}.bounce-in-out{animation-timing-function:cubic-bezier(.76,-.245,.24,1.245)!important}.short-delay{animation-delay:.3s!important}.long-delay{animation-delay:.7s!important} -------------------------------------------------------------------------------- /presentation.md: -------------------------------------------------------------------------------- 1 | class: center, middle 2 | # APEX 18.1 "hidden" features 3 | 4 | **Marko Gorički** 5 | 6 | [@mgoricki](https://twitter.com/mgoricki) 7 | 8 | mgoricki8@gmail.com 9 | 10 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 11 | 12 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 13 | 14 | 15 | --- 16 | 17 | class: center, middle 18 | count: false 19 | # APEX ~~18.1~~ "hidden" features 20 | 21 | **Marko Gorički** 22 | 23 | [@mgoricki](https://twitter.com/mgoricki) 24 | 25 | mgoricki8@gmail.com 26 | 27 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 28 | 29 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 30 | 31 | --- 32 | 33 | class: center, middle 34 | count: false 35 | # APEX ~~18.1~~ ~~"hidden"~~ features 36 | 37 | **Marko Gorički** 38 | 39 | [@mgoricki](https://twitter.com/mgoricki) 40 | 41 | mgoricki8@gmail.com 42 | 43 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 44 | 45 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 46 | 47 | --- 48 | 49 | class: center, middle 50 | count: false 51 | # APEX ~~18.1~~ ~~"hidden"~~ ~~features~~ 52 | 53 | **Marko Gorički** 54 | 55 | [@mgoricki](https://twitter.com/mgoricki) 56 | 57 | mgoricki8@gmail.com 58 | 59 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 60 | 61 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 62 | 63 | --- 64 | 65 | class: center, middle 66 | count: false 67 | # APEX APIs 68 | 69 | **Marko Gorički** 70 | 71 | [@mgoricki](https://twitter.com/mgoricki) 72 | 73 | mgoricki8@gmail.com 74 | 75 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 76 | 77 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 78 | 79 | --- 80 | 81 | class: center, middle 82 | count: false 83 | # APEX PL/SQL APIs 84 | 85 | **Marko Gorički** 86 | 87 | [@mgoricki](https://twitter.com/mgoricki) 88 | 89 | mgoricki8@gmail.com 90 | 91 | [https://github.com/mgoricki/](https://github.com/mgoricki/) 92 | 93 | APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 94 | 95 | 96 | --- 97 | 98 | # About Me 99 | 100 | - Software Consultant @ BiLog (Croatia) 101 | - More than 10 years of experience with APEX 102 | - Presenter at HROUG, SIOUG, APEX World, KSCOPE, APEX Alpe Adria ([https://www.aaapeks.info](https://www.aaapeks.info)),
APEX Connect 103 | - [apex.world](http://apex.world) Member of the year 2017 (and month November 2017) 104 | - APEX related blog - [apexbyg.blogspot.com](http://apexbyg.blogspot.com) 105 | - [https://github.com/mgoricki/](https://github.com/mgoricki/) 106 | - [@mgoricki](https://twitter.com/mgoricki) 107 | - mgoricki8@gmail.com 108 | 109 | .myPhoto[![Marko Gorički](./img/slika.jpg)] 110 | --- 111 | 112 | # BiLog 113 | 114 | - Software development company focused on consulting and business solution development 115 | - Technology focus Oracle (APEX) 116 | - Forms > APEX migrations, APEX educations, consulting, plugin development 117 | - Our APEX solutions: 118 | - HR management software 119 | - Regulatory reporting for insurance 120 | - Reinsurance 121 | - GDPR 122 | 123 | .bilogWeb[![BiLog Web](./img/bilogWeb.png)] 124 | 125 | --- 126 | 127 | # Agenda 128 | 129 | - New APEX 18.* PL/SQL APIs and features: 130 | - Session 131 | - Application Settings 132 | - ACL 133 | - Export 134 | - Mail templates 135 | - Dynamically Set Parsing Schema 136 | - APEX 5.* APIs and features 137 | - Session Cloning 138 | - APEX URL 139 | - APEX String 140 | - Other APIs 141 | 142 | 143 | --- 144 | 145 | class: center, middle 146 | 147 | # Why to use APEX APIs? 148 | 149 | --- 150 | exclude: true 151 | 152 | # Why to use APEX APIs? 153 | 154 | - Example 1: 155 | 156 | ```javascript 157 | /* not OK: */ 158 | $('#P11_ITEM1,label[for=P11_ITEM1]').hide(); 159 | 160 | /* OK: */ 161 | apex.item('P11_ITEM1').hide(); 162 | ``` 163 | 164 | - Example 2: 165 | 166 | ```javascript 167 | /* not OK: */ 168 | /* not OK: */ 169 | $('#P11_ITEM2').val(); 170 | 171 | /* OK: */ 172 | apex.item('P11_ITEM2').getValue(); 173 | ``` 174 | - [Demo](http://localhost:8080/ords/f?p=114:11) 175 | 176 | ??? 177 | 178 | - example with select list > popup LOV 179 | 180 | --- 181 | 182 | # Where to start? 183 | 184 | - APEX documentation 185 | - [apex.oracle.com/doc182](https://apex.oracle.com/doc182) 186 | - [Release Notes](https://docs.oracle.com/database/apex-18.1/HTMRN/toc.htm#HTMRN-GUID-540B73CB-08A7-4422-B6BF-CC785EC47694) / New Features 187 | - [Changes in this release](https://docs.oracle.com/database/apex-18.2/AEAPI/changes-in-this-release.htm#AEAPI29121) 188 | - Sample Applications 189 | - [#orclapex](https://twitter.com/hashtag/orclapex?src=tren) 190 | - Blogs 191 | - [https://github.com/Dani3lSun/awesome-orclapex](https://github.com/Dani3lSun/awesome-orclapex) 192 | - [apex.oracle.com/shortcuts](https://apex.oracle.com/shortcuts) 193 | 194 | 195 | 196 | --- 197 | 198 | # APEX_SESSION package 199 | 200 | - **set_debug** and **set_trace** available from 5.1 201 | - New in 18.1: 202 | - **create_session** 203 | - **attach** 204 | - **delete_session** 205 | - **detach** 206 | 207 | ## SET_DEBUG 208 | 209 | - sets debug level for all future requests in a session. 210 | - 7 levels ([constants](https://docs.oracle.com/database/apex-18.1/AEAPI/Constants-2.htm#AEAPI29184)): 211 | - 1 - error 212 | - 2 - warning 213 | - 4 - info (default) - same as YES 214 | - 5 - app_enter 215 | - 6 - app_trace 216 | - 8 - engine_enter 217 | - 9 - engine_trace 218 | 219 | ```sql 220 | begin 221 | apex_session.set_debug ( 222 | p_session_id => :APP_SESSION, 223 | p_level => apex_debug.c_log_level_info); 224 | commit; -- DON'T FORGET TO COMMIT!!!! 225 | end; 226 | / 227 | ``` 228 | 229 | ## SET_TRACE 230 | 231 | - sets trace mode in all future requests of a session 232 | 233 | ```sql 234 | begin 235 | apex_session.set_trace ( 236 | p_session_id => :APP_SESSION, 237 | p_level => 'SQL'); 238 | commit; -- DON'T FORGET TO COMMIT!!!! 239 | end; 240 | / 241 | ``` 242 | 243 | ```sql 244 | -- active sessions view 245 | select * 246 | from apex_workspace_sessions 247 | where workspace_name = :WORKSPACE 248 | and user_name = nvl(:USER, user_name); 249 | 250 | -- activity log view 251 | select * 252 | from apex_activity_log 253 | where session_id = :APP_SESSION 254 | order by time_stamp desc; 255 | 256 | -- debug messages view 257 | select * 258 | from apex_debug_messages 259 | where application_id = 114 260 | and session_id = :APP_SESSION; 261 | ``` 262 | 263 | ## Create Session 264 | 265 | - creates a new session for the given application, sets environment and runs **the Initialization PL/SQL Code**. 266 | 267 | ```sql 268 | begin 269 | apex_util.set_workspace(:WORKSPACE_NAME); 270 | apex_session.create_session (p_app_id => 114 271 | , p_page_id => 1 272 | , p_username => 'DEMO'); 273 | end; 274 | / 275 | 276 | -- test variables 277 | select v('APP_ID') as app_id 278 | , v('APP_SESSION') as app_session 279 | , v('APP_USER') as app_user 280 | , apex_page.get_url as get_url 281 | from dual; 282 | ``` 283 | 284 | ## Attach Session 285 | 286 | - sets environment and runs the **Initialization PL/SQL Code** 287 | 288 | ```sql 289 | begin 290 | apex_session.attach(p_app_id => 114 291 | , p_page_id => 3 292 | , p_session_id => :APP_SESSION); 293 | end; 294 | / 295 | ``` 296 | 297 | ## Delete/Detach Session 298 | - calls application's **Cleanup PL/SQL Code** and reset the environment 299 | - apex_session.detach - same as delete session but no parameter 300 | 301 | ```sql 302 | begin 303 | -- p_session_id is optional paarmeter - with null same as detach 304 | apex_session.delete_session (p_session_id => :APP_SESSION); 305 | end; 306 | / 307 | ``` 308 | 309 | ## Links 310 | - [Documentation 18.2](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_SESSION.htm) 311 | - before APEX 18.1 you could use OraOpenSource's [OOS Utils](https://oos-utils.readthedocs.io/en/latest/oos_util_apex/) 312 | 313 | --- 314 | 315 | # Application Settings 316 | 317 | - No more need for simple key-value configuration tables 318 | - Key feature: **On Upgrade Keep Value** 319 | - **API package**: apex_app_settings (get_value/set_value) 320 | - **dictionary view**: apex_application_settings 321 | 322 | ## GET_VALUE 323 | 324 | - gets the application setting value 325 | 326 | ```sql 327 | -- before use, not enough to just set workspace (security_group_id) 328 | exec apex_util.set_workspace(:WORKSPACE); 329 | 330 | -- you need to create or attach to session if used outside APEX session 331 | begin 332 | apex_session.create_session (p_app_id => 114 333 | , p_page_id => 1 334 | , p_username => :USER); 335 | end; 336 | / 337 | 338 | -- get_value example 339 | select name 340 | , apex_app_setting.get_value(p_name => name) as val 341 | , on_upgrade_keep_value 342 | from apex_application_settings 343 | where application_id = 114; 344 | ``` 345 | 346 | ## SET_VALUE 347 | 348 | - changes the application setting value 349 | - also needs APEX session 350 | 351 | ```sql 352 | begin 353 | apex_app_setting.set_value ( 354 | p_name => 'REPORT_SERVER' 355 | ,p_value => '10.11.12.13:9080/jasperserver/'); 356 | commit; -- DON'T FORGET TO COMMIT 357 | end; 358 | / 359 | ``` 360 | 361 | ## Links 362 | - [Documentation 18.2](https://docs.oracle.com/database/apex-18.1/AEAPI/APEX_APP_SETTING.htm) 363 | 364 | --- 365 | 366 | # Application Access Control (ACL) 367 | 368 | - Developers define roles and assign users to roles 369 | - Control access to pages and components with Authorization Schemes 370 | - **dictionary views**: 371 | - apex_appl_acl_roles 372 | - apex_appl_acl_users 373 | - apex_appl_acl_user_roles 374 | - **API package**: apex_acl 375 | - add_user_role 376 | - add_user_roles 377 | - remove_user_role 378 | - remove_all_user_roles 379 | - replace_user_roles 380 | - has_user_role 381 | - has_user_any_roles 382 | - can create administration page through features (also new feature) 383 | - procedures are overloaded - you can use role_id or role_static_id 384 | 385 | ## ADD_USER_ROLE 386 | 387 | - adds role to the user 388 | 389 | ```sql 390 | begin 391 | apex_util.set_workspace(:WORKSPACE); 392 | apex_acl.add_user_role ( 393 | -- assigns a role to a user 394 | p_application_id => 114 -- default wwv_flow_security.g_flow_id 395 | ,p_user_name => :USER 396 | ,p_role_static_id => 'READER' -- other proc with p_role_id 397 | ); 398 | commit; 399 | end; 400 | / 401 | ``` 402 | 403 | ## REMOVE_USER_ROLE 404 | 405 | - removes an assigned role from a user 406 | 407 | ```sql 408 | begin 409 | apex_util.set_workspace(:WORKSPACE); 410 | apex_acl.remove_user_role ( 411 | p_application_id => 114, -- default wwv_flow_security.g_flow_id, 412 | p_user_name => :USER, 413 | p_role_static_id => 'READER' 414 | ); 415 | commit; 416 | end; 417 | / 418 | ``` 419 | 420 | ## ADD_USER_ROLES 421 | 422 | - adds multiple roles to the user 423 | 424 | ```sql 425 | begin 426 | apex_util.set_workspace(:WORKSPACE); 427 | apex_acl.add_user_roles( 428 | -- assigns an array of roles to a user 429 | p_application_id => 114, 430 | p_user_name => :USER, 431 | p_role_static_ids => apex_t_varchar2('READER', 'ADMINISTRATOR') 432 | ); 433 | commit; 434 | end; 435 | / 436 | ``` 437 | 438 | 439 | ## REPLACE_USER_ROLES 440 | 441 | - replaces any existing assigned roles to new array of roles 442 | 443 | ```sql 444 | begin 445 | apex_util.set_workspace(:WORKSPACE); 446 | apex_acl.replace_user_roles ( 447 | p_application_id => 114, -- default wwv_flow_security.g_flow_id, 448 | p_user_name => :USER, 449 | p_role_static_ids => apex_string.split('ADMINISTRATOR:CONTRIBUTOR', ':')); 450 | end; 451 | / 452 | ``` 453 | 454 | ## REMOVE_ALL_USER_ROLES 455 | 456 | - removes all assigned roles from a user 457 | 458 | ```sql 459 | begin 460 | apex_util.set_workspace(:WORKSPACE); 461 | apex_acl.remove_all_user_roles( 462 | p_application_id => '114', --default wwv_flow_security.g_flow_id, 463 | p_user_name => :USER); 464 | commit; 465 | end; 466 | / 467 | ``` 468 | 469 | ## USER_HAS_ROLE 470 | 471 | - checks if user has specific role 472 | 473 | ```sql 474 | begin 475 | apex_util.set_workspace(:WORKSPACE); 476 | if apex_acl.has_user_role(p_application_id => :APP_ID 477 | , p_user_name => :USER 478 | , p_role_static_id => 'READER') then 479 | dbms_output.put_line('OK'); 480 | else 481 | dbms_output.put_line('NOT OK'); 482 | end if; 483 | end; 484 | / 485 | ``` 486 | 487 | ## HAS_USER_ANY_ROLES 488 | 489 | - checks if user has any role 490 | 491 | ```sql 492 | begin 493 | apex_util.set_workspace('SIOUG2018'); 494 | if apex_acl.has_user_any_roles (p_application_id => :APP_ID 495 | , p_user_name => :USER) then 496 | dbms_output.put_line('OK'); 497 | else 498 | dbms_output.put_line('NOT OK'); 499 | end if; 500 | end; 501 | / 502 | ``` 503 | 504 | ## Links 505 | - [Documentation 18.2](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_ACL.htm) 506 | 507 | --- 508 | 509 | # APEX Export 510 | 511 | - can be done in APEX Builder, with Java Utility or SQLcl 512 | - can export the app definitions, files, feedback, and workspaces to text files as CLOBs 513 | - available from APEX 5.1 (but not documented) 514 | - uses utility types APEX_T_EXPORT_FILE and APEX_T_EXPORT_FILES 515 | 516 | ```sql 517 | -- APEX_T_EXPORT_FILE 518 | create or replace type wwv_flow_t_export_file force is object ( 519 | name varchar2(255), 520 | contents clob 521 | ) 522 | 523 | -- APEX_T_EXPORT_FILES 524 | create or replace type wwv_flow_t_export_files is table of wwv_flow_t_export_file 525 | ``` 526 | 527 | ## GET_APPLICATION 528 | 529 | - Definition: 530 | 531 | ```sql 532 | function get_application ( 533 | p_application_id in number, 534 | p_split in boolean default false, 535 | p_with_date in boolean default false, 536 | p_with_ir_public_reports in boolean default false, 537 | p_with_ir_private_reports in boolean default false, 538 | p_with_ir_notifications in boolean default false, 539 | p_with_translations in boolean default false, 540 | p_with_pkg_app_mapping in boolean default false, 541 | p_with_original_ids in boolean default false, 542 | p_with_no_subscriptions in boolean default false, 543 | p_with_comments in boolean default false, 544 | p_with_supporting_objects in varchar2 default null, 545 | p_with_acl_assignments in boolean default false -- you can export ACL assignments 546 | ) 547 | return wwv_flow_t_export_files; 548 | ``` 549 | 550 | - Example: 551 | 552 | ```sql 553 | -- get application 554 | declare 555 | v_apex_export_files apex_t_export_files; 556 | begin 557 | v_apex_export_files := apex_export.get_application(:APP_ID 558 | -- , p_with_acl_assignments => true 559 | ); 560 | dbms_output.put_line(v_apex_export_files(1).name); 561 | dbms_output.put_line(length(v_apex_export_files(1).contents)); 562 | end; 563 | / 564 | ``` 565 | 566 | 567 | ## Split Application 568 | ```sql 569 | declare 570 | v_apex_export_files apex_t_export_files; -- table of apex_t_export_file 571 | v_app_exp_file blob; 572 | begin 573 | v_apex_export_files := apex_export.get_application(:APP_ID 574 | , p_split => true 575 | ); 576 | for i in v_apex_export_files.first..v_apex_export_files.last 577 | loop 578 | dbms_output.put_line(v_apex_export_files(i).name); 579 | end loop; 580 | end; 581 | / 582 | ``` 583 | 584 | ## Other Functions 585 | - **get_feedback** - exports user feedback 586 | 587 | ```sql 588 | function get_feedback ( 589 | p_workspace_id in number, 590 | p_with_date in boolean default false, 591 | p_since in date default null, 592 | p_deployment_system in varchar2 default null ) 593 | return wwv_flow_t_export_files; 594 | ``` 595 | 596 | - **get_workspace** - exports the given workspace's definition and users 597 | 598 | ```sql 599 | function get_workspace ( 600 | p_workspace_id in number, 601 | p_with_date in boolean default false, 602 | p_with_team_development in boolean default false, 603 | p_with_misc in boolean default false -- include data from SQL Workshop, mail logs, etc. in the export. 604 | ) 605 | return wwv_flow_t_export_files; 606 | ``` 607 | 608 | - **get_workspace_files** - exports the given workspace's static files 609 | 610 | ```sql 611 | function get_workspace_files ( 612 | p_workspace_id in number, 613 | p_with_date in boolean default false ) 614 | return wwv_flow_t_export_files; 615 | ``` 616 | 617 | ## Links 618 | 619 | - [Demo](http://localhost:8080/ords/f?p=114:16) 620 | - [Documentation](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_EXPORT.htm) 621 | 622 | 623 | 624 | 625 | --- 626 | 627 | # APEX Mail Templates 628 | 629 | - new feature in APEX 18.1 (Shared Components > Email Templates) 630 | - API package: apex_mail - (2 new procedures and one function): 631 | - send (procedure and function) 632 | - prepare_template procedure 633 | 634 | - **dictionary views** 635 | - apex_mail_log 636 | - apex_mail_queue 637 | - apex_mail_attachments 638 | 639 | ## SEND procedure 640 | 641 | - new template_static_id parameter 642 | 643 | ```sql 644 | declare 645 | v_placeholders clob; 646 | begin 647 | apex_util.set_workspace('SIOUG2018'); 648 | apex_json.initialize_clob_output; 649 | apex_json.open_object; 650 | 651 | apex_json.write('EVENT_NAME' , 'MakeIT 2018'); 652 | apex_json.write('EVENT_DATE' , '15.10.2018.'); 653 | apex_json.write('EVENT_LINK' , 'www.makeIT.si'); 654 | apex_json.write('DURATION' , '2 days'); 655 | apex_json.write('INVITEE' , 'Marko Gorički'); 656 | apex_json.write('ORGANIZER' , 'SIOUG'); 657 | apex_json.write('LOCATION' , 'Portorož'); 658 | apex_json.write('MY_APPLICATION_LINK', 'www.makeIT.si'); 659 | apex_json.write('NOTES' , 'n/a'); 660 | apex_json.write('URL_LINK' , 'n/a'); 661 | apex_json.write('URL_NAME' , 'n/a'); 662 | apex_json.write('START_TIME' , '15.10.2018.'); 663 | 664 | apex_json.close_object; 665 | v_placeholders := apex_json.get_clob_output; 666 | apex_json.free_output; 667 | 668 | apex_mail.send ( 669 | p_template_static_id => 'EVENT' 670 | , p_placeholders => v_placeholders 671 | , p_to => 'marko.goricki@bilog.hr' 672 | ); 673 | apex_mail.push_queue; 674 | end; 675 | / 676 | ``` 677 | 678 | - [Demo on apex.oracle.com](https://apex.oracle.com/pls/apex/f?p=93889:2) 679 | 680 | 681 | ## SEND function 682 | 683 | - same as send functions but returns mail_id (used for adding atachements) 684 | 685 | ## PREPARE_TEMPLATE procedure 686 | 687 | - returns a formatted mail based on an e-mail template where the placeholders specified as json string are substituted 688 | 689 | ```sql 690 | procedure prepare_template ( 691 | p_static_id in varchar2, 692 | p_placeholders in clob, 693 | p_application_id in number default wwv_flow_security.g_flow_id, 694 | p_subject out varchar2, 695 | p_html out clob, 696 | p_text out clob); 697 | ``` 698 | 699 | ## Links 700 | 701 | - [Documentation](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_MAIL.htm) 702 | 703 | 704 | --- 705 | 706 | 707 | # Dynamically Set Parsing Schema 708 | - change the parsing user for the current page view to another workspace schema 709 | - can only call it from Initialization PL/SQL Code 710 | 711 | ```sql 712 | begin 713 | apex_util.set_parsing_schema_for_request ( 714 | p_schema => :SCHEMA 715 | ); 716 | end; 717 | / 718 | ``` 719 | 720 | ## Example 721 | 722 | ```sql 723 | if :APP_PAGE_ID between 1 and 100 then 724 | apex_util.set_parsing_schema_for_request ( 725 | p_schema => :G_PARSING_SCHEMA ); 726 | end if; 727 | ``` 728 | 729 | ## Links 730 | 731 | - [Demo](http://localhost:8080/ords/f?p=114:14) 732 | - [Documentation](https://docs.oracle.com/database/apex-18.1/AEAPI/SET_PARSING_SCHEMA_FOR_REQUEST-Procedure.htm) 733 | 734 | ??? 735 | 736 | Multi-tenancy is an architecture in which a single instance of a software application serves multiple customers. Each customer is called a tenant. Tenants may be given the ability to customize some parts of the application, such as color of the user interface (UI) or business rules, but they cannot customize the application's code. 737 | 738 | --- 739 | 740 | # Session Cloning 741 | 742 | - before using it, you have to enable it with **sys** user or **apex_administrator_role** user: 743 | 744 | ```sql 745 | grant apex_administrator_role to sioug2018; 746 | ``` 747 | 748 | ```sql 749 | begin 750 | apex_instance_admin.set_parameter( 751 | p_parameter => 'CLONE_SESSION_ENABLED', 752 | p_value => 'Y'); 753 | end; 754 | / 755 | ``` 756 | - to use it add request to the link APEX_CLONE_SESSION: 757 | - .../f?p=114:10:15609087012832:**APEX_CLONE_SESSION**::: 758 | 759 | ## Links 760 | 761 | - [Demo](http://localhost:8080/ords/f?p=114:14:0) 762 | 763 | --- 764 | 765 | # APEX URL 766 | 767 | - bad way - DB needs to hard parse query for each SQL statement 768 | 769 | ```sql 770 | select 'f?p=&APP_ID.:17:&APP_SESSION.:::P17_ITEM:1' as my_url 771 | , apex_util.prepare_url('f?p=&APP_ID.:17:&APP_SESSION.:::P17_ITEM:1') as my_url_with_cs 772 | from some_table; 773 | ``` 774 | 775 | - better - not so readable and developer can easily make errors 776 | ```sql 777 | select 'f?p=&APP_ID.:17:'||:APP_SESSION||':::P17_ITEM:1' as my_url 778 | , apex_util.prepare_url('f?p=&APP_ID.:17:'||:APP_SESSION||':::P17_ITEM:1') as my_url_with_cs 779 | from some_table; 780 | ``` 781 | 782 | - good way - readable, creates checksum if needed 783 | 784 | ```sql 785 | select apex_page.get_url(p_page => '17' 786 | , p_items => 'P17_ITEM' 787 | , p_values => '1') as my_url 788 | from some_table; 789 | ``` 790 | 791 | - other parameters 792 | 793 | ```sql 794 | -- PARAMETERS 795 | -- * p_application application id or alias. defaults to the current application. 796 | -- * p_page page id or alias. defaults to the current page. 797 | -- * p_session session id. defaults to the current session id. 798 | -- * p_request URL request parameter. 799 | -- * p_debug URL debug parameter. defaults to the current debug mode. 800 | -- * p_clear_cache URL clear cache parameter. 801 | -- * p_items comma delimited list of item names to set session state. 802 | -- * p_values comma separated list of item values to set session state. 803 | -- * p_printer_friendly URL printer friendly parameter. defaults tot he current request's printer friendly mode. 804 | -- * p_trace SQL trace parameter. 805 | ``` 806 | 807 | --- 808 | 809 | # Strings (APEX_STRING) 810 | 811 | - new in 5.1 812 | - utilities for varchar2, clob, apex_t_varchar2, and apex_t_number types 813 | 814 | ## JOIN and SPLIT 815 | - apex_util.string_to_table and apex_util.table_to_string are [DEPRECATED](https://docs.oracle.com/database/apex-18.2/AEAPI/STRING_TO_TABLE-Function.htm) 816 | - **SPLIT**: 817 | 818 | ```sql 819 | -- apex_util.string_to_table DEPRECATED 820 | declare 821 | v_arr apex_application_global.vc_arr2; 822 | begin 823 | v_arr := apex_util.string_to_table('One:Two:Three'); 824 | for i in 1..v_arr.count 825 | loop 826 | dbms_output.put_line(v_arr(i)); 827 | end loop; 828 | end; 829 | / 830 | ``` 831 | 832 | ```sql 833 | -- apex_string 834 | select * from apex_string.split('One:Two:Three', ':'); 835 | -- doesn't work: select * from APEX_UTIL.STRING_TO_TABLE('One:Two:Three'); 836 | ``` 837 | 838 | - **JOIN**: 839 | 840 | ```sql 841 | -- apex_util.table_to_string DEPRECATED 842 | declare 843 | v_arr apex_application_global.vc_arr2; 844 | begin 845 | select ename 846 | bulk collect into v_arr 847 | from emp; 848 | 849 | dbms_output.put_line(apex_util.table_to_string(v_arr)); 850 | end; 851 | / 852 | ``` 853 | 854 | ```sql 855 | declare 856 | v_arr apex_t_varchar2; 857 | begin 858 | select ename 859 | bulk collect into v_arr 860 | from emp; 861 | 862 | dbms_output.put_line(apex_string.join(v_arr, ':')); 863 | end; 864 | / 865 | ``` 866 | ## Key value tables - PUT/GET/DELETE 867 | 868 | ```sql 869 | declare 870 | v_table apex_t_varchar2; 871 | begin 872 | -- populate table 873 | for i in (select ename, sal from emp) 874 | loop 875 | -- put element into table 876 | apex_string.plist_put(v_table, i.ename, i.sal); 877 | end loop; 878 | 879 | 880 | -- get element from table 881 | dbms_output.put_line( 882 | apex_string.plist_get(v_table, 'JONES') 883 | ); 884 | end; 885 | / 886 | ``` 887 | 888 | ## FORMAT 889 | - returns a formatted string, with substitutions applied. 890 | 891 | ```sql 892 | select apex_string.format('Hi %s! Hope to see you at the party. It starts at %s.' 893 | , 'Marko' 894 | , '18:30') m 895 | from dual; 896 | ``` 897 | 898 | ```sql 899 | -- with %0 %1 - starts with zero 900 | select apex_string.format('Hi %1! Hope to see you at the party. It starts at %0.' 901 | , '18:30' 902 | , 'Marko' 903 | , p_max_length => 10) m 904 | from dual; 905 | ``` 906 | ## SHUFFLE 907 | - Returns the input table values, re-ordered.. 908 | 909 | ```sql 910 | select * 911 | from apex_string.shuffle(apex_t_varchar2('One','Two','Three')); 912 | ``` 913 | 914 | ## Parsing CSV data 915 | - output CSV from a table (in SQL Developer or SQLcl): 916 | 917 | ```sql 918 | select /*csv*/ * from emp; 919 | ``` 920 | - parse CSV: 921 | 922 | ```sql 923 | with 924 | function get_column (p_row varchar2 925 | , p_col_num number) 926 | return varchar2 927 | is 928 | v_row apex_t_varchar2; 929 | begin 930 | v_row := apex_string.split(p_row, ','); 931 | if v_row.exists(p_col_num) then 932 | return v_row(p_col_num); 933 | end if; 934 | return null; 935 | end; 936 | select get_column(column_value, 1) as col1 937 | , get_column(column_value, 2) as col2 938 | , get_column(column_value, 3) as col3 939 | , get_column(column_value, 4) as col4 940 | , get_column(column_value, 5) as col5 941 | , get_column(column_value, 6) as col6 942 | , get_column(column_value, 7) as col7 943 | , get_column(column_value, 8) as col8 944 | from apex_string.split(:CSVDATA, chr(10)); -- chr(10) or chr(10)||chr(13) 945 | ``` 946 | 947 | ## APEX_UTIL.GET_HASH 948 | - computes a hash value for all given values 949 | - can be used to implement lost update detection for data records 950 | - p_salted - if true (the default), salt hash with internal session info 951 | 952 | ```sql 953 | select apex_util.get_hash( 954 | p_values => apex_t_varchar2 (empno, sal, comm), 955 | p_salted => true 956 | ) x 957 | from emp; 958 | ``` 959 | 960 | ## Links 961 | 962 | - [Documentation](https://docs.oracle.com/database/apex-18.2/AEAPI/APEX_STRING.htm) 963 | 964 | 965 | --- 966 | 967 | # Other APIs 968 | - New in 18.1 969 | - **APEX_PKG_APP_INSTALL** - utilities you can use to manage Packaged Applications. 970 | - **APEX_JWT** - utilities for JSON Web Tokens (JWT) 971 | - **APEX_EXEC** - contains procedures and functions to execute queries or procedural calls on local and remote data sources as well as web source modules 972 | - **APEX_CREDENTIAL** (new in 18.2) - package to change stored credentials either persistently or for the current APEX session only 973 | 974 | - Useful from previous versions: 975 | - **APEX_ZIP** - compress and to uncompress files and store them in a ZIP file 976 | - **APEX_JSON** - utilities to parse and generate JSON 977 | - **APEX_WEB_SERVICE** - utilities to invoke WS 978 | 979 | - Non APEX APIs 980 | - https://github.com/mortenbra/alexandria-plsql-utils 981 | - OraOpenSource https://oos-utils.readthedocs.io/en/latest/README/ 982 | 983 | --- 984 | class: center, middle 985 | 986 | # Questions? 987 | 988 | --- 989 | class: center, middle 990 | 991 | # http://bit.do/hroug-apex-hidden-features 992 | .qrcode[![qrcode](./img/qrcode.png)] 993 | 994 | --- 995 | class: center, middle 996 | 997 | # Thank You! 998 | 999 | 1000 | 1001 | ??? --------------------------------------------------------------------------------