├── 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[]
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[]
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[]
993 |
994 | ---
995 | class: center, middle
996 |
997 | # Thank You!
998 |
999 |
1000 |
1001 | ???
--------------------------------------------------------------------------------